pytest 用例查詢原理

dongfanger發表於2020-09-30

當執行pytest命令時,pytest會從project中查詢test來執行。本文先從幾個路徑相關的概念講起,這樣便於理解pytest在遍歷路徑時的走向。

幾個路徑相關的概念

PYTHONHOME

定義了Python標準庫的路徑。

PYTHONPATH

定義了Python import模組搜尋的路徑。

basedir

①如果是module,目錄中不包括__init__.py,basedir的值等於a

a
|--b_test.py

②如果是package,目錄中包括__init__.py,basedir的值等於y

y
|--a
| |--b_test.py
| |--__init__.py // 表明a是package

③如果是package的package,目錄中都包括__init__.py,basedir的值等於x

x
|--y
| |--a
| |--__init__.py // 表明y是package
| | |--b_test.py
| | |--__init__.py // 表明a是package

sys.path

模組搜尋路徑集,包括以上3個目錄。它決定了import能否找到模組。

current working directory

當前工作目錄,縮寫cwd,等於執行pytest命令的目錄。

如果用python -m pytest,以模組的方式來執行,會把cwd也加入sys.path中。

例如,在a目錄下執行pytest,cwd是a,basedir是y,sys.path中只包含y。如果執行python -m pytest,sys.path中既包含y也包含a

y
|--a
| |--b_test.py
| |--__init__.py // 表明a是package

pytest查詢原理

第一種情況

pytest命令是可以加引數的,如果加了資料夾/檔案引數,那麼就只在引數指定的資料夾/檔案中查詢,可以指定多個。例如

pytest a_dir b_dir c_test.py d_test.py

特殊的,如果a_dir中包含了c_test.py,那麼會收整合2次,pytest也會執行2次。

也可以使用::來指定函式/類/方法,例如

pytest test_mod.py::test_func
pytest test_mod.py::TestClass::test_method

第二種情況

pytest不帶引數。

  • 從“當前工作目錄”開始找,遞迴查詢子目錄。匹配 test_*.py 或 *_test.py 的檔案。

  • 找到這些模組(Python中1個.py檔案就是1個模組)以後,進一步根據上節所述找basedir。

  • 呼叫sys.path.insert(0, basedir),把basedir加入sys.path中。這些模組就可以被pytest import了。

  • import之後,查詢test開頭的函式或方法。如果是類中的方法,類必須以Test開頭,並且沒有__init__方法。

公眾號dongfanger

相關文章