pytest文件60-pytest.main()的使用
前言
pytest 執行用例的時候,一般用命令列去執行,有些小夥伴不太習慣命令列執行用例,可能是之前深受 unittest 框架的影響,習慣在專案的根目錄下寫一個 run_all.py 的檔案。
執行的時候,使用 python 執行 run_all.py 來執行測試用例。
pytest.main()
先看看 pytest.main() 的原始碼, main 函式的內容
- args 傳一個list物件,list 裡面是多個命令列的引數
- plugins 傳一個list物件,list 裡面是初始化的時候需註冊的外掛
def main(args=None, plugins=None): """ return exit code, after performing an in-process test run. :arg args: list of command line arguments. :arg plugins: list of plugin objects to be auto-registered during initialization. """ from _pytest.main import EXIT_USAGEERROR try: try: config = _prepareconfig(args, plugins) except ConftestImportFailure as e: exc_info = ExceptionInfo(e.excinfo) tw = py.io.TerminalWriter(sys.stderr) tw.line( "ImportError while loading conftest '{e.path}'.".format(e=e), red=True ) exc_info.traceback = exc_info.traceback.filter(filter_traceback) exc_repr = ( exc_info.getrepr(style="short", chain=False) if exc_info.traceback else exc_info.exconly() ) formatted_tb = safe_str(exc_repr) for line in formatted_tb.splitlines(): tw.line(line.rstrip(), red=True) return 4 else: try: return config.hook.pytest_cmdline_main(config=config) finally: config._ensure_unconfigure() except UsageError as e: tw = py.io.TerminalWriter(sys.stderr) for msg in e.args: tw.line("ERROR: {}\n".format(msg), red=True) return EXIT_USAGEERROR
如果不帶任何引數,那麼執行的效果跟我們在 cmd 直接執行 pytest 命令一樣,預設執行的是當前目錄及子目錄的所有資料夾的測試用例
> pytest
run_all.py
在專案的根目錄,新建一個 run_all.py 的檔案
只需寫簡單的2行程式碼
import pytest
# 預設執行的是當前目錄及子目錄的所有資料夾的測試用例
pytest.main()
這樣就能在 pycharm 裡面右鍵執行,不帶引數預設運行當前目錄及子目錄的所有資料夾的測試用例
帶引數執行
在執行的時候,也可以指定引數執行
-s: 顯示程式中的 print/logging 輸出
-v: 豐富資訊模式, 輸出更詳細的用例執行資訊
-k: 執行包含某個字串的測試用例。如:pytest -k add XX.py 表示執行 XX.py 中包含 add 的測試用例。
-q: 簡單輸出模式, 不輸出環境資訊
-x: 出現一條測試用例失敗就退出測試。在除錯階段非常有用,當測試用例失敗時,應該先除錯通過,而不是繼續執行測試用例。
在命令列執行帶上 -s 引數
> pytest -s
那麼在 pytest.main() 裡面等價於
import pytest
# 帶上-s引數
pytest.main(["-s"])
在命令列執行帶上多個引數時
> pytest -s -x
那麼在 pytest.main() 裡面等價於
import pytest
# 帶上-s引數
pytest.main(["-s", "-x"])
指定執行某個用例
指定執行 cases/module1 資料夾下的全部用例, 在命令列執行時, 先 cd 到專案的根目錄
>pytest cases/module1
那麼在 pytest.main() 裡面等價於
import pytest
# 帶上-s引數
pytest.main(["cases/module1"])
執行指定的 cases/module1/test_x1.py 下的全部用例,在命令列執行時, 先cd到專案的根目錄
'''
pytest cases/module1/test_x1.py
'''
那麼在 pytest.main() 裡面等價於
import pytest
# 帶上-s引數
pytest.main(["cases/module1/test_x1.py"])
執行指定的 cases/module1/test_x1.py 下的某一個用例 test_x, 在命令列執行時, 先cd到專案的根目錄
'''
pytest cases/module1/test_x1.py::test_x
'''
那麼在 pytest.main() 裡面等價於
import pytest
# 帶上-s引數
pytest.main(["cases/module1/test_x1.py::test_x"])
通過上面跟命令列執行的對比,對 pytest.main() 的使用也就基本掌握了
plugins引數的使用
一般我們寫外掛的程式碼放到 conftest.py 會被pytest查詢到,如果不是寫到 conftest.py 的外掛內容,可以通過 plugins 引數指定載入
# run_all.py
import pytest
# 在run_all.py下自定義外掛
class MyPlugin(object):
def pytest_sessionstart(self):
print("*** test run start blog地址 https://www.cnblogs.com/yoyoketang/")
# plugins指定載入外掛
pytest.main(["cases/module1"], plugins=[MyPlugin()])
執行後會看到在引數用例開始之前答應上面的內容
*** test run start blog地址 https://www.cnblogs.com/yoyoketang/
============================= test session starts =============================
platform win32 -- Python 3.6.6, pytest-4.5.0, py-1.9.0, pluggy-0.13.1
Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type>
rootdir: D:\wangyiyun\web
plugins: repeat-0.8.0, rerunfailures-9.1, xdist-2.1.0
collected 5 items
cases\module1\test_x1.py . [ 20%]
cases\module1\test_x2.py .... [100%]
========================== 5 passed in 0.05 seconds ===========================
plugins引數的作用就是指定需載入的外掛,也可以指定多個。