CI作到90%的行覆蓋率,真能發現BUG嗎?

阿里妹導讀:這麼多的CASE,花了大量時間和資源去運行,真能發現BUG嗎?CI作到90%的行覆蓋率,能發現問題嗎?測試用例愈來愈多,刪一些,會不會就發現不了問題了?今天,咱們談談如何評估測試用例的有效性?

咱們的測試用例有兩個比較關鍵的部分:git

1)調用被測代碼:例以下面的RuleService.getLastRuleByClientId(ClientId)。
2)進行結果Check:例以下面的AssertEqual(OrderId,"ABCD1234")。算法

TestCaseA
...
  RuleService.createRuleByClientId(ClientId,RuleDO);
  StringOrderId=RuleService.getLastRuleByClientId(ClientId);
...

TestCaseB
...
  RuleService.createRuleByClientId(ClientId,RuleDO);
  StringOrderId=OrderService.getLastOrderByClientId(ClientId);
  AssertEqual(OrderId,"ABCD1234");
...

咱們但願一組測試用例不只可以「觸發被測代碼的各類分支」,還可以作好結果校驗。單元測試

  • 當業務代碼出現問題的時候,測試用例能夠發現這個問題,咱們就認爲這一組測試用例是有效的。
  • 當業務代碼出現問題的時候,測試用例沒能發現這個問題,咱們就認爲這一組測試用例是無效的。

咱們對測試用例有效性的理論建模是:學習

測試有效性 = 被發現的問題數 / 出現問題的總數

爲何要評估測試用例的有效性?

測試用例有效性評估的方法?

基於故障覆盤的模式成本過高,咱們但願可以主動創造問題來評估測試用例的有效性。測試

咱們找到了一種衡量「測試有效性」的方法,變異測試(mutation testing):spa

變異測試的例子3d

咱們用了一組測試用例(3個),去測試一個判斷分支。
而爲了證實這一組測試用例的有效性,咱們向業務代碼中注入變異。咱們把b<100的條件改爲了b<=100。日誌

咱們認爲:code

  • 一組Success的測試用例,在其被測對象發生變化後(注入變異後),應該至少有一個失敗。
  • 若是這組測試用例仍然所有Success,則這組測試用例的有效性不足。

經過變異測試的方式:讓注入變異後的業務代碼做爲「測試用例」,來測試「測試代碼」。對象

咱們實現了多種規則,能夠主動的注入下面這些變異:

如何優雅的評估測試有效性?

爲了全自動的進行測試有效性評估,咱們作了一個變異機器人,其主要運做是:

  1. 往被測代碼中寫入一個BUG(即:變異);
  2. 執行測試;
  3. 把測試結果和無變異時的測試結果作比對,判斷是否有新的用例失敗;
  4. 重複1-3若干次,每次注入一個不一樣的Bug;
  5. 統計該系統的「測試有效性」 。

變異機器人的優勢:

  1. 防錯上線:變異是單獨拉代碼分支,且該代碼分支永遠不會上線,不影響生產。
  2. 全自動:只須要給出系統代碼的git地址,便可進行評估,獲得改進報告。
  3. 高效:數小時便可完成一個系統的測試有效性評估。
  4. 擴展性:該模式能夠支持JAVA以及JAVA之外的多種語系。
  5. 適用性:該方法不只適用於單元測試,還適用於其餘自動化測試,例如接口測試、功能測試、集成測試。

變異機器人的使用門檻:

  1. 測試成功率:只會選擇經過率100%的測試用例,所對應的業務代碼作變異注入。
  2. 測試覆蓋率:只會注入被測試代碼覆蓋的業務代碼,測試覆蓋率越高,評估越準確。

高配版變異機器人

咱們正在打造的高配版變異機器人擁有三大核心競爭力:

分鐘級的系統評估效率

爲了保證評估的準確性,100個變異將會執行全量用例100遍,每次執行時間長是一大痛點。

高配版變異機器人給出的解法:

  1. 並行注入:基於代碼覆蓋率,識別UT之間的代碼覆蓋依賴關係,將獨立的變異合併到一次自動化測試中。
  2. 熱部署:基於字節碼作更新,減小變異和部署的過程。
  3. 精準測試:基於UT代碼覆蓋信息,只運行和本次變異相關的UT(該方法不只適用於UT,還適用於其餘自動化測試,例如接口測試、功能測試、集成測試)。

學習型注入經驗庫

爲了不「殺蟲劑」效應,注入規則須要不斷的完善。

高配版變異機器人給出的解法:故障學習,基於故障學習算法,不斷學習歷史的代碼BUG,並轉化爲注入經驗。可學習型經驗庫目前覆蓋螞蟻金服的代碼庫,明年會覆蓋開源社區。

兼容不穩定環境

集成測試環境會存在必定的不穩定,難以判斷用例失敗是由於「發現了變異」仍是「環境出了問題」,致使測試有效性評估存在偏差。

高配版變異機器人給出的解法:

  1. 高頻跑:一樣的變異跑10次,對屢次結果進行統計分析,減小環境問題引發的偶發性問題。
  2. 環境問題自動定位:接入附屬的日誌服務,它會基於用例日誌/系統錯誤日誌構建的異常場景,自動學習「因環境問題致使的用例失敗」,準確區分出用例是否發現變異。

落地效果如何?

咱們在螞蟻金服的一個部門進行了實驗,得出了這樣的數據:

換言之,幾個系統的測試有效性爲:系統A 72%,系統B 56%,系統C 70%。

測試有效性(%) = 1 - 未發現注入數 / 注入數

更多的測試有效性度量手段

基於代碼注入的測試有效性度量,只是其中的一種方法,咱們平常會用到的方法有這麼幾種:

  • 代碼注入:向代碼注入變異,看測試用例是否能發現該問題
  • 內存注入:修改API接口的返回內容,看測試用例是否能發現該問題
  • 靜態掃描:掃描測試代碼裏是否作了Assert等判斷,看Assert場景與被測代碼分支的關係
  • ... 還有更多其餘的度量手段

Meet the testcase again

測試有效性能夠做爲基石,驅動不少事情向好發展:

  • 讓測試用例變得更能發現問題。
  • 讓無效用例可被識別、清理。
  • 創造一個讓技術人員真正思考如何寫好TestCase的質量文化。
  • 測試左移與敏捷的前置條件。
  • ......

寫到最後,想起了同事給我講的一個有趣的人生經歷:

「大二期間在一家出版社編輯部實習,工做內容就是校對文稿中的各類類型的錯誤。編輯部考覈校對質量的辦法是,人爲的事先在文稿中加入各類類型的錯誤,而後根據你的錯誤發現率來衡量,並計算實習工資。」

「你幹得咋樣?」

「我學習了他們的規則,寫了個程序來查錯,拿到了第一個滿分」

「厲害了...」

「第二個月就不行了,他們不搞錯別字了,搞了一堆語法、語義、中心思想的錯誤... 我就專心幹活兒了」

「...」

異曲同工,其致一也。



本文做者:義理

閱讀原文

本文來自雲棲社區合做夥伴「阿里技術」,如需轉載請聯繫原做者。

相關文章
相關標籤/搜索