前言:
單元測試是保證程序質量的基石,也是考驗編程功底的第一道關卡!
編寫和執行單元測試,是爲了證明目標代碼的行爲和我們期望的一致,更是爲了給上級模塊提供良好穩定的執行環境;
1. 觀察目標函數全部的邏輯分支,針對它們設計用例:
項目需求爲“判斷是否爲超人”,下面我基於Python3,用判斷覆蓋法來設計參數對其進行單元測試:
# coding = utf-8
import pytest
"""第一步:根據傳入的參數判斷目標是否爲超人(Superman)"""
def is_superman(skill, hand):
# 是否擁有飛行能力?
can_fly = skill
# 是否有10個手指?
have_ten_fingers = hand
if not can_fly:
return False
if not have_ten_fingers:
return False
# 返回 True,表示檢查的目標是一個真正的"超人"
return True
2. 對is_superman
函數設計一個“邏輯分支”表,可以看到共有3步(有幾列就有幾步),所以我們至少需要設計3組用例:
**注意:下面表格中的 0 表示 False,1 表示 True**
分支 & 步 | 1 | 2 | 3 |
---|---|---|---|
if | 0 | 1 | - |
if | - | 0 | 1 |
return | - | - | 1 |
3. 遍歷目標函數的全部路徑的思路:
接下來對這個目標函數設計一個測試器,用3組條件覆蓋測試
基於 Python3 的代碼舉例——測試函數
"""第二步:準備3組參數,逐個傳入目標函數並驗證其結果"""
def test_person():
"""由於在python裏 0==False,1==True ,所以你可以這樣設計3組簡單的測試用例:"""
test_cases = [
[0, 0],
[1, 0],
[1, 1]
]
"""根據上面3組用例,設計你的預期結果"""
expected_results = [False, False, True]
"""for循環幫你覆蓋全部用例"""
for i in range(len(test_cases)):
assert is_superman(test_cases[i][0], test_cases[i][1]) == expected_results[i]
if __name__ == '__main__':
pytest.main()
4. 運行腳本,查看測試結果:
============================= test session starts ==============================
platform darwin -- Python 3.6.8, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /Users/terry/PycharmProjects/SuperMancollected 1 item
test_func_unittest.py . [100%]
=========================== 1 passed in 0.01 seconds ===========================
Process finished with exit code 0
5. 嘗試增加一條用例,然後運行腳本,查看新的測試結果:
def test_person():
test_cases = [
[0, 0],
[1, 0],
[1, 1],
[0, 1], # <--增加1條用例
]
expected_results = [False, False, True, True] # <--對應增加一個預期結果
============================= test session starts ==============================
platform darwin -- Python 3.6.8, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /Users/terry/PycharmProjects/SuperMancollected 1 item
test_func_unittest.py F
test_func_unittest.py:26 (test_person)
False != True
Expected :True
Actual :False
<Click to see difference>
def test_person():
"""由於在python裏 0==False,1==True ,所以你可以這樣設計3組簡單的測試用例:"""
test_cases = [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
]
"""根據上面3組用例,設計你的預期結果"""
expected_results = [False, False, True, True]
"""for循環幫你覆蓋全部用例"""
for i in range(len(test_cases)):
> assert is_superman(test_cases[i][0], test_cases[i][1]) == expected_results[i]
E assert False == True
E + where False = is_superman(0, 1)
test_func_unittest.py:41: AssertionError
[100%]
=================================== FAILURES ===================================
_________________________________ test_person __________________________________
def test_person():
"""由於在python裏 0==False,1==True ,所以你可以這樣設計3組簡單的測試用例:"""
test_cases = [
[0, 0],
[1, 0],
[1, 1],
[0, 1],
]
"""根據上面3組用例,設計你的預期結果"""
expected_results = [False, False, True, True]
"""for循環幫你覆蓋全部用例"""
for i in range(len(test_cases)):
> assert is_superman(test_cases[i][0], test_cases[i][1]) == expected_results[i]
E assert False == True
E + where False = is_superman(0, 1)
test_func_unittest.py:41: AssertionError
=========================== 1 failed in 0.04 seconds ===========================
Process finished with exit code 0