<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    編寫優(yōu)美的GTest測試案例

     使用gtest也有很長一段時間了,這期間也積累了一些經驗,所以分享一下。GTest為我們提供了便捷的測試框架,讓我們只需要關注案例本身。如何在GTest框架下寫出優(yōu)美的測試案例,我覺得必須要做到:
      案例的層次結構一定要清晰
      案例的檢查點一定要明確
      案例失敗時一定要能精確的定位問題
      案例執(zhí)行結果一定要穩(wěn)定
      案例執(zhí)行的時間一定不能太長
      案例一定不能對測試環(huán)境造成破壞
      案例一定獨立,不能與其他案例有先后關系的依賴
      案例的命名一定清晰,容易理解
      案例的可維護性也是非常重要,如果做到上面的8點,自然也就做到了可維護性。下面來分享一下我對于上面8點的經驗:
      1. 案例的層次結構一定要清晰
      所謂層次結構,至少要讓人一眼就能分辨出被測代碼和測試代碼。簡單的說,就是知道你在測什么。由于是進行接口測試,我已經習慣了如下的案例層次:
      DataDefine
      我會將測試案例所需要的數據,以及數據之間的聯系全部在預先定義好。測試數據與案例邏輯的分離,有利于維護和擴展測試案例。同時,GTest先天就支持測試數據參數化,為測試數據的分離提供了進一步的便捷。什么是測試數據參數化?就是你可以預先定義好一批各種各樣的數據,而你只需要編寫一個測試案例的邏輯代碼,gtest會將定義好的數據逐個套入測試案例中進行執(zhí)行。具體的做法請見:玩轉Google開源C++單元測試框架Google Test系列(gtest)之四 - 參數化
      SUT
      SUT,即system under test,表明你的測試對象是什么,它可以是一個類(CUT),對象(OUT),函數(MUT),甚至可以是整個應用程序(AUT)。我單獨將這個層次劃分出來,主要有兩個目的:
      (1)明確的表示出你的測試對象是什么
      (2)為復雜調用對象包裝簡單調用接口
      明確表示測試對象是什么,便于之后對測試案例的維護和對測試案例的理解。同時,對于一些被測對象,你想要調用它需要經過一系列煩瑣的過程,這時,就需要將這一煩瑣的調用過程隱藏起來,而只關注被測對象的輸入和輸出。
      TestCase
      測試工程中,必須非常明確的表示出哪些是測試案例,哪些是其他的輔助文件。通常,我們會在測試案例的文件名加上Test前綴(或者后綴)。我建議,將所有的測試案例文件或代碼放在最顯眼的地方,讓所有看到你的測試工程的人,第一眼看到的就是測試案例,這很重要。

      Checker
      對于一個復雜系統(tǒng)的接口測試,僅僅堅持輸入和輸出是遠遠不夠的。比如測試一個寫數據庫的函數,函數的返回值告訴你數據已經成功寫入是遠遠不夠的,你必須親身去數據庫中查個究竟才行。因此,對于某一類的測試案例,我們可以抽象出一些通用的檢查點代碼。
      如果做到上面的分層,那么一個測試案例寫出來的結構應該會是這個樣子:
    TEST(TestFoo, JustDemo)
    {
    GetTestData(); // 獲取測試數據
    CallSUT(); // 調用被測方法
    CheckSomething(); // 檢查點驗證
    }
      這樣的測試案例,一目了然。
      2. 案例的檢查點一定要明確
      一定要明確案例的檢查點是什么,并且讓檢查點盡量集中。有一個不好的習慣就是核心的檢查點在分布在多個函數中,需要不斷的跳轉才能了解到這個案例檢查了些什么。好的做法應該是盡量讓檢查點集中,能夠非常清晰的分辨出案例對被測代碼做了哪些檢查。所以,盡量讓Gtest的ASSERT_和EXPECT_系列的宏放在明顯和正確的地方。
      3. 案例失敗時一定要能精確的定位問題
      測試案例失敗時,我們通常手忙腳亂。如果一個測試案例Failed,卻不能立即推斷是被測代碼的Bug的話,這個測試案例也有待改進。我們可以在一些復雜的檢查點斷言中加入一些輔助信息,方便我們定位問題。比如下面這個測試案例:
    int n = -1;
    bool actualResult = Foo::Dosometing(n);
    ASSERT_TRUE(actualResult)
      如果測試案例失敗了,會得到下面的信息:
    Value of: actualResult
    Actual: false
    Expected:true
      這樣的結果對于我們來說,幾乎沒有什么用。因為我們根本不知道actualResult是什么,以及在什么情況下才會出現非預期值。因此,在斷言處多加入一些信息,將有助于定位問題:
    int n = -1;
    bool actualResult = Foo::Dosometing(n);
    ASSERT_TRUE(actualResult) << L"Call Foo::Dosometing(n) when n = " << n;
      4. 案例執(zhí)行結果一定要穩(wěn)定
      要保證測試案例在什么時候、什么情況下執(zhí)行的結果都是一樣的。一個一會成功一會失敗的案例是沒有意義的。要保證案例穩(wěn)定性的方法有很多,比如杜絕案例之間的影響,有時候,由于前一個案例執(zhí)行完后,將一些系統(tǒng)的環(huán)境破壞了,導致后面的案例執(zhí)行失敗。在測試某些本身就存在一定幾率或延時的系統(tǒng)時,使用超時機制是比較簡單的辦法。比如,你需要測試一個啟動Windows服務的方法,如果我們在調用了該方法后立即進行檢查,很可能檢查點會失敗,有時候也許又是通過的。這是因為Windows服務由Stop狀態(tài)到Running狀態(tài),中間還要經過一個Padding狀態(tài)。所以,簡單的做法是使用超時機制,隔斷時間檢查一次,直到超過某個最大忍受時間。
    ASSERT_TRUE(StartService('xxx'));
    int tryTimes = 0;
    int status = GetServiceStatus('xxx');
    while (status != Running)
    {
    if (tryTimes >= 10)
    break;
    ::Sleep(200);
    tryTimes++;
    status = GetServiceStatus('xxx');
    }
    ASSERT_EQ(Running, status) << "Check the status after StartService('xxx')";
      5. 案例執(zhí)行的時間一定不能太長
      我們應該盡量讓案例能夠快速的執(zhí)行,一方面,我們可以通過優(yōu)化我們的代碼來減少運行時間,比如,減少對重復內容的讀取。一方面,對于一些比較耗時的操作,比如文件系統(tǒng),網絡操作,我們可以使用Mock對象來替代真實的對象。使用GMock是一個不錯的選擇。
      6. 案例一定不能對測試環(huán)境造成破壞
      有的案例需要在特定的環(huán)境下來能執(zhí)行,因此會在案例的初始化時對環(huán)境進行一些修改。注意,不管對什么東西進行了修改,一定要保證在案例執(zhí)行完成的TearDown中將這些環(huán)境都還原回來。否則有可能對后面的案例造成影響,或者出現一些莫名其妙的錯誤。
      7. 案例一定獨立,不能與其他案例有先后關系的依賴
      任何一個案例都不依賴于其他測試案例,任何一個案例的執(zhí)行結果都不應該影響到別的案例。任何一個案例都可以單獨拿出去正確的執(zhí)行。所以,不能寄希望于前一個案例所做的環(huán)境準備,因為這是不對的。
      8. 案例的命名一定清晰,容易理解
      案例的名字要規(guī)范,長不要緊,一定要清晰的表達測試案例的用途。比如,下面的測試案例名稱都是不好的:
    TEST(TestFoo, Test)
    TEST(TestFoo, Normal)
    TEST(TestFoo, Alright)
      比如像下面的案例名稱就會好一點:
    TEST(TestFoo, Return_True_When_ParameterN_Larger_Then_Zero)
    TEST(TestFoo, Return_False_When_ParameterN_Is_Zero)

    posted on 2013-11-08 14:17 順其自然EVO 閱讀(444) 評論(0)  編輯  收藏 所屬分類: selenium and watir webdrivers 自動化測試學習

    <2013年11月>
    272829303112
    3456789
    10111213141516
    17181920212223
    24252627282930
    1234567

    導航

    統(tǒng)計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 拍拍拍无挡免费视频网站| 特级毛片A级毛片免费播放| 日韩视频免费在线观看| 在线观看亚洲av每日更新| 四虎永久在线精品免费一区二区| 成在线人永久免费视频播放| 亚洲av无码专区在线电影天堂| 四虎影视免费在线| 免费国产污网站在线观看不要卡| 四虎永久精品免费观看| 三年片在线观看免费观看大全中国| 亚洲国产精品视频| 中国一级毛片免费看视频| 亚洲AV成人片色在线观看| 4虎1515hh永久免费| 亚洲一区二区三区国产精品无码| 好吊妞998视频免费观看在线| 亚洲sm另类一区二区三区| 亚洲黄黄黄网站在线观看| 日韩精品无码免费专区午夜不卡| 亚洲综合久久综合激情久久| 波多野结衣在线免费观看| 亚洲精品无码永久在线观看男男| 免费va在线观看| 国产在线一区二区综合免费视频| 亚洲黄色三级网站| 日本免费人成黄页网观看视频| 丰满少妇作爱视频免费观看| 久久久亚洲精品国产| 成人免费视频观看无遮挡| 国产三级在线免费观看| 久久久久亚洲AV无码专区首JN | 亚洲无圣光一区二区| 德国女人一级毛片免费| 美女无遮挡拍拍拍免费视频| 亚洲视频在线观看网址| 免费看男女下面日出水视频| 久久精品视频免费播放| 亚洲国产精品美女久久久久| 国产av无码专区亚洲av果冻传媒| 国产情侣激情在线视频免费看|