我們會發現,每個測試類的名稱就是對應的目標類的名稱+"test",里面的方法也是如此,如果是構造函數,則是諸如
ConstructorTest或ConstructorTestN這樣的形式,N為重載次數.每個方法里面的代碼看上去也不奇怪,只是構造參數來調用而已,最后通過斷言來判斷(用過NUnit的朋友不會陌生吧?).我們試著直接把一個方法里的斷言去掉看看,編譯,TestManager,run,嘿,果然,去掉斷言的方法就pass了!看來蒙老大不難呢,只要把所有的方法的斷言都給去掉,然后給老大看測試后的結果,呵呵…
Step4.深入的了解一下方法上帶有的屬性的含義.
每個方法上幾乎都帶有TestMethod這個屬性,我們直覺告訴我們,這肯定是表示被測試函數的意思.事實也正是如此,在Unit Test里,有許多測試屬性,常用的如下:
屬性 | 描述 |
TestClass() |
該屬性表示一個測試裝置。 |
TestMethod() |
該屬性表示一個測試用例。 |
AssemblyInitialize() |
在執行為執行選擇的第一個 TestClass() 中的第一個 TestMethod() 之前,執行帶有該屬性的方法。 |
ClassInitialize() |
帶有該屬性的方法在執行第一個測試之前調用。 |
TestInitialize() |
帶有該屬性的方法在執行每個 TestMethod() 之前調用。 |
TestCleanup() |
帶有該屬性的方法在執行每個 TestMethod() 之后調用。 |
ClassCleanup() |
帶有該屬性的方法在執行 ALL 測試之后調用。 |
AssemblyCleanup() |
在執行為執行選擇的第一個 TestClass() 中的第一個 TestMethod() 之后,執行帶有該屬性的方法。 |
Description() |
提供關于給定 TestMethod() 的描述。 |
Ignore() |
由于某種原因忽略 TestMethod() 或 TestClass()。 |
ExpectedException() |
當測試特定異常時,如果使用該屬性指定的異常不是從實現代碼引發,則測試不會失敗。 |
需要注意的是,上面的屬性不是可以適用于所有方法的,比如AssemblyInitialize()和ClassInitialize()是必須是靜態方法的屬性.
我們可以把初始化的操作放在他們里進行.
Step5.修改測試方法及其斷言.
到現在,我們的思路開始清晰起來了,我們要開始做真正的測試了,不是僅僅去掉斷言就pass那么簡單了:)
我們的測試思路應該是這樣:我們調用該方法,需要傳入什么值,會影響什么值,當它執行之后,會產生怎樣的期待值?我們把期待值與實際的值想比較,同時寫下斷言失敗的message.
還是以我們的MyCahce為例,假如我們有個ListCache類,里面有個AddItemToTop(item)方法,表示把一個item插入到當前鏈表的頭部.我們實際的測試函數該這么寫
Guid id = System.Guid.NewGuid();
Item item = new Item(id);
list.AddItemToTop(item);
Assert.AreEqual(id, roomList.FirstLinkedItem.Key, "插入后查詢獲得的key值與插入的對象的key值不相等!");
通過比對插入后的鏈表的頭部的key與之前保存的key值來判斷,這是不是一次成功的插入.
這只是個很簡單的例子,我們當然應該根據具體的方法需要實現的功能來定義測試代碼.
Step6.OVER
完成了上面5部,相信你已經對VSTS的Unit Test非常的熟悉了,接下來需要做的就是把你需要的測試的method都提供正確的測試代碼,注意,這里我們甚至不要考慮我們本身的項目究竟有沒有實現該功能,但我們應該該知道,我們需要什么功能.我們只針對應該產生的結果寫測試代碼.當測試不通過時,我們只需要修改我們的目標項目,而不再需要修改我們的測試項目.這其實正是TDD(測試驅動開發)的思想,我們如果要驗證我們的方法有沒有錯,只需要run一下test即可,真正實現了全自動化單元測試, 這里邊的實際開發效率的提高,只有你在真正體會過后才能明白:)
文章來源于領測軟件測試網 http://www.kjueaiud.com/