【pytest单元测试框架】(3)pytest 扩展
pytest 扩展
Pytest 可以扩展非常多的插件来实现各种功能,这里介绍几个对做 Web 自动化测试非常有用的插件。
1、pytest-html
pytest-html 可以生成 HTML 格式的测试报告。首先,通过 pip 命令安装 pytest-html 扩展。
pip install pytest-html
其次,运行测试用例,并生成测试报告
pytest ./ --html=./report/result.html
最后,在 report 目录下打开 result.html,pytest-html 测试报告如图所示:
2、pytest-rerunfailures
pytest-rerunfailures 可以在测试用例失败时进行重试:
pip install pytest-rerunfailures
通过“--reruns”参数设置测试用例运行失败后的重试次数:
(base_practice) D:\00test\base_practice\pyTest>pytest -v ./ --reruns 3 --html=./report/20211118result.html =============================================================== test session starts =============================================================== platform win32 -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 -- C:\Users\yzp\PycharmProjects\base_practice\Scripts\python.exe cachedir: .pytest_cache metadata: {'Python': '3.7.4', 'Platform': 'Windows-10-10.0.19041-SP0', 'Packages': {'pytest': '6.2.5', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins' : {'html': '3.1.1', 'metadata': '1.11.0', 'rerunfailures': '10.2'}, 'JAVA_HOME': 'C:\\Program Files\\Java\\jdk1.8.0_311'} rootdir: D:\00test\base_practice\pyTest plugins: html-3.1.1, metadata-1.11.0, rerunfailures-10.2 collected 17 items test_assert.py::test_add1 PASSED [ 5%] test_assert.py::test_add2 RERUN [ 11%] test_assert.py::test_add2 RERUN [ 11%] test_assert.py::test_add2 RERUN [ 11%] test_assert.py::test_add2 FAILED [ 11%] test_assert.py::test_isprime1 PASSED [ 17%] test_assert.py::test_isprime2 PASSED [ 23%] test_assert.py::test_in PASSED [ 29%] test_assert.py::test_not_in PASSED [ 35%] test_fixtrue01.py::test_35 RERUN [ 41%] test_fixtrue01.py::test_35 RERUN [ 41%] test_fixtrue01.py::test_35 RERUN [ 41%] test_fixtrue01.py::test_35 FAILED [ 41%] test_fixtrue01.py::test_45 PASSED [ 47%] test_fixtrue02.py::TestMul::test_mul35 RERUN [ 52%] test_fixtrue02.py::TestMul::test_mul35 RERUN [ 52%] test_fixtrue02.py::TestMul::test_mul35 RERUN [ 52%] test_fixtrue02.py::TestMul::test_mul35 FAILED [ 52%] test_fixtrue02.py::TestMul::test_mul45 PASSED [ 58%] test_parameterized.py::test_row[case1] PASSED [ 64%] test_parameterized.py::test_row[case2] RERUN [ 70%] test_parameterized.py::test_row[case2] RERUN [ 70%] test_parameterized.py::test_row[case2] RERUN [ 70%] test_parameterized.py::test_row[case2] FAILED [ 70%] test_parameterized.py::test_row[case3] PASSED [ 76%] test_parameterized.py::test_row[case4] PASSED [ 82%] test_rerun.py::test_fail RERUN [ 88%] test_rerun.py::test_fail RERUN [ 88%] test_rerun.py::test_fail RERUN [ 88%] test_rerun.py::test_fail FAILED [ 88%] test_sample.py::test_answer RERUN [ 94%] test_sample.py::test_answer RERUN [ 94%] test_sample.py::test_answer RERUN [ 94%] test_sample.py::test_answer FAILED [ 94%] test_project/test_sub.py::test_baidu PASSED [100%] ==================================================================== FAILURES ===================================================================== ____________________________________________________________________ test_add2 ____________________________________________________________________ def test_add2(): > assert add(5, 5) > 10 E assert 10 > 10 E + where 10 = add(5, 5) test_assert.py:34: AssertionError _____________________________________________________________________ test_35 _____________________________________________________________________ def test_35(): > assert mul(3, 5) == 14 E assert 15 == 14 E +15 E -14 test_fixtrue01.py:41: AssertionError -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ===========setup_module========= ==========setup_founction========= ==========setup========= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- =========teardowm========== ==========setup_founction========== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==========setup_founction========= ==========setup========= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- =========teardowm========== ==========setup_founction========== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==========setup_founction========= ==========setup========= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- =========teardowm========== ==========setup_founction========== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==========setup_founction========= ==========setup========= _______________________________________________________________ TestMul.test_mul35 ________________________________________________________________ self = <pyTest.test_fixtrue02.TestMul object at 0x000002095B02FA48> def test_mul35(self): > assert mul(3, 5) == 16 E assert 15 == 16 E +15 E -16 test_fixtrue02.py:41: AssertionError -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ===============setup_class=============== ==============setup_method================= ==========setup============= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- ===========teardown============ ==============teardown_method============== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==============setup_method================= ==========setup============= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- ===========teardown============ ==============teardown_method============== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==============setup_method================= ==========setup============= ------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------- ===========teardown============ ==============teardown_method============== -------------------------------------------------------------- Captured stdout setup -------------------------------------------------------------- ==============setup_method================= ==========setup============= _________________________________________________________________ test_row[case2] _________________________________________________________________ base = 3, exponent = 3, expected = 9 @pytest.mark.parametrize( "base, exponent, expected", ((2, 2, 4), (3, 3, 9), (2, 3, 8), (0, 9, 0)), ids=["case1", "case2", "case3", "case4"]) def test_row(base, exponent, expected): > assert math.pow(base, exponent) == expected E assert 27.0 == 9 E +27.0 E -9 test_parameterized.py:18: AssertionError ____________________________________________________________________ test_fail ____________________________________________________________________ def test_fail(): > assert 2+2 == 5 E assert 4 == 5 E +4 E -5 test_rerun.py:2: AssertionError ___________________________________________________________________ test_answer ___________________________________________________________________ def test_answer(): > assert inc(3) == 5 E assert 4 == 5 E +4 E -5 test_sample.py:13: AssertionError ------------------------------ generated html file: file://D:\00test\base_practice\pyTest\report\20211118result.html ------------------------------ ============================================================= short test summary info ============================================================= FAILED test_assert.py::test_add2 - assert 10 > 10 FAILED test_fixtrue01.py::test_35 - assert 15 == 14 FAILED test_fixtrue02.py::TestMul::test_mul35 - assert 15 == 16 FAILED test_parameterized.py::test_row[case2] - assert 27.0 == 9 FAILED test_rerun.py::test_fail - assert 4 == 5 FAILED test_sample.py::test_answer - assert 4 == 5 ===================================================== 6 failed, 11 passed, 18 rerun in 0.30s ======================================================
从运行结果可以看到,在测试用例运行失败后进行了6 * 3 次重试。因为 Web 自动化测试会因为网络等因素导致测试用例运行失败,而重试机制可以增加测试用例的稳定性。
3、pytest-parallel 扩展
pytest-parallel 扩展可以实现测试用例的并行运行:
创建 test_ parallel.py,在每条测试用例中分别设置 sleep()来模拟运行时间较长的测试用例。
from time import sleep def test_sleep3(): sleep(3) def test_sleep4(): sleep(4) def test_sleep5(): sleep(5)
不使用线程运行测试用例:
(base_practice) D:\00test\base_practice\pyTest>pytest -q test_sleep.py ... [100%] 3 passed in 12.04s (base_practice) D:\00test\base_practice\pyTest>
参数“--tests-per-worker”用来指定线程数,“auto”表示自动分配:
pytest -q test_parallel.py --tests-per-worker auto pytest-parallel: 1 worker (process), 3 tests per worker (threads) ... [100%] 3 passed in 6.02 seconds
pytest-parallel 的更多用法如下所示:
# runs 2 workers with 1 test per worker at a time > pytest --workers 2 # runs 4 workers (assuming a quad-core machine) with 1 test per worker > pytest --workers auto # runs 1 worker with 4 tests at a time > pytest --tests-per-worker 4 # runs 1 worker with up to 50 tests at a time > pytest --tests-per-worker auto # runs 2 workers with up to 50 tests per worker > pytest --workers 2 --tests-per-worker auto
虽然并行运行测试可以非常有效地缩短测试的运行时间,但是 Web 自动化测试本身非常脆弱,在并行运行测试时很可能会产生相互干扰,从而导致测试用例失败,因此建议谨慎使用。
本博客所有文章仅用于学习、研究和交流目的,欢迎非商业性质转载。
本文来自博客园,作者:hello_殷,转载请注明原文链接:https://www.cnblogs.com/yinzuopu/p/15573691.html
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。