1. 程式人生 > >Python程式碼覆蓋率分析工具Coverage

Python程式碼覆蓋率分析工具Coverage

簡介

在測試中,為了度量產品質量,程式碼覆蓋率被作為一種測試結果的評判依據,在Python程式碼中用來分析程式碼覆蓋率的工具當屬Coverage。程式碼覆蓋率是由特定的測試套件覆蓋被測原始碼的程度來度量,Coverage是一種用於統計Python程式碼覆蓋率的工具,通過它可以檢測測試程式碼的有效性,即測試case對被測程式碼的覆蓋率幾何。
Coverage支不僅持分支覆蓋率統計,還可以生成HTML/XML報告。並且XML報告可以結合Jenkins和Sonar整合工具一起使用。
Coverage官方文件:http://coverage.readthedocs.org/en/latest/

安裝

Coverage作為Python的一個第三方庫,使用時需要先安裝,使用pip命令進行安裝。

安裝命令:pip install coverage

C:\Users\TynamYang>pip install coverage
Collecting coverage
Downloading coverage-5.1-cp37-cp37m-win32.whl (204 kB)
|████████████████████████████████| 204 kB 731 kB/s
Installing collected packages: coverage
Successfully installed coverage-5.1

C:\Users\TynamYang>

安裝完成後可以看到安裝的版本:coverage-5.1

安裝完成後使用coverage,coverage有兩種使用方法,一種是在命令列中使用,一種是呼叫API使用。方便控制部分需要測試的程式碼。

命令列中使用

1、基本引數
命令列中使用文件:http://coverage.readthedocs.org/en/latest/cmd.html
命令列中使用時常用引數:

  • run – 執行Python程式並收集執行資料
  • report – 報告覆蓋率結果
  • html – 生成HTML檔案,內容含覆蓋率結果列表
  • json – 生成JSON檔案,內容含覆蓋率結果
  • xml – 生成XML報告檔案,內容含覆蓋率結果
  • erase – 清除之前收集的覆蓋率資料
  • combine – 合併多個數據檔案
  • debug – 獲取除錯資訊

可以使用help命令檢視幫助: coverage help

2、執行程式碼收集資訊
在使用coverage時,基本需要兩步執行,第一步執行原始碼,收集被測試的原始碼覆蓋率的資訊,第二步生成程式碼覆蓋率的資訊報告。
如下測試程式碼:

#test.py
# coding:utf-8

import unittest

def add_numb(a, b):
    return a + b

def division_numb(a, b):
    return a / b

class Test(unittest.TestCase):
    def test_add_1(self):
        self.assertEqual(add_numb(1,1), 2)

    def test_add_2(self):
        self.assertEqual(add_numb(2,0), 1)

    def test_division_1(self):
        self.assertEqual(division_numb(2,1), 2)

    def test_division_2(self):
        self.assertEqual(division_numb(2,0), 2)

if __name__ == "__main__":
    unittest.main(verbosity=2)

使用命令執行: coverage run test.py

C:\Users\TynamYang\Desktop> coverage run test.py
test_add_1 (__main__.Test) ... ok
test_add_2 (__main__.Test) ... FAIL
test_division_1 (__main__.Test) ... ok
test_division_2 (__main__.Test) ... ERROR

======================================================================
ERROR: test_division_2 (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 22, in test_division_2
self.assertEqual(division_numb(2,0), 2)
File "test.py", line 9, in division_numb
return a / b
ZeroDivisionError: division by zero

======================================================================
FAIL: test_add_2 (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test.py", line 16, in test_add_2
self.assertEqual(add_numb(2,0), 1)
AssertionError: 2 != 1

----------------------------------------------------------------------
Ran 4 tests in 0.003s

FAILED (failures=1, errors=1)
PS C:\Users\TynamYang\Desktop>

程式碼執行完成後會生成一個覆蓋率統計結果檔案:.coverage。該檔名可通過設定COVERAGE_FILE環境變數進行修改。

3、生成報告
檢視報告有兩種方式,一種是在當前命令列模式下檢視,一種是生成HTML報告檔案檢視。
命令列模式下檢視
根據執行程式碼後生成的.coverage檔案,使用report引數可在命令列模式下檢視覆蓋率統計結果。
使用命令:coverage report

PS C:\Users\TynamYang\Desktop> coverage report
Name      Stmts   Miss  Cover
-----------------------------
test.py      16      0   100%
PS C:\Users\TynamYang\Desktop>

由結果可以得知,執行的test.py檔案,程式碼覆蓋率是100%
結果展示中的欄位含義:

  • tmts:語句總數
  • Miss:未執行到的語句數
  • Cover:覆蓋率,計算公式 Cover=(Stmts-Miss)/Stmts

生成HTML報告檔案
使用命令生成HTML報告:coverage html -d covhtml
其中引數-d是指定生成的html所在的資料夾名
命令執行完成後會生成一個covhtml檔案。

檔案中的index.html檔案覆蓋率資料統計。
也可以看一些示例:https://nedbatchelder.com/files/sample_coverage_html/

各欄位說明:

  • Stmts 總的有效程式碼行數(不包含空行和註釋行)
  • Miss 未執行的程式碼行數(不包含空行和註釋行)
  • Branch 總分支數
  • BrMiss 未執行的分支數
  • Cover 程式碼覆蓋率
  • Missing 未執行的程式碼部分在原始檔中行號

以執行的測試原檔案命名的檔案,可以高亮顯示覆蓋和未覆蓋的程式碼。如test_py.html。
也可以看一些示例,如http://nedbatchelder.com/code/coverage/sample_html/

呼叫API使用

呼叫API使用文件:http://coverage.readthedocs.org/en/latest/api.html
在python程式碼中通過呼叫coverage模組執行程式碼生成程式碼覆蓋率的統計結果。使用方法也非常簡單,如下示例:

if __name__ == "__main__":
    # 例項化物件
    cov = coverage.coverage()
    # 開始分析
    cov.start()
    suite = unittest.defaultTestLoader.discover(os.getcwd(), "test.py")
    unittest.TextTestRunner().run(suite)
    # 結束分析
    cov.stop()
    # 結果儲存
    cov.save()
    # 命令列模式展示結果
    cov.report()
    # 生成HTML覆蓋率報告
    cov.html_report(directory='covhtml')

&n