Boost.Test:如何编写不会自动运行的测试用例
嘿,这个场景我太熟悉了——项目里总会有一些跑起来费时间的测试,不想让CI每次都触发执行,但本地又能按需运行。你的自定义命令行参数思路是可行的,但其实还有更明确、更易维护的实现方式,给你分几种常用方案说说:
1. 用测试框架自带的标记/分组功能
几乎所有主流测试框架都原生支持给测试打标签或者分组,这是最推荐的方式,语义清晰且无需额外造轮子:
- Python pytest:给慢测试加
@pytest.mark.slow装饰器,CI里执行pytest -m "not slow"就会跳过所有标记为slow的测试;本地需要跑的时候,直接用pytest -m slow单独执行这类测试。 - Java JUnit 5:用
@Tag("slow")注解标记测试,然后在CI的Maven/Gradle配置里过滤掉这个标签(比如Maven的surefire插件配置<excludedTags>slow</excludedTags>);本地跑的时候指定包含该标签即可。 - JavaScript Jest:可以把慢测试放到单独的
describe('slow tests', () => { ... })块里,CI里通过jest --testPathIgnorePatterns=slow跳过对应的文件,本地跑的时候直接指定文件路径执行。
这种方式的好处是和测试框架深度绑定,其他团队成员一看标记就懂,不需要额外维护自定义逻辑。
2. 基于CI环境变量自动跳过
大多数CI系统(比如GitHub Actions、GitLab CI、Jenkins)都会自动设置环境变量(比如CI=true、CONTINUOUS_INTEGRATION=true),你可以在测试代码里直接判断这个变量,当处于CI环境时自动跳过慢测试:
举个pytest的例子:
import os import pytest @pytest.mark.skipif(os.getenv("CI") == "true", reason="跳过CI环境下的耗时测试") def test_data_analysis_large_dataset(): # 这里是耗时很长的测试逻辑 assert process_large_data() == expected_result
这种方式完全不需要修改CI的命令,测试代码自己处理逻辑,非常直观,新人接手也能快速理解。
3. 物理拆分慢测试到单独目录/文件
如果你的慢测试数量比较多,干脆把它们统一放到单独的目录(比如tests/slow/)或者文件(比如test_slow_scenario.py)里,然后在CI配置里只执行常规测试目录,本地需要跑的时候再单独指定这个目录:
比如CI里执行:
pytest tests/unit/ tests/integration/
本地跑慢测试时执行:
pytest tests/slow/
或者想跑全部测试就直接pytest tests/。
这种方式的优势是物理隔离,边界清晰,不会和常规测试混在一起,适合慢测试占比比较高的项目。
关于你考虑的自定义命令行参数方案
这个方案其实是可行的,比如在pytest里自定义--run-slow参数,通过conftest.py来控制测试的执行:
# conftest.py def pytest_addoption(parser): parser.addoption("--run-slow", action="store_true", help="执行耗时测试用例") def pytest_collection_modifyitems(config, items): if not config.getoption("--run-slow"): skip_slow = pytest.mark.skip(reason="需要添加--run-slow参数才能执行") for item in items: if "slow" in item.keywords: item.add_marker(skip_slow)
但对比前面几种方案,这种需要自己实现参数解析和过滤逻辑,相对繁琐一些,除非你的测试框架没有原生标记功能,否则不太推荐。
总结一下,优先选测试框架原生标记,其次是环境变量自动跳过,这两种方式都比自定义命令行参数更明确、更易维护。
内容的提问来源于stack exchange,提问作者pic11

