Pytest单元测试系列[v1.0.0][配置文件]

理解Pytest的配置文件 Pytest里有哪些配置文件:

配置文件 描述:无论选择使用哪种配置文件,它们的格式几乎是一样的
pytest.ini pytest主配置文件,可以改变pytest默认行为
conftest.py 本地插件库,其中的hook函数和fixture将作用于该文件所在目录及其子目录
__init__.py 每个测试子目录都包含该文件时,在多个测试目录中可以出现同名的测试文件
tox.ini 如果你使用tox工具,会用到tox.ini,它与pytest.ini类似,只不过是tox的配置文件,可以把pytest的配置写在tox.ini里,就无需同时使用pytest.ini和tox.ini了
setup.cfg 它也采用ini文件格式,而且可以影响setup.py的行为,如果要发布一个python包,它的作用也很大,可以在setup.py文件里添加几行代码,使用python setup.py test 运行所有的pytest测试用例;如果打算发布python包,也可以使用setup.cfg文件存储pytest的配置信息
pytest.ini
; --- ; Excerpted from "Python Testing with pytest", ; published by The Pragmatic Bookshelf. ; Copyrights apply to this code. It may not be used to create training material, ; courses, books, articles, and the like. Contact us if you are in doubt. ; We make no guarantees that this code is fit for any purpose. ; Visit http://www.pragmaticprogrammer.com/titles/bopytest for more book information. ; --- [pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; ... more options ...

tox.ini
; --- ; Excerpted from "Python Testing with pytest", ; published by The Pragmatic Bookshelf. ; Copyrights apply to this code. It may not be used to create training material, ; courses, books, articles, and the like. Contact us if you are in doubt. ; We make no guarantees that this code is fit for any purpose. ; Visit http://www.pragmaticprogrammer.com/titles/bopytest for more book information. ; --- ; ... tox specific stuff ...[pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; ... more options ...

setup.cfg
; ... packaging specific stuff ...[tool:pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; ... more options ...

执行命令pytest --help能够看到所有设置选项
[pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found:markers (linelist)markers for test functions empty_parameter_set_mark (string) default marker for empty parametersets norecursedirs (args)directory patterns to avoid for recursion testpaths (args)directories to search for tests when no files or directories are given in the command line. usefixtures (args)list of default fixtures to be used with this project python_files (args)glob-style file patterns for Python test module discovery python_classes (args)prefixes or glob names for Python test class discovery python_functions (args)prefixes or glob names for Python test function and method discovery disable_test_id_escaping_and_forfeit_all_rights_to_community_support (bool) disable string escape non-ascii characters, might cause unwanted side effects(use at your ownconsole_output_style (string) console output: "classic", or with additional progress information ("progress" (percentage) | "count"). xfail_strict (bool)default for the strict parameter of xfail markers when not given explicitly (default: False) junit_suite_name (string) Test suite name for JUnit report junit_logging (string)Write captured log messages to JUnit report: one of no|system-out|system-err junit_duration_report (string) Duration time to report: one of total|call junit_family (string)Emit XML for schema: one of legacy|xunit1|xunit2 doctest_optionflags (args) option flags for doctests doctest_encoding (string) encoding used for doctest files cache_dir (string)cache directory path. filterwarnings (linelist) Each line specifies a pattern for warnings.filterwarnings. Processed after -W and --pythonwarnings. log_print (bool)default value for --no-print-logs log_level (string)default value for --log-level log_format (string)default value for --log-format log_date_format (string) default value for --log-date-format log_cli (bool)enable log display during test run (also known as "live logging"). log_cli_level (string)default value for --log-cli-level log_cli_format (string)default value for --log-cli-format log_cli_date_format (string) default value for --log-cli-date-format log_file (string)default value for --log-file log_file_level (string)default value for --log-file-level log_file_format (string) default value for --log-file-format log_file_date_format (string) default value for --log-file-date-format addopts (args)extra command line options minversion (string)minimally required pytest version rsyncdirs (pathlist)list of (relative) paths to be rsynced for remote distributed testing. rsyncignore (pathlist)list of (relative) glob-style paths to be ignored for rsyncing. looponfailroots (pathlist) directories to check for changes timeout (string)Timeout in seconds before dumping the stacks.Default is 0 which means no timeout. timeout_method (string)Timeout mechanism to use.'signal' uses SIGALRM if available, 'thread' uses a timer thread.The default is to use 'signal' and fall back to 'th timeout_func_only (bool) When set to True, defers the timeout evaluation to only the test function body, ignoring the time it takes when evaluating any fixtures used in t pytester_example_dir (string) directory to take the pytester example files fromenvironment variables: PYTEST_ADDOPTSextra command line options PYTEST_PLUGINScomma-separated plugins to load during startup PYTEST_DISABLE_PLUGIN_AUTOLOAD set to disable plugin auto-loading PYTEST_DEBUGset to enable debug tracing of pytest's internals

插件可以添加ini文件选项
除了前边列出来的这些选项,利用插件和conftest.py文件还可以添加新的选项,而且新增的选项也可以使用pytest --help查看。
更改默认命令行选项 经过前边的文章,已经涉猎到很多pytest选项了,例如-v/–verbose可以输出详细信息,-l/–showlocals可以查看失败测试用例里堆栈中的局部变量,你可能经常用到这些选项,但又不想重复输入,此时就可以借助pytest.ini文件里的addopts设置
[pytest] addopts = -rsxX -l --tb=short --strict

选项 介绍
-rsxX 表示pytest报告所有测试用例被跳过、预计失败、预计失败但实际通过的原因
-l 表示pytest报告所有失败测试用例的对战中的局部变量
–tb=short 表示简化堆栈回溯信息,只保留文件和行数
–strict 选项表示禁止使用未在配置文件中注册的标记
注册标记来防范拼写错误 在pytest.ini中注册标记:
[pytest] markers= smoke: Run the smoke test functions for tasks project get:Run the test functions that test tasks.get()

标记注册好后,可以通过pytest --markers来查看
(venv) E:\Programs\Python\Python_Pytest\pytest-nice>pytest --markers @pytest.mark.smoke: Run the smoke test functions for tasks project@pytest.mark.get:Run the test functions that test tasks.get()

这样当我们给addopts加上–strict时,没有注册的标记就不能再使用,因此也就尽可能减少拼写错误
指定pytest的最低版本号 minversion选项可以指定运行测试用例的pytest的最低版本,例如测试两个浮点数的值是否接近,我们会使用approx()函数,但这个功能直到pytest3.0才出现,为此我们可以在pytest.ini文件中添加
[pytest] minversion = 3.0

指定pytest忽略某些目录 pytest执行搜索时,会递归遍历所有子目录,可以使用norecurse选项简化pytest的搜索工作。
norecurse的默认值是.* build dist CVS _darcs {arch}*.egg
如果让pytest忽略Tasks项目的src目录,则需要加入norecursedirs里
[pytest] norecursedirs = .* venv src *.egg dist build

指定测试目录 testpaths只是pytest去哪里访问,它是一系列相对于根目录的路径,用于限定测试用例的搜索范围,只有在pytest未指定文件目录参数或者测试用例标识符时,该选项才会启动。
task_proj/ |------pytest.ini |------src ||------tasks ||------api.py ||------...... |------test |------conftest.py |------func ||------__init__py ||------test_add.py ||------...... |------unit |------__init__.py |------test_task.py |------......

例如这样的机构目录,我们要指定test目录为pytest的执行路径
[pytest] testpaths = test

然后只需要从tasks_proj开始运行pytest,pytest就会直接去找test路径。
更改测试搜索的规则 pytest的执行,是根据一定的规则搜索并运行测试的:
  • 从一个或多个目录开始查找
  • 在该目录和所有子目录下递归查找测试模块
  • 测试模块是指定文件名为test_.py和_test.py的文件
  • 在测试模块中查找以test_开头的函数名
  • 查找名字以Test开头的类,首先筛选掉包含__init__函数的类,再查找类中以Test_开头的类方法
接下来修改规则:
默认规则pytest寻找Test*开头的类,而这个类不能含有__init__()函数,可以使用python_classes来修改
[pytest] python_classes = *Test Test* *Suite

像python_classes一样,python_files可以更改默认的测试搜索规则,而不是仅查找以test_开头的文件和_test结尾的文件
[pytest] python_files = test_* *_test check_*

同样的可以修改搜索测试函数和方法的命名规则
[pytest] python_functions = test_* check_*

禁用XPASS 设置xfail_strict = true将会使那些被标记为@pytest.mark.xfail但是实际通过的测试用例也会报告为失败。
避免文件名冲突
duplicate |------dup_a ||------test_func.py |dup_b ||------test_func.py

两个py文件中分别写入函数test_a()和test_b()
def test_a(): pass

def test_b(): pass

如此目录结构,两个同名文件,虽然文件内容不同,但他们还是会冲突,可以单独运行py文件,但在duplicate路径下执行就不行了,会报如下错误:
(venv) E:\Programs\Python\Python_Pytest\SourceCode\ch6\duplicate>pytest ================== test session starts =================================== platform win32 -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0 rootdir: E:\Programs\Python\Python_Pytest, inifile: pytest.ini plugins: xdist-1.29.0, timeout-1.3.3, repeat-0.8.0, nice-0.1.0, instafail-0.4.1, forked-1.0.2, emoji-0.2.0, allure-pytest-2.6.3 collected 1 item / 1 errors=========================================== ERRORS ============================ ____________________ ERROR collecting SourceCode/ch6/duplicate/b/test_func.py __________________________ import file mismatch: imported module 'test_func' has this __file__ attribute: E:\Programs\Python\Python_Pytest\SourceCode\ch6\duplicate\a\test_func.py which is not the same as the test file we want to collect: E:\Programs\Python\Python_Pytest\SourceCode\ch6\duplicate\b\test_func.py HINT: remove __pycache__ / .pyc files and/or use a unique basename for your test file modules !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ============================== 1 error in 0.32 seconds ==========================================

【Pytest单元测试系列[v1.0.0][配置文件]】报错信息中也并没明显指出问题在哪,要解决这个问题,只需要在各个子目录里添加一个空的__init__.py文件即可,测试子目录添加__init__.py是个好习惯

    推荐阅读