1、單元測試 XXXX作為一個新項目,和其他所有項目一樣,在開發工作進行之初就在考慮如何保證代碼開發的質量。答案很容易找到:充分的單元測試。但是以前真正做得好得項目卻不多。
經過分析,總結了一下做好單元測試工作的四個要素:
――思想上的重視
――計劃上保證
――測試手段保證
――測試效果的可驗證
1.1 思想上重視
從以往的開發過程總結了一些教訓:
――開發人員模塊在交付聯調前,測試不充分,導致聯調周期較長
――代碼進入維護期后,修改代碼往往引起不可預期的錯誤。導致開發人員比較害怕在相對穩定的代碼上進行修改。
由于有這些教訓,所以在編碼之前,項目從領導到員工都很重視單元測試工作。
1.2 計劃上保證
計劃制定經過了XXXX的分解流程,XXXX分解小組成員討論時充分意識到了單元測試工作的必要性,也意識到了為之要付出的代價。最終確定了單元測試和代碼開發的比重為2:1左右。以操作維護的配置模塊為例,最終制定的計劃如下:

從計劃中可以看出,花在單元測試上的時間和代碼開發的時間的比重甚至超過了2:1。
附:表方法測試代碼和被測代碼的行數統計數據(該部分測試覆蓋率已達95%以上)
從數據看來,我們當初的估計是對的。測試代碼行數和被測代碼行數的比值大致是2:1
1.3 測試手段保證
1.3.1 測試框架
對于一個系統工程來說,一個好的框架是至關重要的。一個好的框架應該有如下一些特點:
――結構清晰。不同的粒度層次在框架中一目了然
――可擴展性良好。
我們選擇單元測試工具就是為了滿足能基于該工具搭建一個好的單元測試框架,另外還有以下幾個方面的考慮:
――整個開發組負責三個模塊:數據庫,操作維護,傳輸。每個模塊由不同的開發人員負責。從測試代碼的可維護性考慮,需要統一各人編寫測試代碼的框架以及風格
――前臺代碼是由C語言編寫的
――單元測試應該是可回歸的,自動化的
最終我們選擇了Cunit,因為Cunit完全符合我們的要求。
Cunit是一種針對于C語言代碼的單元測試框架,具有以下優點:
–提供很多實用的接口函數(比如:各種斷言、信息匯總、打印等)
–簡單、安全、方便
–可添加任意多個測試單元
–逐步添加,匯總成套,全面回歸測試
–完全免費
測試框架選定以后,在組內進行了相應的培訓,使得每個人的認識達到相同的水平,盡可能保證以后測試風格的一致。
1.3.2 測試方案和測試規程
單元測試是一個系統的工作,在進行之前需要一個總體的規劃。這個工作在單元測試方案中得到體現;測試規程是對測試方案的細化,是單元測試的指導。測試規程可以在notes的測試管理平臺中錄入。
1.3.3 自動化測試的考慮
一個單元測試是由許多測試用例構成的,要實現可回歸,自動化的測試,每個測試用例都應該可以按照一定的順序連續的執行。要達到這個目標,就要求對整個單元測試做一個很好的規劃。以數據庫模塊為例,我們做了如下的規劃:
● 數據環境的建立
數據庫的測試依賴于一套數據表。單元測試一開始就需要在表中插入數據,以建立后續測試用例依賴的數據環境
● 測試粒度合理的劃分
我們把被測對象分為表方法、查詢接口和修改接口。

注:測試用例套(TestSuite)是Cunit的一個概念,用于封裝測試用例套或者測試用例(TestCase)
● 在某種粒度上面保證數據環境的松耦合
所有的測試用例基于數據環境編寫,數據環境對于數據庫的單元測試是及其重要的。每個測試用例從前一個用例繼承數據環 境,又將本測試用例修改后的數據環境移交給下一個測試用例。從這個過程可以看出,數據環境在測試用例間是緊耦合的。如果測試用例一多,數據環境就會變得難 以控制,用例的編寫將變得非常麻煩。尤其是多人分工合作的情況下,簡直變成了不可能的任務。
幸好我們有測試套!
以表方法的測試套為例,在第二級粒度上,一個套就是一張表所有表方法測試用例的集合。這個套包含的測試用例大致在 4、5個左右。我們的策略是:二級粒度測試套內部的測試用例緊耦合數據環境,而二級粒度套之間的數據環境為松耦合。這通過在每個二級粒度套內加入一個數據 環境恢復用例來實現。
這樣一來,我們可以按照二級粒度的測試套來分工編寫測試代碼。
● 樁函數的考慮
單元測試是不依賴其他模塊的測試。但是實際代碼中存在對其他模塊函數的調用。為了消除這種依賴關系,就需要編寫樁函數來替代對外部模塊函數的調用。
為了清晰起見,我們的樁函數集中在一個文件中。
樁函數只是一個實現,至于原形定義,還是要引用其他模塊的頭文件,這樣可以跟蹤其他模塊函數接口最新的改動。
● 單元測試工程的規劃
一個清晰合理的單元測試工程規劃是必要的,這樣有利于對象的查找和維護。
以DBS模塊的單元測試為例,我們的工程結構如下圖所示。
1.3.4 測試效果的可驗證
如何來量化單元測試的效果?
覆蓋率是一個最直觀的指標。我們采用了Rational公司的Pure Coverage工具來獲取覆蓋率。這也是公司推薦的一個簡單易上手的工具。我們要求測試覆蓋率達到90%以上。
2、自動測試
2.1 每日構造
每日構造是公司推行的一個最佳實踐。它有一下一些功能:
● 開發人員及時把最新代碼放入代碼庫,及時check out和check in,避免積累大量代碼
● 及時進行模塊間的整合,及時發現問題
● 對部分功能進行測試,無需等待
● 使用測試用例工具,對功能進行完整和重復的檢驗
● 記錄所有程序問題
● 實現解決Bug的自動流程
● 提高正式版本提交的質量和速度
● XXXX在軟件上開始推行每日構造。
2.2 冒煙測試
如果在每日構造的同時進行“冒煙測試”,能最早發現版本的問題。“冒煙測試”是微軟提出的名詞。其
對象是每一個新編譯的需要正式測試的軟件版本,目的是確認軟件基本功能正常,可以進行后續的正式測試工作。“冒煙測試“的執行者是版本編譯人員。
ZXWR-RNS網管項目已有用Robot在網管產品進行冒煙測試的實踐。但是對于前臺軟件,公司內部尚未有這方面的嘗試。
2.3 自動測試
基于前期模塊的單元測試工作,一個自然的想法就是在每日構造的框架上運行模塊的單元測試代碼,實現前臺軟件的每日自動化測試。這是比“冒煙測試”更全面,更徹底的一個測試。
2.3.1 單板軟件
模塊1
模塊2
模塊n
模擬測試工具
XXXX軟件的架構
2.3.2 自動測試的規劃
2.3.2.1 自動測試的級別
從軟件的構成來考慮,分三級構造測試工程:
● 模塊單元級:基本的軟件單元
● 板級:由多模塊組成的單板軟件
● 系統集成級:由模擬測試軟件和單板軟件組成
這三個級別的測試是互相補充的關系。每日構造進行三個級別的測試,這樣就比較完整了。
2.3.2.2 測試代碼的管理
要實現每日構造并進行自動測試,必須將測試代碼也提升到被測代碼同等的地位,納入CC的管理。在CC上的目錄結構如下所示:
BoardSWS
-BoardTest \\板級測試工程目錄,包含測試用例代碼以及板級測試工程
-SystemTest \\系統集成級工程目錄,不含測試用例,僅含工程
-SCMM
-UnitTest \\模塊單元級測試目錄,包含該級測試用例以及測試工程
-SCMM源碼
-Cunit \\模塊單元級測試用Cunit文件
-其他模塊
-Cunit \\板級測試用Cunit文件
SimuRNC
-SystemTest \\系統集成級測試工程目錄,包含測試工程和測試用例
-SimuRNC源碼
-Cunit
基于這樣的目錄結構,發布代碼和測試代碼在CC中納入同一個VOB管理比較方便。這樣一來,測試代碼和發布代碼執行相同的CC-CQ關聯策略。也就是說,修改測試代碼也需要和CQ關聯。
2.3.3 自動測試的執行
自動測試由版本室完成。自動測試執行分為四個步驟:
● 同步CC的文件到本地
● 編譯各測試工程(VC環境),輸出編譯結果文件
● 執行編譯結果,輸出測試執行結果文件
● 將編譯結果導入
notes
上述步驟都是通過編寫一個BAT文件掛在WINDOWS的“任務計劃”中每日自動完成。
附:
BAT文件(DBS模塊)
編譯結果 (DBS模塊)
測試執行結果(DBS模塊)
2.3.4 自動測試的目標
依附于每日構造機制,自動依序運行三個級別的自動測試,測試產生的結果輸出到文本文件。然后通過自動分析腳本提取該文件中沒有通過的用例信息,發送郵件通知相關責任人進行分析處理。如此做到“日事日畢”,將故障扼殺在萌芽狀態,保證代碼質量的穩定。