出處
作者:許式偉
寫于:2005年3月
背景:
WPS Office 2005 (開發(fā)代號: V6)
原文:
why-unit-test.pdf
(pdf格式)
目錄
- 自動化單元測試的重要特征
- 單元測試的項目意義
- 單元測試對設(shè)計的意義
- cppunit for v6
- 將測試案例寫在dll中
常規(guī)測試的缺陷
- 一般是基于手工的,不具備可回歸性。因此測試的效率不高。
- 由于缺乏效率,往往導(dǎo)致測試僅僅針對典型數(shù)據(jù),覆蓋面往往也很低。
自動化單元測試的重要特征
- 自動化、可回歸性
- Quiet
- 案例的執(zhí)行安全受控
自動化、可回歸性
-
測試的結(jié)果是程序直接檢測的,而不是
“通過人眼對屏幕上的輸出結(jié)果的觀測”
。
- 測試的輸入數(shù)據(jù)和預(yù)測結(jié)果直接在案例中, 除非結(jié)果非預(yù)期,否則不需要任何輸出 。
- 因此,并不推薦屏幕輸出,或者寫可視化的測試單元。
- 案例的執(zhí)行不需要人工干預(yù),可隨時回放。
- 因此,我們可以通過大量典型測試數(shù)據(jù)進行回歸,以確保系統(tǒng)的可靠性。
-
對比:常規(guī)測試典型過程
- 在屏幕上提示輸入數(shù)據(jù),然后打印結(jié)果,通過查看屏幕顯示的結(jié)果,確認我們的系統(tǒng)是否存在問題。
Quiet
- 絕對避免在案例執(zhí)行過程中彈出對話框或者進行其他UI交互。
- (調(diào)試模式下例外)
案例的執(zhí)行安全受控
- 某個測試案例執(zhí)行的失敗(甚至出現(xiàn)了異常),不會導(dǎo)致測試環(huán)境的崩潰,也不影響另一個案例的執(zhí)行結(jié)果。
常規(guī)測試樣例
void main ()
{
int n ;
for ( ;; )
{
std :: cout << " input n(0 to exit): " ;
std :: cin >> n ;
if ( n == 0 )
break ;
std :: cout << " n! = " << fact ( n ) << std :: endl ;
}
}
cppunit測試案例
class TestFact : public TestCase
{
public :
CPPUNIT_TEST_SUITE ( TestFact ) ;
CPPUNIT_TEST ( test ) ;
CPPUNIT_TEST_SUITE_END () ;
void test ()
{
CPPUNIT_ASSERT ( fact ( 3 ) == 6 ) ;
CPPUNIT_ASSERT ( fact ( 4 ) == 24 ) ;
CPPUNIT_ASSERT ( fact ( 5 ) == 120 ) ;
}
} ;
CPPUNIT_TEST_SUITE_REGISTRATION ( TestFact ) ;
單元測試的項目意義
- 模塊更加可控。
- 及早發(fā)現(xiàn)問題,提高模塊質(zhì)量,降低系統(tǒng)測試成本。
- 加速開發(fā)周期。
單元測試與項目控制
-
單元測試不應(yīng)該是程序員的個人行為,而與項目進度控制、質(zhì)量控制息息相關(guān)。
- 通過監(jiān)測單元測試的情況,來量化模塊開發(fā)的進度與質(zhì)量。
-
要改善項目的控制,必須“做好單元測試”。
- 不止是要讓單元測試成為每個程序員的例行公事,而且要讓它變得規(guī)范、變得受控。
單元測試的誤區(qū)
- 一個很常見誤解是:嗯,單元測試,好事啊,只是最近時間很緊,下回做吧。
-
實際上
單元測試大家都會去做
,我們提倡單元測試,更大程度上是要達到:
- 規(guī)范單元測試的編寫(手段);
- 最大程度保留下來我們的測試案例;
加速開發(fā)周期
-
一個系統(tǒng)自動化程度越高,則運營成本越低。
- 單元(模塊)是最容易,也是最應(yīng)該采用自動化測試的。而集成測試、系統(tǒng)測試雖然也有自動化的方法和支持工具,但需要更高額的代價。
-
單元測試
將問題的發(fā)現(xiàn)周期縮短,降低bug修復(fù)成本。
- 如果問題在集成測試、系統(tǒng)測試期被發(fā)現(xiàn),那么同樣一個問題需要花幾倍甚至幾十倍的時間進行定位、修復(fù)。
- 單元測試降低了集成測試、系統(tǒng)測試的壓力和投入成本。
單元測試的主要檢查點
- 案例的覆蓋度
- Bug量與Bug反復(fù)情況
- 案例文檔的規(guī)范
單元測試對設(shè)計的意義
- 設(shè)計應(yīng)該以可測試性為第一目標。
- 及時發(fā)現(xiàn)模塊構(gòu)架調(diào)整引發(fā)的潛在Bug。
模塊的可測試性
-
可測試性 = 低耦合
- 環(huán)境模擬(依賴的模塊、數(shù)據(jù)輸入)
- 模塊設(shè)計應(yīng)該首先保證可測試性。
- 堅持進行單元測試可提高設(shè)計能力。
- 一個模塊可以很方便地進行測試,那么就可以說它是一個設(shè)計優(yōu)良的模塊。
發(fā)現(xiàn)模塊構(gòu)架調(diào)整的潛在Bug
- 通常 模塊在架構(gòu)調(diào)整期(代碼重構(gòu))最容易引入Bug。
- 只有在模塊開發(fā)中就不斷積累經(jīng)典數(shù)據(jù)、以案例的形式固化已知Bug,才可能在架構(gòu)調(diào)整等最容易引發(fā)問題的情形下獲得最佳效果。
cppunit for v6
- 引入調(diào)試模式
- 通用的調(diào)試開關(guān)
- 有選擇的運行測試案例
- 獨特的dll測試模式
調(diào)試模式
-
同一套測試代碼,兩種工作模式。
- cppunit提供了安全可控的自動化測試平臺。
- 但是是代碼總會有bug。為了讓測試案例可調(diào)試,v6在開源的cppunit基礎(chǔ)上,結(jié)合kfc的調(diào)試策略,引入調(diào)試模式。
通用的調(diào)試開關(guān)
-
/ndebug
- 進入自動化測試模式。默認為調(diào)試模式。
-
/output:<xmlfile>
- 輸出結(jié)果到xml文件。注意:/output:后不能有空格。
- 默認輸出到控制臺。
-
/run:<testclass>[.<testmethod>]
- 執(zhí)行<testclass>類所有案例,或者執(zhí)行<testclass>的<testmethod>案例。
有選擇的運行測試案例
- 你可以只執(zhí)行某個TestCase類,或者只是執(zhí)行某個TestCase中的某個method。
- 演示rununit程序的參數(shù)含義:
<testclass> <testmethod>
- 演示通用開關(guān):
/run:<testclass>[.<testmethod>]
將測試案例寫在dll中
- 測試案例同步更新
- 測試dll內(nèi)部組件
- 關(guān)于rununit工具
基于dll的單元測試
-
對比
- 為dll寫測試程序(exe方式)
-
優(yōu)點
-
方便測試案例的同步更新
- 并且強迫你同步更新測試案例
- 可測試dll的內(nèi)部組件
- 去除了建立新工程的過程(有點麻煩)。
-
方便測試案例的同步更新
關(guān)于rununit工具
-
用rununit調(diào)試你的dll
- rununit程序是一個通用的testcaseRunner,可用于執(zhí)行(或調(diào)試)一個dll中的部分或全部案例。
- 命令行
rununit testcase[.dll] [testclass] [testmethod] [/ndebug] [/pause] [/output:<xmlfile>]
Visual Studio中調(diào)試dll
今天,你“單元測試”了嗎?
- 如果你沒有,那么我告訴你,你已經(jīng)落伍啦!
附錄
- rununit.exe: 參考ksdn中關(guān)于該程序的詳細說明。
- CreateCppUnitTestCase宏: 參考KSRule.dsm(macros for Visual Studio)。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
