100%的單元測試覆蓋率是不夠的

目錄

摘要

譯文內容

缺少測試用例

缺少功能

測試錯誤或不正確

異常處理

後續測試步驟


摘要

許多人將100%的單元測試覆蓋率等同於高代碼質量,但這還不夠。 代碼覆蓋率工具僅衡量測試是否執行代碼; 他們對測試的有效性沒有判斷力。 測試人員應審查單元測試,即使它們具有較高的覆蓋率,也可以幫助改進測試或在必要時補充額外的測試。

譯文內容

當開發人員進行的單元測試中100%覆蓋我們的代碼時,爲什麼需要測試人員?在創建測試時,測試人員爲什麼應審查單元測試?因爲100%的單元測試代碼覆蓋率還不夠。

代碼覆蓋率工具跟蹤代碼的執行情況,並提供有關該執行情況的指標。最常見的措施之一是聲明覆蓋率。語句覆蓋率給出了已執行語句佔程序中語句總數的百分比。許多組織設定了單元測試覆蓋率的目標,共同的目標是80%的語句覆蓋率。

開發人員爲獲得100%的單元測試覆蓋率而感到自豪,項目團隊的成員將其與擁有高質量的代碼聯繫在一起。但是,即使測試執行了每一行代碼,然後我們將代碼稱爲“完全測試”,這也會產生誤導。

100%的單元測試覆蓋率並不意味着我們已經進行了良好的測試,甚至並不意味着測試已經完成。測試可能會丟失重要數據,而只能使用成功的數據進行測試,而無法測試導致失敗的數據。 100%的單元測試覆蓋率沒有說明缺少代碼,缺少錯誤處理或缺少要求。

測試也可能實際上沒有檢查代碼的功能。僅執行代碼而不檢查其功能仍然在覆蓋率指標中。

以下示例說明了僅依靠單元測試覆蓋範圍會導致什麼問題。代碼是Python,測試是使用unittest模塊編寫的。希望這些示例能激發測試人員檢查單元測試,改進這些測試或通過功能測試來補充它們,以填補空白—即使測試覆蓋率爲100%。

缺少測試用例

考慮下面的函數(only_correct_data),該函數具有多個參數,執行一些數學運算並返回結果。只需一次單元測試即可實現100%的代碼覆蓋率,因爲此函數只有一行代碼:

def only_correct_data(a,b,c):

    返回(a /(b-c))

def test_only_correct_data(self):
   #僅測試可得出正確結果的數據

    self.assertEqual(only_correct_data(1,2,3),-1)
    self.assertEqual(only_correct_data(2,3,1),1)
    self.assertEqual(only_correct_data(0,2,3),0)

測試覆蓋率爲100%,其中三個測試用例分別覆蓋負面結果,正面結果和零結果。缺少的是會導致被零除錯誤的測試用例。使用調用only_correct_data(2,2,2)將導致被零除的異常。爲開發人員找到丟失的測試案例是改善單元測試的好方法。

複查這些單元測試並確保它們徹底的另一個好處是,測試人員可以專注於整體系統質量,用戶體驗和對客戶的接受度。知道數學是正確的並且可以通過單元測試驗證的,可以使測試人員專注於與質量相關的其他因素

缺少功能

單元測試通常會驗證開發人員的意圖是否正確實現,但是即使100%的代碼覆蓋率也並不意味着完全滿足要求。

在此示例中,有一個稱爲“狗”的類,該類根據狗的大小返回“吠”。

狗類(對象):

    def __init __(自身,大小):
       如果size ==“ Large”:
           self.bark =“糟糕!”
       如果size ==“ Small”:
           self.bark =“弓哇”

def test_missing():
   #缺少對中型犬的測試

    l =狗(“大”)
    self.assertEqual(l.bark,“糟糕!”)
    s =狗(“小”)
   self.assertEqual(s.bark,“ Bow Wow”)

狗類中缺少吠叫“ Ruff”的中型狗。該代碼缺少要求,並且由於在此階段進行了額外的測試,該錯誤早在驗收測試之前就已被發現,因此無需花費太多精力進行修復。

此示例說明了100%的代碼覆蓋率並不能告訴您有關丟失的代碼的任何信息。單元測試將檢查代碼是否在工作,因爲開發人員打算使代碼工作,但不一定是代碼滿足客戶要求。

測試錯誤或不正確

在測試過程中100%執行代碼並不意味着測試實際上是好的測試,甚至根本測試不到任何東西。

def rev_string(in_string):
   返回in_string

def test_bad_test():
   #實際上不檢查代碼是否正確

    self.assertIsNotNone(rev_string(“ Test String”))

在此示例中,該函數應反轉字符串,但不是。即使單元測試具有100%的覆蓋率,它也不會實際檢查字符串是否反向。僅檢查返回值是否不是“ None”。測試用例可以執行代碼,而無需實際測試任何內容,仍然可以實現100%的代碼覆蓋率。測試人員應仔細檢查這些測試的質量或創建實際驗證功能的測試。

    do_nothing = rev_string(“測試字符串”)

該行將執行rev_string,但不會實際對其進行測試,仍然達到100%的覆蓋率。在這些情況下,測試人員可以幫助開發人員考慮適當的方法來測試功能,以填補測試空白。

異常處理

此示例顯示了一種非常常見的情況,其中代碼進行了一些錯誤檢查,但尚未經過全面測試。 本文創建的所有代碼的代碼覆蓋率是98%,但是這裏缺少的一項測試是一項重要的測試。

def missing_important(a,b):

     如果a爲None:
        #handle例外
        a = 1/0#意圖錯誤
    回報(a + b)

def test_incomplete(self):
    #未測試異常處理
    self.assertEqual(missing_important(1,2),3)

單元測試是測試異常處理的一種絕妙方法,因爲開發人員可以完全控制上下文並可以注入測試錯誤所需的條件。 在系統級別或通過API工作的測試人員可能無法創建條件,在此示例中,變量“ a”的值爲“ None”。

後續測試步驟

這些示例很簡單,可以證明這些觀點,當然,在實踐中,單元測試也很有價值。 但是,高比例的單元測試覆蓋範圍並不能自動等於高質量的代碼。 測試也必須有效。

仍然需要測試人員檢查單元測試,以確保它們是最佳測試,使用自己的測試來改進或補充單元測試,在審查單元測試時牢記客戶需求的觀點,並確定哪些領域 單元測試涵蓋了這些內容,可以幫助優化集成和系統測試。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章