如何检测未标记的pytest测试?构建CI脚本实现告警或报错
检测未标记的Pytest测试用例并集成到CI
方法1:用pytest收集+脚本分析
通过pytest的--collect-only功能导出所有测试的元数据,再用脚本筛选出没有自定义分组标记的测试,最终在CI中抛出错误终止流程。
步骤1:编写检测脚本(check_unmarked_tests.py)
import subprocess import sys import json # 调用pytest收集所有测试并输出为JSON格式 collect_result = subprocess.run( ["pytest", "--collect-only", "-q", "--tb=no", "--json-report"], capture_output=True, text=True ) if collect_result.returncode != 0: print("收集测试用例失败:", collect_result.stderr) sys.exit(1) test_data = json.loads(collect_result.stdout) unmarked_tests = [] # 定义内置标记(这些不算作你的分组标记,需要排除) builtin_marks = {"parametrize", "skip", "xfail", "skipif", "usefixtures"} # 遍历所有测试,检查是否有自定义分组标记 for test_item in test_data["tests"]: test_marks = set(test_item.get("marks", [])) custom_group_marks = test_marks - builtin_marks if not custom_group_marks: unmarked_tests.append(test_item["nodeid"]) # 根据检查结果输出信息并设置退出码 if unmarked_tests: print("错误:发现未标记的测试用例(这些测试不会在CI中执行):") for test in unmarked_tests: print(f" - {test}") sys.exit(1) else: print("所有测试用例均已配置有效分组标记。") sys.exit(0)
步骤2:集成到GitHub Actions
在你的CI workflow文件(比如.github/workflows/check-unmarked-tests.yml)中添加如下Job:
name: 检查未标记测试用例 on: [pull_request, push] jobs: check-unmarked: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: 配置Python环境 uses: actions/setup-python@v5 with: python-version: "3.x" - name: 安装依赖 run: | python -m pip install --upgrade pip pip install pytest pytest-json-report - name: 执行未标记测试检查 run: python check_unmarked_tests.py
方法2:用pytest钩子自定义检查
编写一个极简的pytest插件,在测试收集阶段直接检查标记,无需额外脚本。
编写pytest插件(pytest_enforce_marks.py)
def pytest_collection_modifyitems(config, items): builtin_marks = {"parametrize", "skip", "xfail", "skipif", "usefixtures"} unmarked_tests = [] for item in items: # 获取当前测试的所有标记名称 test_mark_names = set(mark.name for mark in item.iter_markers()) custom_group_marks = test_mark_names - builtin_marks if not custom_group_marks: unmarked_tests.append(item.nodeid) if unmarked_tests: config.stderr.write("错误:检测到未标记的测试用例:\n") for test in unmarked_tests: config.stderr.write(f" {test}\n") raise SystemExit(1)
在CI中使用插件
直接通过pytest命令加载插件并执行检查:
pytest -p pytest_enforce_marks.py --collect-only
额外提示
- 如果存在无需分组的特殊测试(比如基础工具类测试),可以添加一个
allow_unmarked标记,在检查逻辑中排除带有该标记的测试。 - 建议将检查放在PR触发的CI流程中,提前拦截未标记的测试,避免合并后出现测试遗漏。
内容的提问来源于stack exchange,提问作者Stalin Thomas
相关产品推荐
相关产品推荐

