python - 如果未运行最小数量的测试,如何使 pytest 返回失败?

标签 python pytest

由于测试可以根据现有环境自动启用或禁用,因此始终存在 CI 中某些内容发生更改的风险,从而使 pytest 在不应该进行的测试时跳过测试。

如果我可以在环境变量中定义最小数量的测试,或者甚至是固定数量的预期测试,我就可以防止 CI 通过仅仅因为测试被跳过而发生的事故。

大多数时候pytest是由tox调用的,tox也用在开发环境中。这意味着预期的测试数量必须在 CI 配置中定义(如 .travis.yml),因为这是唯一特定于 CI 的地方。

最佳答案

您可以添加自定义钩子(Hook)实现并计算通过的测试数量。测试运行完成后,检查计数器,如果通过的测试量太低,则使用自定义退出代码退出。示例:将代码添加到您的 conftest.py 中:

import pytest


def pytest_addoption(parser):
    parser.addoption('--minpass', type=int, default=0, help='minimum amount of tests to pass')


def pytest_sessionstart(session):
    session.count_passed = 0


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    outcome = yield
    result = outcome.get_result()

    if result.when == 'call' and result.passed:
        item.session.count_passed += 1


def pytest_sessionfinish(session, exitstatus):
    min_passed = session.config.getoption('minpass')
    if session.count_passed < min_passed:
        session.exitstatus = 127
        reporter = session.config.pluginmanager.get_plugin('terminalreporter')
        reporter.section('Session errors', sep='-', red=True, bold=True)
        reporter.line(f'Not enough successful tests - expected at least {min_passed} to pass, passed {session.count_passed}')

这添加了一个新的命令行选项--minpass,它期望运行成功所需的最少测试量;默认值为零,因此如果未提供,它不会影响任何现有套件。 session.exitstatus = 127 设置自定义退出代码;将其更改为您需要的任何代码。 pytest_sessionfinish Hook 使用终端报告器在自定义部分中显示错误;将输出更改为您需要的任何格式。

至少有一项测试能够通过 yield 的示例执行:

$ pytest --minpass 1
======================================= test session starts ========================================
platform linux -- Python 3.6.9, pytest-5.3.1, py-1.8.0, pluggy-0.13.0
rootdir: /home/hoefling/projects/private/stackoverflow/so-59116898
plugins: mock-1.11.0, xdist-1.29.0, asyncio-0.10.0, forked-1.0.2, cov-2.8.1, testinfra-3.2.0
collected 1 item                                                                                   

test_spam.py s                                                                               [100%]
------------------------------------------ Session errors ------------------------------------------
Not enough successful tests - expected at least 1 to pass, passed 0


======================================== 1 skipped in 0.01s ========================================
$ echo $?
127

如果您想支持环境变量,请调整 pytest_sessionfinish 钩子(Hook)实现,例如

def pytest_sessionfinish(session, exitstatus):
    min_passed = session.config.getoption('minpass') or int(os.environ.get('PYTEST_MINPASS', '0'))
    ...

并设置PYTEST_MINPASS环境变量以打开检查。

关于python - 如果未运行最小数量的测试,如何使 pytest 返回失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59116898/

相关文章:

python - 如何避免在我的代码片段中使用\xc2 字符或 ?

python - 从 Python 2.7 中的父目录导入模块

pytest - py.test 给出 Coverage.py 警告 : Module sample. py 从未导入

python - pytest-xdist: LookupError: setuptools-scm 无法检测版本

python - pytest-cov无法使用新的Coverage版本5.X生成报告,但适用于Coverage版本4.4.2

python - 使用Python组合包含整数的列中的列表行

python - 为什么 pandas .isin 比 "in"快得多?

python - 在 Python 中是否对多个变量赋值使用括号?

python - 使用 Python 在 Apache Beam 管道中进行异常处理

python - 为目录中的每个文件运行 pytest