ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

08-pytest常用插件

2021-07-08 13:34:39  阅读:208  来源: 互联网

标签:插件 repeat assume 08 py assert pytest test


常用插件

  • pip install pytest-rerunfailures 失败重跑
  • pip install pytest-assume 多重校验
  • pip install pytest-ordering 控制用例的执行顺序
  • pip install pytest-repeat 重复执行用例

pytest-rerunfailures

  • 场景
    • 测试失败后要重新运行n次,要在重新运行之间添加延迟时间、间隔n秒再运行。
  • 安装
  • 运行要求
    • Python 3.6~3.9, or PyPy3
    • pytest 5.0+
  • 使用方式
    • 命令行参数:--reruns n(重新运行次数),--reruns-delay m(等待运行秒数)
    • 装饰器参数:reruns=n(重新运行次数),reruns_delay=m(等待运行秒数)

重新运行所有失败的用例

要重新运行所有测试失败,使用 --reruns 命令行选项,并指定要运行测试的最大次数:
pytest -vs --reruns 3 test_rerun.py

from time import sleep


def test_rerun1():
    sleep(0.5)
    assert 1 == 2

def test_rerun2():
    sleep(0.5)
    assert 2 == 2

def test_rerun2():
    sleep(0.5)
    assert 'h' == 'world'

执行结果:

test_rerun.py::test_rerun1 RERUN
test_rerun.py::test_rerun1 RERUN
test_rerun.py::test_rerun1 RERUN
test_rerun.py::test_rerun1 FAILED
test_rerun.py::test_rerun2 RERUN
test_rerun.py::test_rerun2 RERUN
test_rerun.py::test_rerun2 RERUN
test_rerun.py::test_rerun2 FAILED

添加重新运行的延时

要在两次重试之间增加延迟时间,使用 --reruns-delay 命令行选项,指定下次测试重新开始之前等待的秒数
pytest test_rerun.py --reruns 3 --reruns-delay 1
说明:明显看到重跑的两个测试用例之间有一段时间间隔

重新运行指定的测试用例

@pytest.mark.flaky(reruns=2,reruns_delay=2)
运行结果:

test_rerun.py::test_rerun1 FAILED
test_rerun.py::test_rerun2 PASSED
test_rerun.py::test_rerun3 RERUN
test_rerun.py::test_rerun3 RERUN
test_rerun.py::test_rerun3 FAILED

兼容性问题

  • 不可以和fixture装饰器一起使用: @pytest.fixture()
  • 该插件与pytest-xdist的 --looponfail 标志不兼容
  • 该插件与核心--pdb标志不兼容
    最后总结,这个插件虽然还用,但是坑还是不少,建议主要使用失败重试次数和重试间隔的功能即可。

pytest-assume

  • 场景
    • 一个方法中些多条断言,中间有一条失败,后面的代码就不执行了,我们希望有失败也能执行完毕。
  • 安装
  • 使用方式
    • pytest.assume(1==4)
    • pytest.assume(2==4)

assert 多重断言

def test_assume():
    assert 1 == 2
    assert False == True
    assert 100 == 200

运行结果:

FAILED
test_assume.py:8 (test_assume)
1 != 2

Expected :2
Actual   :1
<Click to see difference>

def test_assume():
>       assert 1 == 2
E       assert 1 == 2

test_assume.py:10: AssertionError

结论
可以看到,第一行断言失败之后,后面的断言也不会执行,包括正常的代码

pytest.assume多重断言

def test_assume():
    # assert 1 == 2
    # assert False == True
    # assert 100 == 200
    pytest.assume(1 == 1)
    pytest.assume(False == True)
    pytest.assume(100 == 200)
    pytest.assume(4 != 1)

运行结果:

FAILED
test_assume.py:10 (test_assume)
tp = <class 'pytest_assume.plugin.FailedAssumption'>, value = None, tb = None

    def reraise(tp, value, tb=None):
        try:
            if value is None:
                value = tp()
            if value.__traceback__ is not tb:
>               raise value.with_traceback(tb)
E               pytest_assume.plugin.FailedAssumption: 
E               2 Failed Assumptions:
E               
E               test_assume.py:16: AssumptionFailure
E               >>	pytest.assume(False == True)
E               AssertionError: assert False
E               
E               test_assume.py:17: AssumptionFailure
E               >>	pytest.assume(100 == 200)
E               AssertionError: assert False

结论

  • 可以看到,第二行即使断言失败,后面的断言还是会继续执行
  • 这有助于我们分析和查看到底一共有哪些断言是失败的
  • 而且最后的代码也还会正常执行,比直接用assert更高效

pytest-ordering

  • 场景
    • 对于集成测试,通常会有上下文依赖关系的测试用例。有的需求,先执行某些需求。测试用例尽量不要有依赖。
  • 安装
  • 使用方式
    • @pytest.mark.run(order=2)

pytest中测试用例执行顺序是从上往下执行

import pytest

def test_1():
    assert True

def test_2():
    assert 1 == 1

def test_2():
    assert 2 == 2

运行结果:

pytest-ordering控制执行顺序

import pytest


@pytest.mark.run(order=3)
def test_1():
    assert True

@pytest.mark.run(order=1)
def test_2():
    assert 1 == 1

@pytest.mark.run(order=2)
def test_3():
    assert 2 == 2

执行结果:

总结:
1、除了用@pytest.mark.run(order=3)这种方式指定测试用例顺序
2、还可以使用pytest.mark.third 方法指定

pytest-repeat

  • 场景
    • 平常在做功能测试的时候,经常会遇到某个模块不稳定,偶然会出现一些bug,对于这种问题我们会针对此用例反复执行多次,最终复现出问题来
    • 自动化运行用例时候,也会出现偶然的bug,可以针对单个用例,或者针对某个模块的用例重复执行多次
  • 安装
  • 运行要求
    • Python 2.7、3.4+或PyPy
    • py.test 2.8或更高版本* 使用方式
  • 使用方式
    • count=2
    • count 2
    • pytest --html=report.html --self-contained-html -s --reruns=5 --count=2 test_request.py

重复测试直到失败(重要!!!)

- 如果需要验证偶现问题,可以一次又一次地运行相同的测试直到失败,这个插件将很有用
- 可以将pytest的 -x 选项与pytest-repeat结合使用,以强制测试运行程序在第一次失败时停止

pytest --count=1000 -x test_file.py

代码如下:

def test_example():
    import random
    flag = random.choice([True, False])
    print(flag)
    sleep(1)
    assert flag

执行命令:
pytest --count 5 -x test_repeat.py

执行结果:

test_repeat.py::test_example[1-5] True
PASSED
test_repeat.py::test_example[2-5] True
PASSED
test_repeat.py::test_example[3-5] False
FAILED

================================================================= FAILURES =================================================================
____________________________________________________________ test_example[3-5] _____________________________________________________________

    def test_example():
        import random
        flag = random.choice([True, False])
        print(flag)
        sleep(1)
>       assert flag
E       assert False

test_repeat.py:17: AssertionError
========================================================= short test summary info ==========================================================
FAILED test_repeat.py::test_example[3-5] - assert False
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================================= 1 failed, 2 passed in 3.10s ========================================================

总结:执行了三次,第三次失败,就不再执行了。

@pytest.mark.repeat(count)

如果要在代码中将某些测试用例标记为执行重复多次,可以使用 @pytest.mark.repeat(count)

@pytest.mark.repeat(5)
def test_repeat():
    sleep(1)
    print("测试用例执行")

执行命令:
pytest test_repeat.py::test_repeat

执行结果:

test_repeat.py::test_repeat[1-5] 测试用例执行
PASSED
test_repeat.py::test_repeat[2-5] 测试用例执行
PASSED
test_repeat.py::test_repeat[3-5] 测试用例执行
PASSED
test_repeat.py::test_repeat[4-5] 测试用例执行
PASSED
test_repeat.py::test_repeat[5-5] 测试用例执行
PASSED

============================================================ 5 passed in 5.05s =============================================================

--repeat-scope

命令行参数

作用:可以覆盖默认的测试用例执行顺序,类似fixture的scope参数

- function:默认,范围针对每个用例重复执行,再执行下一个用例
- class:以class为用例集合单位,重复执行class里面的用例,再执行下一个
- module:以模块为单位,重复执行模块里面的用例,再执行下一个
- session:重复整个测试会话,即所有测试用例的执行一次,然后再执行第二次

class示例

class TestRepeat:

    def test_repeat1(self):
        print("test1++++++++test1")

    def test_repeat2(self):
        print("test2+++++++++test2")


class TestRepeat2:

    def test_repeat3(self):
        print("test3++++++++test3")

    def test_repeat4(self):
        print("test4+++++++++test4")

执行命令: pytest --count=2 --repeat-scope=class test_repeat.py
执行结果:

test_repeat.py::TestRepeat::test_repeat1[1-2] test1++++++++test1
PASSED
test_repeat.py::TestRepeat::test_repeat2[1-2] test2+++++++++test2
PASSED
test_repeat.py::TestRepeat::test_repeat1[2-2] test1++++++++test1
PASSED
test_repeat.py::TestRepeat::test_repeat2[2-2] test2+++++++++test2
PASSED
test_repeat.py::TestRepeat2::test_repeat3[1-2] test3++++++++test3
PASSED
test_repeat.py::TestRepeat2::test_repeat4[1-2] test4+++++++++test4
PASSED
test_repeat.py::TestRepeat2::test_repeat3[2-2] test3++++++++test3
PASSED
test_repeat.py::TestRepeat2::test_repeat4[2-2] test4+++++++++test4
PASSED

============================================================ 8 passed in 0.04s =============================================================

兼容性问题

  • pytest-repeat不能与unittest.TestCase测试类一起使用。
  • 无论--count设置多少,这些测试始终仅运行一次,并显示警告

其他

后续单独讲解pytest-xdis(重要!!!)插件的使用。

标签:插件,repeat,assume,08,py,assert,pytest,test
来源: https://www.cnblogs.com/murcy/p/14984439.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有