Pytest单元测试系列[v1.0.0][pytest插件常用技巧]

使用pytest-xdist并发执行测试

pytest-xdist:Run Tests in Parallel

[https://pypi.python.org/pypi/pytest-xdist]
在自动化测试中有些资源只能同时被一个测试用例访问,如果不需要同时使用同一个资源,那么测试用例便可以并行执行
执行命令pip install pytest-xdist安装插件

E:\Programs\Python\Python_Pytest\TestScripts>pip install pytest-xdist
Collecting pytest-xdistDownloading https://files.pythonhosted.org/packages/9f/cc/371b2e6dfbf4e8df07b04e310dd6ea0b3f367e257d1e6cb516b25bc4af1b/pytest_xdist-1.29.0-py2.py3-none-any.whl
Collecting pytest-forked (from pytest-xdist)Downloading https://files.pythonhosted.org/packages/3f/55/ef92c340e723495dbee91d749903d2b7950b49c501943296257246d7d880/pytest_forked-1.0.2-py2.py3-none-any.whl
Requirement already satisfied: six in c:\python37\lib\site-packages (from pytest-xdist) (1.12.0)
Requirement already satisfied: pytest>=4.4.0 in c:\python37\lib\site-packages (from pytest-xdist) (4.5.0)
Collecting execnet>=1.1 (from pytest-xdist)Downloading https://files.pythonhosted.org/packages/77/1a/f69e1f73bc36f55d3273afd1c52936def71ac67d9c5215be3a4ca3a45577/execnet-1.6.0-py2.py3-none-any.whl
Requirement already satisfied: setuptools in c:\users\davieyang\appdata\roaming\python\python37\site-packages (from pytest>=4.4.0->pytest-xdist) (41.0.1)
Requirement already satisfied: py>=1.5.0 in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (1.8.0)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (0.4.1)
Requirement already satisfied: attrs>=17.4.0 in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (19.1.0)
Requirement already satisfied: pluggy!=0.10,<1.0,>=0.9 in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (0.11.0)
Requirement already satisfied: atomicwrites>=1.0 in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (1.3.0)
Requirement already satisfied: wcwidth in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (0.1.7)
Requirement already satisfied: more-itertools>=4.0.0; python_version > "2.7" in c:\python37\lib\site-packages (from pytest>=4.4.0->pytest-xdist) (7.0.0)
Collecting apipkg>=1.4 (from execnet>=1.1->pytest-xdist)Downloading https://files.pythonhosted.org/packages/67/08/4815a09603fc800209431bec5b8bd2acf2f95abdfb558a44a42507fb94da/apipkg-1.5-py2.py3-none-any.whl
Installing collected packages: pytest-forked, apipkg, execnet, pytest-xdist
Successfully installed apipkg-1.5 execnet-1.6.0 pytest-forked-1.0.2 pytest-xdist-1.29.0

使用pytest-xdist执行测试

E:\Programs\Python\Python_Pytest\TestScripts>pytest -n auto
================================ 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\TestScripts
plugins: xdist-1.29.0, repeat-0.8.0, forked-1.0.2, allure-pytest-2.6.3
gw0 [17] / gw1 [17] / gw2 [17] / gw3 [17]
...........FF..F.                                                                                                                                                    [100%]
=========================== FAILURES ================================================
________________________________________ test_true ____________________________________________
[gw2] win32 -- Python 3.7.3 c:\python37\python.exedef test_true():
>       assert not is_prime(7)
E       assert not True
E        +  where True = is_prime(7)test_asserts.py:65: AssertionError
__________________________________________ test_add4 ___________________________________________
[gw3] win32 -- Python 3.7.3 c:\python37\python.exedef test_add4():
>       assert add(17,22) >= 50
E       assert 39 >= 50
E        +  where 39 = add(17, 22)test_asserts.py:34: AssertionError
______________________________ test_not_equal _____________________________________________
[gw1] win32 -- Python 3.7.3 c:\python37\python.exedef test_not_equal():
>       assert (1, 2, 3) == (3, 2, 1)
E       assert (1, 2, 3) == (3, 2, 1)
E         At index 0 diff: 1 != 3
E         Use -v to get the full difftest_one.py:9: AssertionError
============================== 3 failed, 14 passed, 4 warnings in 2.20 seconds ===============================

参数说明

-n auto 自动侦测系统里的CPU数目
-n numprocesses 指定运行测试的处理器进程数

使用pytest-repeat重复执行用例

pytest-repeat:Run Tests More Than Once

运行命令pip install pytest-repeat[https://pypi.python.org/pypi/pytest-repeat]

E:\Programs\Python\Python_Pytest\TestScripts>pip install pytest-repeat
Collecting pytest-repeatDownloading https://files.pythonhosted.org/packages/2e/de/c1d69002db74a99b3df0463e95066c03d82d9d2a53be738c140207134e0f/pytest_repeat-0.8.0-py2.py3-none-any.whl
Requirement already satisfied: pytest>=3.6 in c:\python37\lib\site-packages (from pytest-repeat) (4.5.0)
Requirement already satisfied: attrs>=17.4.0 in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (19.1.0)
Requirement already satisfied: pluggy!=0.10,<1.0,>=0.9 in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (0.11.0)
Requirement already satisfied: wcwidth in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (0.1.7)
Requirement already satisfied: more-itertools>=4.0.0; python_version > "2.7" in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (7.0.0)
Requirement already satisfied: py>=1.5.0 in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (1.8.0)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (0.4.1)
Requirement already satisfied: setuptools in c:\users\davieyang\appdata\roaming\python\python37\site-packages (from pytest>=3.6->pytest-repeat) (41.0.1)
Requirement already satisfied: six>=1.10.0 in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (1.12.0)
Requirement already satisfied: atomicwrites>=1.0 in c:\python37\lib\site-packages (from pytest>=3.6->pytest-repeat) (1.3.0)
Installing collected packages: pytest-repeat
Successfully installed pytest-repeat-0.8.0

执行测试,运行命令pytest --count=2 -v

E:\Programs\Python\Python_Pytest\TestScripts>pytest --count=2 -v
======================== test session starts==============================================
platform win32 -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0 -- c:\python37\python.exe
cachedir: .pytest_cache
rootdir: E:\Programs\Python\Python_Pytest\TestScripts
plugins: repeat-0.8.0, allure-pytest-2.6.3
collected 34 items                                                                                                                                                         test_asserts.py::test_add[1-2] PASSED                                                                                                                                [  2%]
test_asserts.py::test_add[2-2] PASSED                                                                                                                                [  5%]
test_asserts.py::test_add2[1-2] PASSED                                                                                                                               [  8%]
test_asserts.py::test_add2[2-2] PASSED                                                                                                                               [ 11%]
test_asserts.py::test_add3[1-2] PASSED                                                                                                                               [ 14%]
test_asserts.py::test_add3[2-2] PASSED                                                                                                                               [ 17%]
test_asserts.py::test_add4[1-2] FAILED                                                                                                                               [ 20%]
test_asserts.py::test_add4[2-2] FAILED                                                                                                                               [ 23%]
test_asserts.py::test_in[1-2] PASSED                                                                                                                                 [ 26%]
test_asserts.py::test_in[2-2] PASSED                                                                                                                                 [ 29%]
test_asserts.py::test_not_in[1-2] PASSED                                                                                                                             [ 32%]
test_asserts.py::test_not_in[2-2] PASSED                                                                                                                             [ 35%]
test_asserts.py::test_true[1-2] FAILED                                                                                                                               [ 38%]
test_asserts.py::test_true[2-2] FAILED                                                                                                                               [ 41%]
test_fixture1.py::test_numbers_3_4[1-2] PASSED                                                                                                                       [ 44%]
test_fixture1.py::test_numbers_3_4[2-2] PASSED                                                                                                                       [ 47%]
test_fixture1.py::test_strings_a_3[1-2] PASSED                                                                                                                       [ 50%]
test_fixture1.py::test_strings_a_3[2-2] PASSED                                                                                                                       [ 52%]
test_fixture2.py::TestUM::test_numbers_5_6[1-2] PASSED                                                                                                               [ 55%]
test_fixture2.py::TestUM::test_numbers_5_6[2-2] PASSED                                                                                                               [ 58%]
test_fixture2.py::TestUM::test_strings_b_2[1-2] PASSED                                                                                                               [ 61%]
test_fixture2.py::TestUM::test_strings_b_2[2-2] PASSED                                                                                                               [ 64%]
test_one.py::test_equal[1-2] PASSED                                                                                                                                  [ 67%]
test_one.py::test_equal[2-2] PASSED                                                                                                                                  [ 70%]
test_one.py::test_not_equal[1-2] FAILED                                                                                                                              [ 73%]
test_one.py::test_not_equal[2-2] FAILED                                                                                                                              [ 76%]
test_two.py::test_default[1-2] PASSED                                                                                                                                [ 79%]
test_two.py::test_default[2-2] PASSED                                                                                                                                [ 82%]
test_two.py::test_member_access[1-2] PASSED                                                                                                                          [ 85%]
test_two.py::test_member_access[2-2] PASSED                                                                                                                          [ 88%]
test_two.py::test_asdict[1-2] PASSED                                                                                                                                 [ 91%]
test_two.py::test_asdict[2-2] PASSED                                                                                                                                 [ 94%]
test_two.py::test_replace[1-2] PASSED                                                                                                                                [ 97%]
test_two.py::test_replace[2-2] PASSED                                                                                                                                [100%]============================================ FAILURES ====================================
________________________________ test_add4[1-2] _______________________________________def test_add4():
>       assert add(17,22) >= 50
E       assert 39 >= 50
E        +  where 39 = add(17, 22)test_asserts.py:34: AssertionError
_________________________ test_add4[2-2] ______________________________________________def test_add4():
>       assert add(17,22) >= 50
E       assert 39 >= 50
E        +  where 39 = add(17, 22)test_asserts.py:34: AssertionError
________________________ test_true[1-2] __________________________________________def test_true():
>       assert not is_prime(7)
E       assert not True
E        +  where True = is_prime(7)test_asserts.py:65: AssertionError
____________________________ test_true[2-2] ______________________________________________def test_true():
>       assert not is_prime(7)
E       assert not True
E        +  where True = is_prime(7)test_asserts.py:65: AssertionError
__________________________ test_not_equal[1-2] ____________________________________________def test_not_equal():
>       assert (1, 2, 3) == (3, 2, 1)
E       assert (1, 2, 3) == (3, 2, 1)
E         At index 0 diff: 1 != 3
E         Full diff:
E         - (1, 2, 3)
E         ?  ^     ^
E         + (3, 2, 1)
E         ?  ^     ^test_one.py:9: AssertionError
_________________________________ test_not_equal[2-2] ____________________________________def test_not_equal():
>       assert (1, 2, 3) == (3, 2, 1)
E       assert (1, 2, 3) == (3, 2, 1)
E         At index 0 diff: 1 != 3
E         Full diff:
E         - (1, 2, 3)
E         ?  ^     ^
E         + (3, 2, 1)
E         ?  ^     ^test_one.py:9: AssertionError
=================== 6 failed, 28 passed, 1 warnings in 0.77 seconds =======================

可与重复一个测试子集,后者某一个测试,甚至可以让他在晚上重复执行N次,同时可以让他遇到错误就停止

使用pytest-instafail查看详细堆栈信息

当测试执行遇到失败或错误时能及时看到详细的堆栈信息

pytest-instafail:See Details of Failures and Errors

[https://pypi.python.org/pypi/pytest-instafail]
执行命令pip install pytest-instafail安装插件

E:\Programs\Python\Python_Pytest\TestScripts>pip install pytest-instafail
Collecting pytest-instafailDownloading https://files.pythonhosted.org/packages/fa/16/473621ad68cc2a1cb2888478e66db5080a06adf695470c8dd4ec669c25d5/pytest-instafail-0.4.1.tar.gz
Requirement already satisfied: pytest>=2.9 in c:\python37\lib\site-packages (from pytest-instafail) (4.5.0)
Requirement already satisfied: attrs>=17.4.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (19.1.0)
Requirement already satisfied: more-itertools>=4.0.0; python_version > "2.7" in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (7.0.0)
Requirement already satisfied: six>=1.10.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (1.12.0)
Requirement already satisfied: atomicwrites>=1.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (1.3.0)
Requirement already satisfied: setuptools in c:\users\davieyang\appdata\roaming\python\python37\site-packages (from pytest>=2.9->pytest-instafail) (41.0.1)
Requirement already satisfied: pluggy!=0.10,<1.0,>=0.9 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (0.11.0)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (0.4.1)
Requirement already satisfied: wcwidth in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (0.1.7)
Requirement already satisfied: py>=1.5.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-instafail) (1.8.0)
Building wheels for collected packages: pytest-instafailBuilding wheel for pytest-instafail (setup.py) ... doneStored in directory: C:\Users\davieyang\AppData\Local\pip\Cache\wheels\16\cb\de\3a1d2f5c992fedf9a86b8eead949a606a6c953228ac1fe0655
Successfully built pytest-instafail
Installing collected packages: pytest-instafail
Successfully installed pytest-instafail-0.4.1

通常情况下,pytest执行完毕后,会显示错误和失败用例的堆栈信息,如果测试用例比较多,运行时间太长,很可能我们希望不是到最才看到堆栈回溯信息,使用此插件便可以测试执行失败立马显示异常信息

执行测试

E:\Programs\Python\Python_Pytest\TestScripts>pytest --tb=line --instafail
========================= 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\TestScripts
plugins: xdist-1.29.0, timeout-1.3.3, repeat-0.8.0, instafail-0.4.1, forked-1.0.2, allure-pytest-2.6.3
collected 17 items                                                                                                                                                         test_asserts.py ...FE:\Programs\Python\Python_Pytest\TestScripts\test_asserts.py:34: assert 39 >= 50test_asserts.py ..FE:\Programs\Python\Python_Pytest\TestScripts\test_asserts.py:65: assert not Truetest_fixture1.py ..                                                                                                                                                  [ 52%]
test_fixture2.py ..                                                                                                                                                  [ 64%]
test_one.py .FE:\Programs\Python\Python_Pytest\TestScripts\test_one.py:9: assert (1, 2, 3) == (3, 2, 1)test_two.py ....                                                                                                                                                     [100%]
=================== 3 failed, 14 passed, 1 warnings in 0.32 seconds =======================

使用pytest-timeout设置执行测试的时限

pytest-timeout:Put Time Limits on Your Tests

[https://pypi.python.org/pypi/pytest-time]
运行命令pip install pytest-timeout,安装插件

E:\Programs\Python\Python_Pytest\TestScripts>pip install pytest-timeout
Collecting pytest-timeoutDownloading https://files.pythonhosted.org/packages/58/92/f60ea2e27074d6f97c8aaf21e34d1f838eb623e4b8070680846c65318a10/pytest_timeout-1.3.3-py2.py3-none-any.whl
Requirement already satisfied: pytest>=3.6.0 in c:\python37\lib\site-packages (from pytest-timeout) (4.5.0)
Requirement already satisfied: attrs>=17.4.0 in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (19.1.0)
Requirement already satisfied: atomicwrites>=1.0 in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (1.3.0)
Requirement already satisfied: six>=1.10.0 in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (1.12.0)
Requirement already satisfied: py>=1.5.0 in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (1.8.0)
Requirement already satisfied: more-itertools>=4.0.0; python_version > "2.7" in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (7.0.0)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (0.4.1)
Requirement already satisfied: wcwidth in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (0.1.7)
Requirement already satisfied: pluggy!=0.10,<1.0,>=0.9 in c:\python37\lib\site-packages (from pytest>=3.6.0->pytest-timeout) (0.11.0)
Requirement already satisfied: setuptools in c:\users\davieyang\appdata\roaming\python\python37\site-packages (from pytest>=3.6.0->pytest-timeout) (41.0.1)
Installing collected packages: pytest-timeout
Successfully installed pytest-timeout-1.3.3

执行命令pytest --timeout=0.1

E:\Programs\Python\Python_Pytest\TestScripts>pytest --timeout=0.1
======================== 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\TestScripts
plugins: xdist-1.29.0, timeout-1.3.3, repeat-0.8.0, forked-1.0.2, allure-pytest-2.6.3
timeout: 0.1s
timeout method: thread
timeout func_only: False
collected 17 items                                                                                                                                                         test_asserts.py ...F..F                                                                                                                                              [ 41%]
test_fixture1.py ..                                                                                                                                                  [ 52%]
test_fixture2.py ..                                                                                                                                                  [ 64%]
test_one.py .F                                                                                                                                                       [ 76%]
test_two.py ....                                                                                                                                                     [100%]================================== FAILURES ===============================================
_________________________________ test_add4 ______________________________________________def test_add4():
>       assert add(17,22) >= 50
E       assert 39 >= 50
E        +  where 39 = add(17, 22)test_asserts.py:34: AssertionError
______________________________ test_true ______________________________________________def test_true():
>       assert not is_prime(7)
E       assert not True
E        +  where True = is_prime(7)test_asserts.py:65: AssertionError
________________________________ test_not_equal _________________________________________def test_not_equal():
>       assert (1, 2, 3) == (3, 2, 1)
E       assert (1, 2, 3) == (3, 2, 1)
E         At index 0 diff: 1 != 3
E         Use -v to get the full difftest_one.py:9: AssertionError==================== 3 failed, 14 passed, 1 warnings in 0.32 seconds ======================

使用Tox在多环境下的用例执行

tox 测试多种配置

tox是个命令行工具,它允许测试在多种环境下运行,不仅仅是不同的python版本,可以以用它来测试不同的依赖配置和不同的操作系统配置,其工作方式是通过setup.py文件为待测程序创建源码安装包,他会查看tox.ini中的所有环境设置,并针对每个环境设置执行如下操作

安装tox

C:\Users\davieyang>pip install tox
Collecting toxUsing cached https://files.pythonhosted.org/packages/a7/0c/ed234b83d2c4fcef1cfccf97371183d51dafae62e64334de34d0a6333114/tox-3.14.0-py2.py3-none-any.whl
Collecting importlib-metadata<1,>=0.12; python_version < "3.8" (from tox)Downloading https://files.pythonhosted.org/packages/f6/d2/40b3fa882147719744e6aa50ac39cf7a22a913cbcba86a0371176c425a3b/importlib_metadata-0.23-py2.py3-none-any.whl
Requirement already satisfied: py<2,>=1.4.17 in c:\python37\lib\site-packages (from tox) (1.8.0)
Requirement already satisfied: six<2,>=1.0.0 in c:\python37\lib\site-packages (from tox) (1.12.0)
Collecting toml>=0.9.4 (from tox)Using cached https://files.pythonhosted.org/packages/a2/12/ced7105d2de62fa7c8fb5fce92cc4ce66b57c95fb875e9318dba7f8c5db0/toml-0.10.0-py2.py3-none-any.whl
Requirement already satisfied: packaging>=14 in c:\python37\lib\site-packages (from tox) (19.0)
Collecting filelock<4,>=3.0.0 (from tox)Downloading https://files.pythonhosted.org/packages/93/83/71a2ee6158bb9f39a90c0dea1637f81d5eef866e188e1971a1b1ab01a35a/filelock-3.0.12-py3-none-any.whl
Collecting virtualenv>=14.0.0 (from tox)Downloading https://files.pythonhosted.org/packages/8b/12/8d4f45b8962b03ac9efefe5ed5053f6b29334d83e438b4fe379d21c0cb8e/virtualenv-16.7.5-py2.py3-none-any.whl (3.3MB)100% |████████████████████████████████| 3.3MB 9.9kB/s
Collecting pluggy<1,>=0.12.0 (from tox)Downloading https://files.pythonhosted.org/packages/92/c7/48439f7d5fd6bddb4c04b850bb862b42e3e2b98570040dfaf68aedd8114b/pluggy-0.13.0-py2.py3-none-any.whl
Collecting zipp>=0.5 (from importlib-metadata<1,>=0.12; python_version < "3.8"->tox)Downloading https://files.pythonhosted.org/packages/74/3d/1ee25a26411ba0401b43c6376d2316a71addcc72ef8690b101b4ea56d76a/zipp-0.6.0-py2.py3-none-any.whl
Requirement already satisfied: pyparsing>=2.0.2 in c:\python37\lib\site-packages (from packaging>=14->tox) (2.4.0)
Requirement already satisfied: more-itertools in c:\python37\lib\site-packages (from zipp>=0.5->importlib-metadata<1,>=0.12; python_version < "3.8"->tox) (7.0.0)
Installing collected packages: zipp, importlib-metadata, toml, filelock, virtualenv, pluggy, toxFound existing installation: pluggy 0.11.0Uninstalling pluggy-0.11.0:Successfully uninstalled pluggy-0.11.0
Successfully installed filelock-3.0.12 importlib-metadata-0.23 pluggy-0.13.0 toml-0.10.0 tox-3.14.0 virtualenv-16.7.5 zipp-0.6.0

配置tox.ini

  • 在tox目录下创建一个虚拟环境
  • 使用pip安装依赖包
  • 使用pip在步骤1的虚拟环境中安装自己的程序包
  • 运行测试用例
  • 所有环境都测试完成后,tox生成一个汇总的测试结果
    在项目文件最顶层添加tox.ini文件(与setup.py放在一个目录里),然后在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.ini , put in same dir as setup.py[tox]
envlist = py27,py37[testenv]
deps=pytest
commands=pytest[pytest]
addopts = -rsxX -l --tb=short --strict
markers = smoke: Run the smoke test test functionsget: Run the test functions that test tasks.get()
选项描述
envlist=py27,py36表示使用python2.7和python3.6来运行测试用例
deps=pytest表示让tox确保pytest已经安装,如果有多个依赖还可以继续以相同方式罗列,并且还可以指定版本
commands=pytest告诉tox在每个环境里运行pytest

执行tox

然后在tox.ini所在路径下执行tox命令即可,它会使用指定的两个环境执行该路径下tests文件夹内的所有测试用例。

(venv) E:\Programs\Python\Python_Pytest\SourceCode\ch7\tasks_proj_v2>tox
GLOB sdist-make: E:\Programs\Python\Python_Pytest\SourceCode\ch7\tasks_proj_v2\setup.py
py37 create: E:\Programs\Python\Python_Pytest\SourceCode\ch7\tasks_proj_v2\.tox\py37
py37 installdeps: pytest
......
----------------------------------Summary----------------------------------------------------------------------------------
py27: commands succeeded
py36: commands succeeded
congratulations :)

使用pytest-sugar让测试结果更有趣

pytest-sugar: instafail+Colors+Progress Bar

使用命令pip install pytest-sugar安装插件

E:\Programs\Python\Python_Pytest\TestScripts>pip install pytest-sugar
Collecting pytest-sugarDownloading https://files.pythonhosted.org/packages/da/3b/f1e3c8830860c1df8f0e0f6713932475141210cfa021e362ca2774d2bf02/pytest_sugar-0.9.2-py2.py3-none-any.whl
Requirement already satisfied: pytest>=2.9 in c:\python37\lib\site-packages (from pytest-sugar) (4.5.0)
Collecting packaging>=14.1 (from pytest-sugar)Downloading https://files.pythonhosted.org/packages/91/32/58bc30e646e55eab8b21abf89e353f59c0cc02c417e42929f4a9546e1b1d/packaging-19.0-py2.py3-none-any.whl
Collecting termcolor>=1.1.0 (from pytest-sugar)Downloading https://files.pythonhosted.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz
Requirement already satisfied: atomicwrites>=1.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (1.3.0)
Requirement already satisfied: wcwidth in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (0.1.7)
Requirement already satisfied: attrs>=17.4.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (19.1.0)
Requirement already satisfied: six>=1.10.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (1.12.0)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (0.4.1)
Requirement already satisfied: py>=1.5.0 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (1.8.0)
Requirement already satisfied: setuptools in c:\users\davieyang\appdata\roaming\python\python37\site-packages (from pytest>=2.9->pytest-sugar) (41.0.1)
Requirement already satisfied: pluggy!=0.10,<1.0,>=0.9 in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (0.11.0)
Requirement already satisfied: more-itertools>=4.0.0; python_version > "2.7" in c:\python37\lib\site-packages (from pytest>=2.9->pytest-sugar) (7.0.0)
Collecting pyparsing>=2.0.2 (from packaging>=14.1->pytest-sugar)Downloading https://files.pythonhosted.org/packages/dd/d9/3ec19e966301a6e25769976999bd7bbe552016f0d32b577dc9d63d2e0c49/pyparsing-2.4.0-py2.py3-none-any.whl (62kB)100% |████████████████████████████████| 71kB 19kB/s
Building wheels for collected packages: termcolorBuilding wheel for termcolor (setup.py) ... doneStored in directory: C:\Users\davieyang\AppData\Local\pip\Cache\wheels\7c\06\54\bc84598ba1daf8f970247f550b175aaaee85f68b4b0c5ab2c6
Successfully built termcolor
Installing collected packages: pyparsing, packaging, termcolor, pytest-sugar
Successfully installed packaging-19.0 pyparsing-2.4.0 pytest-sugar-0.9.2 termcolor-1.1.0

执行测试

E:\Programs\Python\Python_Pytest\TestScripts>pytest
Test session starts (platform: win32, Python 3.7.3, pytest 4.5.0, pytest-sugar 0.9.2)
rootdir: E:\Programs\Python\Python_Pytest\TestScripts
plugins: xdist-1.29.0, timeout-1.3.3, sugar-0.9.2, repeat-0.8.0, instafail-0.4.1, forked-1.0.2, allure-pytest-2.6.3
collecting ... test_asserts.py ✓                                                                                                                                             6% ▋test_asserts.py ✓✓                                                                                                                                           12% █▎test_asserts.py ✓✓✓                                                                                                                                          18% █▊――――――――――――――――――――――――――――――――――――――――――test_add4――――――――――――――――――――――――――――――――――――――――def test_add4():
>       assert add(17,22) >= 50
E       assert 39 >= 50
E        +  where 39 = add(17, 22)test_asserts.py:34: AssertionErrortest_asserts.py ⨯                                                                                                                                            24% ██▍test_asserts.py ⨯✓                                                                                                                                           29% ██▉test_asserts.py ⨯✓✓                                                                                                                                          35% ███▌――――――――――――――――――――――――――――――――――――――― test_true――――――――――――――――――――――――――――――――――――――――――def test_true():
>       assert not is_prime(7)
E       assert not True
E        +  where True = is_prime(7)test_asserts.py:65: AssertionErrortest_asserts.py ⨯                                                                                                                                            41% ████▎test_fixture1.py ✓                                                                                                                                           47% ████test_fixture1.py ✓✓                                                                                                                                          53% ████
█▍    test_fixture2.py ✓                                                                                                                                           59% ████test_fixture2.py ✓✓                                                                                                                                          65% ████
██▌   test_one.py ✓                                                                                                                                                71% ████
███▏  ―――――――――――――――――――――――――――――――――――― test_not_equal ―――――――――――――――――――――――――――――――――――――――def test_not_equal():
>       assert (1, 2, 3) == (3, 2, 1)
E       assert (1, 2, 3) == (3, 2, 1)
E         At index 0 diff: 1 != 3
E         Use -v to get the full difftest_one.py:9: AssertionErrortest_one.py ⨯                                                                                                                                                76% █████
██▋  test_two.py ✓                                                                                                                                                82% ████test_two.py ✓✓                                                                                                                                               88% ████test_two.py ✓✓✓                                                                                                                                              94% ███test_two.py ✓✓✓✓                                                                                                                                            100% ███
███████
==================================== warnings summary ===================================
c:\python37\lib\site-packages\_pytest\mark\structures.py:324c:\python37\lib\site-packages\_pytest\mark\structures.py:324: PytestUnknownMarkWarning: Unknown pytest.mark.run_these_cases - is this a typo?  You can register custom mar
ks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.htmlPytestUnknownMarkWarning,-- Docs: https://docs.pytest.org/en/latest/warnings.htmlResults (0.47s):14 passed3 failed- test_asserts.py:33 test_add4- test_asserts.py:64 test_true- test_one.py:8 test_not_equal

使用PDB在测试失败时开启调试模式

PDB试失败的测试用例

--pdb是Python标准库里的调试模块,在pytest里,可以使用–pdb选项在测试失败是开启调试的交互模式

(venv) E:\Programs\Python\Python_Pytest\TestScripts>pytest --pdb -v -x --lf
========================== test session starts =====================================
platform win32 -- Python 3.7.3, pytest-4.5.0, py-1.8.0, pluggy-0.11.0 -- c:\python37\python.exe
cachedir: .pytest_cache
rootdir: E:\Programs\Python\Python_Pytest\TestScripts, 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 119 items                                                                                                                                                        
run-last-failure: no previously failed tests, not deselecting items.test_api_exceptions.py::TestAdd::test_missing_summary PASSED                                                                                                         [  0%]
test_api_exceptions.py::TestAdd::test_done_not_bool FAILED                                                                                                           [  1%]
>>>>>>>>>>>>>>>>>>> traceback >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>self = <TestScripts.test_api_exceptions.TestAdd object at 0x0000000CEEA430F0>def test_done_not_bool(self):"""Should raise an exception if done is not a bool."""with pytest.raises(ValueError):
>           tasks.add(Task(summary='summary', done='True'))
E           Failed: DID NOT RAISE <class 'ValueError'>test_api_exceptions.py:19: Failed
>>>>>>>>>>>>>>>>>>>>> entering PDB >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
> e:\programs\python\python_pytest\testscripts\test_api_exceptions.py(19)test_done_not_bool()
-> tasks.add(Task(summary='summary', done='True'))
(Pdb)

加上了--pdb参数的执行结果,我们看到最后进入了(Pdb)的交互模式,(Pdb)提示符出现了,表明可以使用pdb的交互调试功能

参数介绍
p/print expr输出expr的值
pp expr美化输出expr的值
l/list列出错误并显示错误之前和之后的5行代码
l/list begin,end列出错误,并通过行号指定需要显示的代码区域
a/args打印当前函数的参数列表(断点发生在帮助函数中会很实用)
u/up移动到堆栈的上一层
d/down移动到堆栈的下一层
q/quit退出当前调试会话
更多的pdb使用方法可参考PDB详细的使用方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/590418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

fastApi 项目部署

方式一&#xff0c;Uvicorn部署 Run a Server Manually - Uvicorn - FastAPI 1&#xff0c;linux服务器安装 python>3.8 2&#xff0c;安装 uvicorn : pip install "uvicorn[standard]" 3&#xff0c;上传项目到服务器 main.py from typing imp…

Leetcode每日一题周汇总 (12.24-12.30)

Leetcode每日一题周汇总 (12.24-12.30) 1.Sunday (12.24) 题目链接&#xff1a;1954. 收集足够苹果的最小花园周长 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个用无限二维网格表示的花园&#xff0c;每一个 整数坐标处都有一棵苹果树。整数坐标…

sql server如何判断关系模式属于哪个范式

判断关系模式属于哪个范式通常需要进行以下步骤&#xff1a; 1. 确定关系模式的属性集合和函数依赖&#xff1a;分析关系模式的属性集合&#xff0c;确定每个属性的含义和依赖关系。找出关系模式中的函数依赖&#xff0c;即属性之间的关联关系。 2. 检查第一范式&#xff08;…

PHP计算某时间段内有几个周及某时间为今年第几周函数

date_default_timezone_set(PRC); function count_weeks($startDate, $endDate ){//开始时间$startDate date(Y-m-d, $startDate);//结束时间if(empty($endDate)) {$endDate date(Y-m-d);}else{$endDate date(Y-m-d, $endDate);}//跨越天数$n (strtotime($endDate)-strtot…

设计模式设计原则——依赖倒置原则(DIP)

DIP&#xff1a;Dependence Inversion Principle 原始定义&#xff1a;High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions。 官…

Stable Diffusion API入门:简明教程

Stable Diffusion 是一个先进的深度学习模型&#xff0c;用于创造和修改图像。这个模型能够基于文本描述来生成图像&#xff0c;让机器理解和实现用户的创意。使用这项技术的关键在于掌握其 API&#xff0c;通过编程来操控图像生成的过程。 在探索 Stable Diffusion API 的世界…

ROS TF坐标变换 - TF树

目录 一、TF树介绍二、TF2与TF三、构建TF树四、rviz查看TF坐标关系 一、TF树介绍 在机器人系统中&#xff0c;存在运动学模型和动力学模型。对于刚体机器人&#xff0c;动力学模型基于刚体动力学&#xff0c;代表机器人系统在运动过程中力/力矩与其运动状态的变化关系。而运动…

【索引的数据结构】第1章节:B+Tree存储结构

目录结构 之前整篇文章太长&#xff0c;阅读体验不好&#xff0c;将其拆分为几个子篇章。 本篇章讲解 BTree 存储结构。 什么是索引 可以简单理解为索引好比一本书的目录&#xff0c;通过目录我们可以快速定位到我们要查看的章节。 MySQL 中的数据同样也是根据索引分类&…

Vue中目录以及文件内容简单分析

src文件下目录分析&#xff1a; App.vue文件中内容&#xff1a; vue文件中基本的三个结构&#xff0c;template&#xff08;结构&#xff09;、script&#xff08;行为&#xff09; 、style&#xff08;样式&#xff09;。 <template><!-- html结构 --><div cl…

如何在日常生活中节约时间。

问题描述&#xff1a;如何在日常生活中节约时间。 问题解答&#xff1a; 第一&#xff0c;睡觉前少玩手机&#xff0c;保证睡眠时间&#xff0c;确保早上能够按时起床。 第二&#xff0c;吃饭选择就近餐厅&#xff0c;尽量不要跑校外远的餐馆吃。 第三&#xff0c;减少无用…

三维重建 3D Gaussian Splatting:实时的神经场渲染

目录​​​​​​​ 概念理解三维高斯喷洒 依赖项: 编译报错: 预训练模型 13G:

linux释放交换空间-Swap

确保剩余内存比swap内存空间大&#xff0c;再执行以下操作&#xff0c;否则会宕机&#xff01; 查看swap分区 swapon -s 会查看到你的swap分区位置 停止swap分区 停止swap分区是将swap内存释放到实际内存中 swapoff /dev/dm-1开启swap分区 swap分区内存成功释放到实际内…

C# 如何读取Excel文件

当处理Excel文件时&#xff0c;从中读取数据是一个常见的需求。通过读取Excel数据&#xff0c;可以获取电子表格中包含的信息&#xff0c;并在其他应用程序或编程环境中使用这些数据进行进一步的处理和分析。本文将分享一个使用免费库来实现C#中读取Excel数据的方法。具体如下&…

matlab字符串标量或字符向量必须具备有效的解释器语法

Matlab报错&#xff1a; 字符串标量或字符向量必须具备有效的解释器语法:\hat{a} 为了能够产生需要的结果&#xff0c;需要使用下面的指令&#xff0c;就可以得到正确的坐标名称 xlabel(’ $\hat{a}$’, ‘interpreter’, ‘latex’)

SSH 端口转发:如何将服务绑定到本地 IP 地址

在日常工作中&#xff0c;我们经常需要访问位于远程服务器上的服务&#xff0c;如数据库、Web 应用程序或其他类型的服务器。直接访问这些服务可能会因为安全限制或网络配置而变得复杂或不可能。这时&#xff0c;SSH 端口转发就成了我们的得力助手。在本篇博客中&#xff0c;我…

2 - 表结构 | MySQL键值

表结构 | MySQL键值 表管理1. 库的操作2. 表的操作表的创建与删除表的修改复制表 3. 管理表记录 数据类型数值类型字符类型&#xff08;汉字或者英文字母&#xff09;日期时间类型 表头存储与日期时间格式的数据枚举类型 数据批量处理 表管理 客户端把数据存储到数据库服务器上…

开始使用MEVN技术栈开发01 概述

开始使用MEVN技术栈开发01 概述 简介 Welcome to Beginning MEVN Stack! This book focuses on the key tasks and concepts to get you started to learn and build MEVN stack applications in a faster pace. 欢迎阅读《MEVN堆栈入门》&#xff01;本书重点介绍关键任务…

C语言指针使用常见问题

1.*p&#xff1a; #include<stdio.h> int main() {char s[ ]"159",*p;ps;printf("%c",*p);printf("%c",*p);return 0; } 输出&#xff1a;15 注意点&#xff1a;根据符号的优先级&#xff0c;*p与*(p)可以等价 2.指针的初始化&#x…

黑豹程序员-vue3下载文件

原理 vue3利用在页面中动态创建a标签&#xff0c;设置a标签属性&#xff0c;触发a标签的click实现文件下载。 代码 在前端工程的public资源目录下&#xff0c;创建template模板文件目录&#xff0c;把要下周的模板文件放入&#xff1a;product-dir.xlsx <el-button type&…

Serverless Framework:开发无服务器应用的最佳工具 | 开源日报 No.133

serverless/serverless Stars: 45.6k License: MIT 该项目是 Serverless Framework&#xff0c;它是一个命令行工具&#xff0c;使用简单易懂的 YAML 语法部署代码和云基础设施以满足各种无服务器应用程序需求。支持 Node.js、Typescript、Python、Go 等多种编程语言&#xff…