Python pytest 用例查找原理

dongfanger · 2020年09月30日 · 117 次阅读

当执行 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__方法。

如果你觉得这篇文章写的还不错的话,关注公众号 “测试老树”,你的支持就是我写文章的最大动力。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册