在上一篇文章中,我們利用 leetcode 的題目介紹如何用 pytest 寫單元測試, 不過我們只用了一組測試資料,感覺對測試對象還不是那麼有信心,所以我們來多增加一些測項吧!
更多測項
python
def test_solution():
nums = [4, 5, 0, -2, -3, 1]
k = 5
ans = 7
solution = Solution()
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
nums = [5]
k = 9
ans = 0
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
nums = [23, 2, 6, 4, 7]
k = 6
ans = 3
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
nums = [-5]
k = 5
ans = 1
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
nums = [0]
k = 2
ans = 1
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
我們補上那麼多測項而測試依然可以通過,感覺信心值也拉滿了
唯一的問題就是這單元測試好像太冗長了,無法一眼就看出你要測試什麼 , 如果別人想透過單元測試了解你寫的程式碼,他反而要先看你這一長串測試代碼, 有人或許已經想到要用迴圈或 mapping 去管理測資,不過既然我們都要用 pytest
框架了,測資這種小事就也交給他吧
使用 parametrize
python
@pytest.mark.parametrize(
('nums', 'k', 'ans'),
[
([4, 5, 0, -2, -3, 1], 5, 7),
([5], 9, 0),
([-5], 5, 1),
([0], 2, 1)
]
)
def test_solution(ans, nums, k):
solution = Solution()
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
程式碼說明:
- 第一個參數(
argnames
) 要填入我們測資的參數名稱,而該參數名稱也要在測試函數有個接收的參數,只要名字有對上就可以 - 第二個參數(
argvalues
) 則是我們測資的值,任何型態都可以 - 測試函數一樣透過斷言來判斷是不是我們預期的答案
透過裝飾器 pytest.mark.parametrize
就可以方便的管理多個測資,整個測試看起來也清爽很多
接著在 terminal 輸入 pytest
,可以看到 pytest 是把它當成多個測試項
如果輸入 pytest -v
有更詳細的測項資訊
ids
可以再透過 ids 給每個測項一個專屬名稱
python
@pytest.mark.parametrize(
('nums', 'k', 'ans'),
[
([4, 5, 0, -2, -3, 1], 5, 7),
([5], 9, 0),
([-5], 5, 1),
([0], 2, 1)
],
ids=['case0', 'case1', 'case2', 'case3']
)
def test_solution(ans, nums, k, request):
# print(request.node.callspec.id) # 如果你想在程式碼中看到 id 可以加這句
solution = Solution()
assert ans == solution.subarray_div_by_k(nums=nums, k=k)
只是不會像動漫一樣能讓命名魔物變強;命名的測項只是方便你看而已,不會進化
哈哈