二、第二章
2.1通過(guò)python -m pytest調(diào)用pytest ----- 調(diào)用方式后期完善其他調(diào)用
這是在2.0版本中新引入的功能。
你可以通過(guò)python的解釋器,利用命令行來(lái)調(diào)用測(cè)試:
python ‐m pytest [...]
這種調(diào)用方式幾乎等同于直接調(diào)用pytest […],但需要注意的是這種通過(guò)python來(lái)調(diào)用的方式同時(shí)會(huì)
將當(dāng)前目錄添加到sys.path
2.2退出碼
pytest有以下6種退出碼:
Exit code 0: 找到所有測(cè)試用例并測(cè)試通過(guò)
Exit code 1: 找到測(cè)試用例并運(yùn)行但是部分測(cè)試用例運(yùn)行失敗
Exit code 2: 用戶中斷了測(cè)試
Exit code 3: 執(zhí)行過(guò)程中發(fā)生了內(nèi)部錯(cuò)誤
Exit code 4: pytest命令行使用錯(cuò)誤
Exit code 5: 沒(méi)有找到任何測(cè)試用例
2.3 版本信息,參數(shù)名,環(huán)境變量的幫助
pytest ‐‐version #顯示pytest的import的路徑
pytest ‐‐fixtures #顯示內(nèi)置的函數(shù)參數(shù)
pytest ‐h | ‐‐help #幫助信息
2.4 第一(N)次測(cè)試失敗后停止
使用下面的參數(shù)可以讓測(cè)試在第1(N)次測(cè)試失敗后停止:
pytest ‐x # 第一次測(cè)試失敗后停止測(cè)試
pytest ‐‐maxfail=2 # 第2次測(cè)試失敗后停止測(cè)試
2.5指定/選擇測(cè)試用例
Pytest在命令行中支持多種方式來(lái)運(yùn)行和選擇測(cè)試用例:
對(duì)模塊中進(jìn)行測(cè)試:
pytest test_mod.py
對(duì)文件夾中進(jìn)行測(cè)試:
pytest testing/
通過(guò)關(guān)鍵字表達(dá)式來(lái)進(jìn)行測(cè)試:
pytest ‐k "MyClass and not method"
這種方式會(huì)執(zhí)行文件名,類名以及函數(shù)名與給定的字符串表達(dá)式相匹配的測(cè)試用例。 上面的用例會(huì)執(zhí)
行TestMyClass.test_something但是不會(huì)執(zhí)行TestMyClass.test_method_simple
and not 在這里是表達(dá)式,未經(jīng)過(guò)測(cè)試
通過(guò)節(jié)點(diǎn)id來(lái)進(jìn)行測(cè)試
每個(gè)被選中的測(cè)試用例都會(huì)被分配一個(gè)唯一的nodeid,它由模塊文件名和以下說(shuō)明符組成:參數(shù)化的
類名、函數(shù)名和參數(shù),用::分隔。
可以通過(guò)下面的方式運(yùn)行模塊中的指定的測(cè)試用例:
pytest test_mod.py::test_func
也可以通過(guò)下面這種方式:
pytest test_mod.py::TestClass::test_method
通過(guò)標(biāo)記符來(lái)進(jìn)行測(cè)試
pytest ‐m slow
這種方式會(huì)運(yùn)行所有通過(guò)裝飾器 @pytest.mark.slow進(jìn)行裝飾的測(cè)試用例。
關(guān)于標(biāo)記符請(qǐng)參考marks
通過(guò)包來(lái)運(yùn)行
pytest ‐‐pyargs pkg.testing
這種方式會(huì)導(dǎo)入pkg.testing,并且基于該包所在為止來(lái)查找并運(yùn)行測(cè)試用例。
2.6詳盡的測(cè)試報(bào)告
參數(shù)**-r**可以用來(lái)在測(cè)試結(jié)束后展示一份“測(cè)試概要信息”,這使得在大型測(cè)試套中獲取一份清楚
的測(cè)試結(jié)果(失敗,跳過(guò)等測(cè)試信息)十分簡(jiǎn)單。
示例:
#test_example.py的內(nèi)容
import pytest
@pytest.fixture
def error_fixture():
assert 0
def test_ok():
print("ok")
def test_fail():
assert 0
def test_error(error_fixture):
pass
def test_skip():
pytest.skip("skipping this test")
def test_xfail():
pytest.xfail("xfailing this test")
@pytest.mark.xfail(reason="always xfail")
def test_xpass():
pass
C:\>pytest ‐ra
2.7 測(cè)試失敗時(shí)自動(dòng)調(diào)用PDB
pytest允許通過(guò)命令行使能在測(cè)試失敗時(shí)自動(dòng)調(diào)用python的內(nèi)置調(diào)試工具PDB:
pytest ‐‐pdb
這會(huì)在每次測(cè)試失敗(或者發(fā)生KeyboardInterrupt)的時(shí)候都去調(diào)用PDB。通常我們可能只需要在第
一次測(cè)試失敗的時(shí)候來(lái)調(diào)用pdb:
pytest ‐x ‐‐pdb #首次失敗的時(shí)候調(diào)用pdb,然后結(jié)束測(cè)試進(jìn)程
pytest ‐‐pdb ‐‐maxfail=3 #前三次失敗的時(shí)候調(diào)用pdb
注意所有的異常信息都會(huì)保存在sys.last_value, sys.last_type和sys.last_traceback中。 在交互使用
中,這允許使用任何調(diào)試工具進(jìn)入后期調(diào)試。我們也可以手動(dòng)的訪問(wèn)這些異常信息,如下:
(Pdb) import sys
(Pdb) sys.last_traceback.tb_lineno
1448
(Pdb) sys.last_value
AssertionError('assert 0')
(Pdb) sys.last_type
<class 'AssertionError'>
2.8 測(cè)試啟動(dòng)時(shí)調(diào)用PDB
pytest允許在測(cè)試啟動(dòng)時(shí)立即調(diào)用pdb:
pytest ‐‐trace
這會(huì)在每個(gè)測(cè)試開始時(shí)立即調(diào)用python的pdb
2.9 設(shè)置斷點(diǎn)
在代碼中使用python的原生接口**python import pdb; pdb.set_trace()**來(lái)設(shè)置斷點(diǎn),在pytest中
會(huì)自動(dòng)禁用該測(cè)試的輸出捕獲:
*其他測(cè)試的輸出捕獲不會(huì)受影響
*先前的測(cè)試中已經(jīng)被捕獲的輸出會(huì)被正常處理
*同一測(cè)試中的后續(xù)輸出不會(huì)被捕獲,而被轉(zhuǎn)發(fā)給sys.stdout。注意即使退出交互式pdb繼續(xù)運(yùn)行測(cè)
試,這一設(shè)置依然生效
2.10分析測(cè)試時(shí)間
pytest.main()
這和在命令行中使用pytest是一樣的, 這種方式不會(huì)拋出SystemExit異常,而會(huì)返回exitcode, 通
過(guò)如下方式可以傳入調(diào)用參數(shù):
pytest.main(['‐x', 'mytestdir'])
你可以在pytest.main中指定額外的插件:
# myinvoke.py的內(nèi)容
import pytest
class MyPlugin(object):
def pytest_sessionfinish(self):
print("*** test run reporting finishing")
pytest.main(["‐qq"], plugins=[MyPlugin()])
運(yùn)行代碼就可以發(fā)現(xiàn)MyPlugin被添加到hook里并被調(diào)用:
C:\>python myinvoke.py
**注意:**調(diào)用pytest.main()會(huì)導(dǎo)入你的測(cè)試用例及其所引用的所有的模塊。因?yàn)閜ython存在模塊導(dǎo)
入的緩存機(jī)制,如果多次調(diào)用pytest.main(),后續(xù)的調(diào)用也不會(huì)再刷新這些導(dǎo)入的資源。因此,不建
議再同一進(jìn)程中多次調(diào)用pytest.main() (比如重新運(yùn)行測(cè)試).