Pytest特點
Pytest是Python的一個第三方單元測試庫。它的目的是讓單元測試變得更容易,並且也能擴充套件到支援應用層面複雜的功能測試。
Pytest的特點有:
- 入門簡單,易上手,文件豐富
- 支援用簡單的assert語句實現豐富的斷言,無需複雜的self.assert*函式
- 支援引數化
- 自動識別測試模組和測試函式
- 執行測試過程中可以將某些測試跳過(skip),或者對某些預期失敗的case標記成失敗
- 支援重複執行(rerun)失敗的 case
- 模組化夾具用以管理各類測試資源
- 對 unittest 完全相容
- 可以很好的和jenkins整合
- 豐富的外掛生態,有各式各樣的外掛,社群繁榮
快速入門
安裝pytest
使用 pip 進行安裝:
pip install pytest
安裝之後檢視版本:
pytest --version
快速開始
1.建立測試函式
Pytest 使用 Python 的 assert
進行條件判斷,最簡單的測試函式如:
# testdemo.py
def test_passing():
assert(1,2,3) ==(1,2,3)
2.執行測試函式
在當前檔案目錄使用命令pytest
執行測試函式:
3.pytest執行規則
pytest會查詢當前目錄及其子目錄下以test_
開頭的檔案或以_test
結尾的檔案,找到檔案後,執行檔案中以test開頭的 函式
4.建立測試類
# test_class.py
class TestClass:
def test_a(self):
x = "hello"
assert "h" in x
def test_b(self):
x = "hello"
assert "a" in x
在當前檔案目錄使用命令pytest
執行測試:
第一次測試通過,第二次測試失敗。 可以在斷言中檢視失敗的原因
Pytest執行用例命令列引數
除了pytest
命令,pytest還提供了很多執行用例的命令列引數,如下:
1.-v
輸出用例更加詳細的執行資訊,比如用例所在的檔案及用例名稱等
2.-s
輸出用例中的調式資訊,比如print的列印資訊等,我們在之前的test_class.py第3行加上一句 print(“測試除錯資訊”)
# test_class.py
class TestClass:
def test_a(self):
print("測試除錯資訊")
x = "hello"
assert "h" in x
def test_b(self):
x = "hello"
assert "a" in x
再執行一次用例看看
3.-m
執行被標記的測試用例
我們修改test_class.py檔案如下:
# test_class.py
import pytest
class TestClass:
def test_a(self):
print("測試除錯資訊")
x = "hello"
assert "h" in x
@pytest.mark.run_this_case
def test_b(self):
x = "hello"
assert "a" in x
使用命令 pytest -m run_this_case test_calss.py
執行
可以看到只執行了被標記的用例
4.-k
執行用例包含“關鍵字”的用例
我們修改test_class.py檔案如下:
# test_class.py
import pytest
class TestClass:
def test_a(self):
print("測試除錯資訊")
x = "hello"
assert "h" in x
def test_b(self):
x = "hello"
assert "a" in x
def test_rock(self):
x = "rock"
assert "o" in x
使用命令 pytest -k "rock" test_class.py
執行
5.-q
簡化控制檯的輸出,可以看到輸出資訊和上面的結果都不一樣, 下圖中有三個.代替了pass結果
6.--collect-only
羅列出所有當前目錄下所有的測試模組,測試類及測試函式
7.--tb=style
執行用例的時候,有些用例執行失敗的時候,螢幕上會出現一大堆的報錯內容,不方便快速檢視是哪些用例失敗,--tb=style
可以遮蔽測試用例執行輸出的回溯資訊,可以簡化用例失敗時的輸出資訊, style的選項有['auto', 'long', 'short', 'no', 'line', 'native'], 具體區別如下:
--tb=auto 有多個用例失敗的時候,只列印第一個和最後一個用例的回溯資訊
--tb=long 輸出最詳細的回溯資訊
--tb=short 輸入assert的一行和系統判斷內容
--tb=line 使用一行顯示錯誤資訊
--tb=native 只輸出python標準庫的回溯資訊
--tb=no 不顯示回溯資訊
8.--lf和--ff
--last-failed 只重新執行上次執行失敗的用例(或如果沒有失敗的話會全部跑)
--failed-first 執行所有測試,但首先執行上次執行失敗的測試(這可能會重新測試,從而導致重複的fixture setup/teardown)
我們修改test_class.py檔案如下:
# test_class.py
import pytest
class TestClass:
def test_a(self):
print("測試除錯資訊")
x = "hello"
assert "h" in x
def test_b(self):
x = "hello"
assert "a" in x
def test_rock(self):
x = "rock"
assert "o" in x
def test_c(self):
x = "world"
assert "q" in x
使用命令pytest
執行全部用例,結果如下:
可以看到執行了4條用例,失敗了2條
然後使用命令pytest --lf
,執行失敗的用例,結果如下:
可以看到只執行了兩條失敗的用例
最後我們使用命令pytest --ff
,先執行失敗的用例,再執行成功的用例,結果如下:
可以看到先執行了2條失敗的用例,然後執行了2條成功的用例
以上就是命令列執行測試用例時經常使用到的引數,這些引數不僅可以單獨使用,也可以組合一起使用,可以使用--help
來檢視更多命令的幫助資訊
Pytest收集測試用例的規則
- 從一個或者多個目錄開始查詢,你可以在命令列指定檔案或者目錄,如果未指定那麼從當前目錄開始收集用例
- 在該目錄和所有子目錄下遞迴查詢測試模組
- 測試模組是指檔名為test_.py或者_test.py的檔案
- 在測試模組中查詢以test_開頭的函式
- 查詢名字以Test開頭的類。其中首先篩選掉包含__init__()函式的類,再查詢類中以Test_開頭的類方法
規則驗證
我們按照以下目錄結構新建一個專案
程式碼如下:
case01.py
# case01.py# 測試函式def test_02(): assert 1 == 1# 普通函式def func(): assert 1 == 1
test_01.py
# test_01.py# 測試函式def test_01(): assert 1 == 1# 普通函式def func_01(): print("這是一個普通函式")# 測試類class TestClass_01(object): # 測試函式 def test_class_1(self): assert 1 == 1 # 普通函式 def func_class_1(self): assert 1 == 1# 普通類class NoTestClass_02(object): # 測試函式 def test_class_2(self): assert 1 == 1 # 普通函式 def func_class_2(self): assert 1 == 1
case.py
# 測試函式def test_02(): assert 1 == 1# 普通函式def func(): assert 1 == 1
在專案根目錄下執行pytest --collect-only
,結果如下:
可以看到,只有2條有效的測試用例
使用pytest -v
命令執行用例,結果如下:
只有test_01.py被識別為測試模組