由于可以基于现有环境自动启用或禁用测试,因此始终存在CI发生更改的风险,这会使pytest在不应该进行的情况下跳过测试。
如果我可以在环境变量中定义最少数量的测试,或者甚至是固定数量的预期测试,则可以防止CI被跳过而导致CI通过的事故。
大多数时候pytest被tox调用,tox也用在开发环境中。这意味着必须在CI配置中定义预期的测试数量(如.travis.yml
),因为这是唯一针对CI的地方。
答案 0 :(得分:2)
您可以添加自定义钩子impl并计算通过的测试数量。测试运行完成后,如果通过的测试量太少,请检查计数器并使用自定义退出代码退出。示例:将代码添加到您的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
挂钩使用终端报告程序在自定义部分显示错误;将输出更改为所需的任何格式。
至少有一个通过合格的测试的样本执行:
$ 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
如果要支持环境变量,请使用{p1>
pytest_sessionfinish
并设置def pytest_sessionfinish(session, exitstatus):
min_passed = session.config.getoption('minpass') or int(os.environ.get('PYTEST_MINPASS', '0'))
...
环境变量以打开检查。