Pytest插件pytest-rerunfailures失败重跑

安装

pip install pytest-rerunfailures

doc

https://github.com/pytest-dev/pytest-rerunfailures

https://pypi.org/project/pytest-rerunfailures/#description

  • 当前最新版本11.0(2023-1-12)
  • python>=3.7
  • pytest 6.0以上

使用方法

第一种用法:装饰器 @pytest.mark.flaky

  • 示例代码

    import pytest
    from time import ctime @pytest.mark.flaky(reruns=3, reruns_delay=2)
    def test_a():
    print(ctime())
    import random assert random.choice([True, False]) # 这个代码你可能直接passed了,随机的 if __name__ == '__main__':
    pytest.main(['-sv',__file__])
  • 示例输出

    test_demo.py::test_a Sun Jan 29 09:39:35 2023
    RERUN
    test_demo.py::test_a Sun Jan 29 09:39:37 2023
    PASSED ========================= 1 passed, 1 rerun in 2.13s ==========================
  • 装饰器中的参数

    • reruns=重跑次数,如果都失败那么这个用例就失败了
    • reruns_delay就是重跑的间隔
  • 结果会记录你rerun的次数

  • 如果把assert改为

     assert random.choice([1, 0, 0, 0, 0])
  • 那你的输出很可能就是如下的

    test_demo.py:10: AssertionError
    =========================== short test summary info ===========================
    FAILED test_demo.py::test_a - AssertionError: assert 0
    ========================= 1 failed, 3 rerun in 6.20s ==========================

  • flaky还有一个参数

    • condition:有点类似于skipif中的条件
  • 示例代码

    import sys
    
    import pytest
    from time import ctime @pytest.mark.flaky(reruns=3, reruns_delay=2,condition=sys.platform.startswith('linux'))
    def test_a():
    print(ctime())
    import random
    assert random.choice([1, 0]) if __name__ == '__main__':
    pytest.main(['-sv', __file__])
  • 你测试多次会发现,遇到失败的情况压根就不会重跑的,因为condition不满足

第二种用法:命令行

  • 跟多数插件一样,它也支持命令行的用法

  • 你可以这样用

    $ pytest --reruns 5 --reruns-delay 1
  • 但是condition并没有这个命令行,它变成了--only-rerun(确切的说也不是变,有点不太一样了)

    # 遇到AssertionError错误就重跑
    $ pytest --reruns 5 --only-rerun AssertionError
    # 遇到AssertionError或者ValueError 就重跑
    $ pytest --reruns 5 --only-rerun AssertionError --only-rerun ValueError
  • 示例代码

    def test_a():
    assert int('a') # 会产生一个ValueError
    pytest -sv --reruns 2 --reruns-delay 1 --only-rerun ValueError test_demo.py
    test_demo.py:4: ValueError
    ==================== short test summary info =================================================
    FAILED test_demo.py::test_a - ValueError: invalid literal for int() with base 10: 'a'
    ==================== 1 failed, 2 rerun in 0.06s ===============================================
  • --only-rerun的意思很明确,只有遇到ValueError才重跑

  • 同样的代码,换个参数--rerun-except,除了ValueError才会重跑,遇到ValueError并不重跑

    pytest -sv --reruns 2 --reruns-delay 1 --rerun-except ValueError test_demo.py
    test_demo.py:4: ValueError
    ======================== short test summary info =================================================
    FAILED test_demo.py::test_a - ValueError: invalid literal for int() with base 10: 'a'
    ======================== 1 failed in 0.06s ====================================================

测试AssertionError的时候 貌似跟我预期的不太一样,可能是我眼花了。

  • 如果命令行没有-v显示的是R标记

    test_demo.py RRF  # 重跑了2次后失败了 , 对应底部的1 failed, 2 rerun in 0.06s 
    
    

部分源码

  • 命令行

    # command line options
    def pytest_addoption(parser):
    group = parser.getgroup(
    "rerunfailures", "re-run failing tests to eliminate flaky failures"
    )
    group._addoption(
    "--only-rerun",
    action="append",
    dest="only_rerun",
    type=str,
    default=None,
    help="If passed, only rerun errors matching the regex provided. "
    "Pass this flag multiple times to accumulate a list of regexes "
    "to match",
    )
    group._addoption(
    "--reruns",
    action="store",
    dest="reruns",
    type=int,
    default=0,
    help="number of times to re-run failed tests. defaults to 0.",
    )
    group._addoption(
    "--reruns-delay",
    action="store",
    dest="reruns_delay",
    type=float,
    default=0,
    help="add time (seconds) delay between reruns.",
    )
  • 装饰器参数

    def get_reruns_count(item):
    ...
    if "reruns" in rerun_marker.kwargs:
    ... def get_reruns_delay(item):
    ...
    if "reruns_delay" in rerun_marker.kwargs:
    ... def get_reruns_condition(item):
    ...
    if rerun_marker is not None and "condition" in rerun_marker.kwargs:
    ...

最新文章

  1. swift实现水仙花数
  2. 如何使用跨平台工具创建 NuGet 包(转)
  3. Entity Framework Code First 中使用 Fluent API 笔记。
  4. BZOJ 1113: [Poi2008]海报PLA
  5. probe函数何时调用的
  6. FireDac 的数据库批量语句提交(高效)
  7. RPC 原理的前生今世
  8. 12 为何使用Html5+CSS3
  9. git workflows
  10. 毕向东tcp学习笔记1
  11. confirm显示数组中的内容时,总是带一个逗号分隔的解决方法
  12. Codeforces Round #426 Div. 1
  13. Outsider(HNOI2019)
  14. <%@include>和<jsp:include>有什么不同呢
  15. jQuery 【事件】【dom 操作】
  16. 文件IO-Linux
  17. 时间操作(JavaScript版)—页面显示格式:年月日 上午下午 时分秒 星期
  18. java 和 C 代码运行效率的比较(整理)
  19. SQL LIKE 通配符随笔
  20. 【SQLSERVER】如何设置权限用户

热门文章

  1. C语言嵌套for循环实现冒泡排序
  2. vue 数组更新(push【可用】,$set,slice,filter,map【都属于浅拷贝】)问题
  3. K8S之prometheus-operator监控
  4. 2022春每日一题:Day 25
  5. Go语言核心36讲15---结构体
  6. [排序算法] 快速排序 (C++) (含三种写法)
  7. ArcObjects SDK开发 008 从mxd地图文件说起
  8. day34 JSTL标签
  9. <二>线程间互斥-mutex互斥锁和lock_guard
  10. IDEA引入本地jar包的几种方法