pytest之執行測試pytest.main()的使用
前言
pytest 執行用例的時候,一般用命令列去執行,可能是之前深受 unittest 框架的影響,習慣在專案的根目錄下寫一個 run_all.py 的檔案。【使用pytest測試框架一般使用pytest.ini主檔案指定執行測試用例;詳細檢視:https://www.cnblogs.com/hls-code/p/14983585.html】
執行的時候,使用 python 執行 run_all.py 來執行測試用例。
pytest.main()
先看看 pytest.main() 的原始碼,main 函式的內容:
- args 傳一個list物件,list 裡面是多個命令列的引數。【包括執行的測試用例(例如:test_a.py);執行測試用例的命令列引數(例如:-vs)】
- 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
pytest如果不帶任何引數,那麼執行的效果跟我們在 cmd 直接執行 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: 出現一條測試用例失敗就退出測試。在除錯階段非常有用,當測試用例失敗時,應該先除錯通過,而不是繼續執行測試用例。
1、在命令列執行帶上 -s 引數:pytest -s
那麼在 pytest.main() 裡面等價於:
import pytest # 帶上-s引數 pytest.main(["-s"])
2、在命令列執行帶上多個引數時:pytest -s -x
那麼在 pytest.main() 裡面等價於:
import pytest # 帶上-s -x引數 pytest.main(["-s", "-x"])
指定執行某個用例
1、指定執行 cases/module1 資料夾下的全部用例, 在命令列執行時, 先 cd 到專案的根目錄:pytest cases/module1
那麼在 pytest.main() 裡面等價於:
import pytest # 執行指定資料夾目錄 pytest.main(["cases/module1"])
2、執行指定的 cases/module1/test_x1.py 下的全部用例,在命令列執行時, 先cd到專案的根目錄:pytest cases/module1/test_x1.py
那麼在 pytest.main() 裡面等價於:
import pytest # 執行指定py檔案 pytest.main(["cases/module1/test_x1.py"])
3、執行指定的 cases/module1/test_x1.py 下的某一個用例 test_x, 在命令列執行時, 先cd到專案的根目錄:pytest cases/module1/test_x1.py::test_x
那麼在 pytest.main() 裡面等價於:
import pytest # 執行指定py檔案下的test_x pytest.main(["cases/module1/test_x1.py::test_x"])
plugins引數的使用
一般我們寫外掛的程式碼放到 conftest.py 會被pytest查詢到,如果不是寫到 conftest.py 的外掛內容,可以通過 plugins 引數指定載入:【預設級別相當於fixture函式中的session級別】
# 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引數的作用就是指定需載入的外掛,也可以指定多個。
去期待陌生,去擁抱驚喜。