)
Python 测试分析参考手册pytest 与 unittest 的检测模式与断言校准指南test-analysis-extensions / python.md【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills本文基于 dotnet-test 插件中 test-analysis-extensions/extensions/python.md 整理而成。该文件是供断言质量、反模式检测、测试缺口分析、测试异味检测与测试打标等多语言测试分析技能消费的“Python 参考数据”统一描述了 pytest 与 unittest 两大框架下的测试发现、断言 API、跳过注解、等待模式、Mystery Guest 耦合、集成标记、Setup/Teardown 与标签能力。读完本文你将掌握一套可直接套用的 Python 测试静态分析清单以及这些规则在当前仓库的哪些技能与 Agent 流水线中被实际调用。一、这份参考数据在仓库中的角色python.md不是一份独立的分析技能而是test-analysis-extensions技能的扩展数据文件。该技能本身标记为user-invocable: false与disable-model-invocation: true其 SKILL.md 明确指出它只负责向其他技能提供按语言划分的参考文件分析技能assertion-quality、test-anti-patterns、test-gap-analysis、test-smell-detection、test-tagging在分析 Python 代码前必须先读取extensions/python.md获取框架相关的查找表再进行判定。调用链路如下以 test-quality-auditor.agent.md 为入口Agent 通过 marker 扫描检测语言与框架Python 侧关注pyproject.toml、setup.py、setup.cfg、pytest.ini、tox.ini、conftest.py、test_*.py、*_test.py确认extensions/python.md存在后路由到各分析技能每个技能如 assertion-quality/SKILL.md、grade-tests/SKILL.md在自己的工作流中强制要求先读取该扩展文件再分类断言或打分。因此python.md实际上是整个仓库 Python 测试分析体系的“事实来源source of truth”各技能通过它保持语言中立、避免用 .NET 或 JS 的框架术语去描述 pytest 套件。二、能力标签各检测能力的支持强度python.md开头用一张能力标签表声明 Python 生态在各检测维度上的支持程度下游技能据此决定是否启用对应流程能力支持程度测试发现Test discovery强 —— 约定驱动test_*.py、*_test.py、Test*类断言检测Assertion detection强 —— 裸assert、unittest方法、pytest.raisesSleep/延迟检测强 ——time.sleep、asyncio.sleep跳过/忽略检测强 ——pytest.mark.skip、unittest.skipSetup/Teardown 检测强 —— fixtures 与方法标签支持供test-tagging技能auto-edit——pytest.mark.tagpytestunittest 无规范语法其中“标签支持”是三类能力auto-edit/report-only/convention-based中的auto-edit因为 pytest 有规范且可安全写入的 marker 语法test-tagging技能可以直接在测试方法上插入pytest.mark.name并修改文件而 unittest 没有规范语法只能产出报告见下文“标签机制”一节。这与 test-quality-auditor.agent.md 的能力矩阵中test-tagging | ✅ auto-editPython 行完全一致。三、测试文件识别Test File Identification分析的第一步是发现哪些文件是测试文件。python.md给出的约定如下框架测试文件约定测试方法标记pytesttest_*.py或*_test.py以test_开头的函数以Test开头无__init__的类及其中以test_开头的方法unittest任意模块通常为test_*.py继承unittest.TestCase且方法以test开头的类两点实操细节值得注意pytest 的类标记强调“以Test开头且无__init__”因为带构造器的类不会被 pytest 收集为测试类unittest 的方法前缀是test不含下划线与 pytest 的test_不同检测正则需区分对待。在仓库实践中code-testing-extensions/extensions/python.md 还补充了更广的测试形态*.uts、test/*.sh、Djangoruntests.py/manage.py test说明识别时应先探查仓库实际约定而不是默认 pytest。四、断言 API 对照表pytest 与 unittestpython.md的核心是一张逐类别的断言对照表这也是assertion-quality技能 Step 3 分类断言的依据该技能定义了 12 个语言中立断言类别类别pytestunittest相等 Equalityassert x yself.assertEqual(x, y)不相等 Inequalityassert x ! yself.assertNotEqual(x, y)布尔 Booleanassert flag/assert not flagself.assertTrue(flag)/self.assertFalse(flag)Noneassert x is Noneself.assertIsNone(x)/self.assertIsNotNone(x)异常 Exceptionwith pytest.raises(SomeError) as exc_info: ...with self.assertRaises(SomeError): ...类型 Typeassert isinstance(x, T)self.assertIsInstance(x, T)同一性 Identityassert x is yself.assertIs(x, y)成员 Membershipassert item in collectionself.assertIn(item, collection)近似 Approximateassert x pytest.approx(y, rel0.01)self.assertAlmostEqual(x, y, places2)字符串 Stringassert sub in s/assert s.startswith(...)self.assertIn(sub, s)跳过 Skippytest.skip(reason)self.skipTest(reason)失败 Failpytest.fail(reason)self.fail(reason)关键校准规则不要误报裸assert文档特别强调一条红线裸assert是 pytest 的规范断言形式会经 pytest 的断言重写assertion rewriting产生丰富的失败 diff。因此在断言质量或反模式分析中绝不能把裸assert当作“缺少框架 API”的异味。这条规则在 assertion-quality/SKILL.md 与 test-anti-patterns/SKILL.md 中都有对应条款例如“pytest bareassertis the canonical assertion form, not a missing assertion library. Do NOT flag.”可见下游技能对这份参考数据的遵守是显式约束。第三方断言库除两大框架外文档还列出了常见的第三方断言库assertpy、hamcrestassert_that、expects。分析器应对这些 API 同样给予识别。五、Sleep/延迟模式Sleep/Delay Patterns在检测测试脆弱性flakiness时需要识别测试中的等待与延迟。python.md给出的模式清单模式示例同步 sleeptime.sleep(2)异步 sleepawait asyncio.sleep(1)循环等待while not condition: time.sleep(0.1)Trio/anyioawait trio.sleep(...)、await anyio.sleep(...)在 test-anti-patterns/SKILL.md 中time.sleep被列为High 严重级“不稳定性指标”wall-clock sleeps 用于同步但同时给出语境化豁免若它出现在真正测试时序的集成测试中则不构成反模式。六、跳过/忽略注解Skip/Ignore Annotations两种框架的跳过机制对应关系如下框架注解pytestpytest.mark.skip(reason...)、pytest.mark.skipif(cond, reason...)、pytest.mark.xfail(reason...)以及内联pytest.skip(...)unittestunittest.skip(reason)、unittest.skipIf(cond, reason)、unittest.skipUnless(cond, reason)、unittest.expectedFailure检测这些注解的价值在于跳过测试不等于断言为空分析器应区分“主动跳过”与“无断言测试”。test-tagging技能还会把带有 flaky 注释的 skip 注解作为flaky特质meta-tag的启发式信号。七、异常处理惯用写法与异味判定python.md给出了异常断言的两种惯用写法# pytest推荐 with pytest.raises(ValueError, matchrmust be positive): parse_amount(-5) # unittest with self.assertRaises(ValueError): parse_amount(-5) # 需要检查异常对象时 with pytest.raises(ValueError) as exc_info: parse_amount(-5) assert must be positive in str(exc_info.value)三个要点pytest 的match参数可以对异常消息做正则匹配比 unittest 更精确通过as exc_info捕获异常上下文后可对exc_info.value做二次断言异味判定边界仅当 try/except 之后没有断言、或异常被静默吞掉时才把裸try/except标记为“Exception Handling”异味。这与 test-anti-patterns/SKILL.md 中的“Swallowed exceptionsexcept:pass”以及“Assert in catch block only”两条 Critical 级反模式完全对应——正确的替代写法就是pytest.raises/assertRaises。八、Mystery Guest常见 Python 外部耦合模式“Mystery Guest”指测试与外部环境文件、数据库、网络、环境变量隐式耦合。python.md给出了指示器对照表指示器需要警惕的内容文件系统open()、pathlib.Path(...).read_text()、os.path.exists、硬编码绝对路径数据库直接psycopg2/mysql.connector/sqlite3.connect到文件路径、SQLAlchemyengine 指向真实 DB URL网络requests.get/post、httpx.get/post、urllib.request.urlopen、裸socket环境os.getenv(X)尤其无默认值时、os.environ[X]可接受io.StringIO/io.BytesIO、pytest fixturestmp_path/tmp_path_factory、monkeypatch.setenv、responses/httpx.MockTransport、pytest-mock、sqlite:memory:这张表是双刃剑既列出了需要标记的外部依赖信号也明确列出了可接受的替代品——分析器不应把tmp_path、monkeypatch、MockTransport误判为耦合。对应到 test-tagging/SKILL.md使用真实数据库、HTTP 客户端、文件系统的测试会被归类为integration特质。九、集成测试标记Integration Test Markers识别集成测试的四类信号目录名tests/integration/、tests/e2e/、tests/acceptance/命名模块/类/函数名包含Integration、E2E、EndToEnd、AcceptanceMarkerpytest.mark.integration/pytest.mark.e2e项目自定义 marker需在pytest.ini/pyproject.toml注册Conftest fixtures启动容器/数据库的 fixturetestcontainers、docker-composefixtures。在test-tagging的特质体系中跨越进程/网络/持久化边界的测试标记为integration走完整应用栈的标记为end-to-end两者有明确区分。十、Setup/Teardown 生命周期框架SetupTeardownpytestpytest.fixture任意 scope、autouseTruefixturesfixture 内 yield 式 teardown 或request.addfinalizerpytest类级setup_method/setup_classteardown_method/teardown_classunittestsetUp/setUpClass/setUpModuletearDown/tearDownClass/tearDownModulepytest 的 fixture 体系强调“按需付费pay-as-you-go”一个 fixture 只有在测试请求它时才执行。因此文档在“语言特定校准说明”中明确只被一个测试使用的 fixture 不算 General Fixture 异味。十一、标签/特质机制供 test-tagging 技能使用框架标签机制示例pytestpytest.mark.name项目注册pytest.mark.positive、pytest.mark.boundaryunittest无内建机制 —— 使用类组织、属性或unittest.skipIf开关仅报告建议 pytest markers 或项目约定pytest 的 marker 必须先注册否则会产生PytestUnknownMarkWarning。python.md给出了pyproject.toml的标准注册写法[tool.pytest.ini_options] markers [ positive: verifies expected behavior under normal conditions, negative: verifies handling of invalid input or error paths, boundary: tests limits, thresholds, empty/null inputs, ]这与 test-tagging/SKILL.md 的实践衔接该技能在 pytestauto-edit场景下为测试方法添加如下的标签并在 Step 6 要求用仓库配置的 pytest 收集命令如pytest --collect-only验证编辑结果pytest.mark.negative pytest.mark.boundary def test_parse_none_input_raises_value_error(): ...由于 pytest 是 auto-edit 能力test-tagging会直接修改文件而 unittest 只能产出 Markdown 报告并建议项目约定——这正是能力标签表中“no canonical syntax in unittest”的落地体现。十二、语言特定校准说明Calibration Notes这是python.md中最需要“人工经验”的部分直接决定分析器的误报率。逐条整理如下裸assert是 pytest 惯用法—— 不要把它标记为“无断言”快照测试syrupy、pytest-snapshot用隐式快照比较替代了assert调用 —— 应视为合法断言属性化测试hypothesis被given(...)装饰的函数即使看起来没有函数体也是真实测试 —— 断言内嵌在生成的输入循环中异步测试pytest-asyncio、anyio测试内部对协程调用缺少await会产生RuntimeWarning且测试实际上“无断言化” —— 应标记为 Critical 反模式。这条与 test-anti-patterns/SKILL.md 中的“Missing await on async assertions”一致也与 assertion-quality/SKILL.md 中“Async tests with unawaited assertions … treat as assertion-free”一致Doctests通过--doctest-modules调用块在用户将其纳入范围内时也应视为测试方法参数化测试pytest.mark.parametrize不是底层函数的重复 —— 应视为合并后的形态这也是 test-anti-patterns/SKILL.md 中“pytest/JUnit/xUnit parameterization 不视为重复”的依据只被一个测试使用的 fixture 不算 General Fixture 异味pytest fixtures 按需执行。十三、在实际流水线中的综合应用把上述参考数据放入 test-quality-auditor.agent.md 的“综合审计流水线”中看Python 项目的审计路径是test-anti-patterns—— 用本文的 Sleep 模式、异常惯用法、Mystery Guest 指示器做严重级排序扫描assertion-quality—— 用本文的断言 API 对照表做 12 类别分类与多样性度量注意例外异常测试天然低断言数、布尔断言检查具体属性不算平凡断言test-gap-analysis—— 伪变异推理定位“改了生产代码但测试不会失败”的行为盲区发现或断言语义不清时才调用test-analysis-extensionstest-tagging—— 用本文的标签机制为 pytest 套件添加pytest.mark.trait并生成分布报告覆盖率/CRAP 等步骤对 Python跳过并显式推荐coverage.py/pytest-cov、mutmut/cosmic-ray等原生工具。输出报告时grade-tests/SKILL.md 要求先读extensions/python.md再对断言打分而 code-testing-extensions/extensions/python.md 则负责“写测试”一侧的运行命令prefix pytest、python -m unittest discover、py_compile语法检查、环境前缀检测等。两者与python.md形成“分析—评分—生成”的完整闭环。结语plugins/dotnet-test/skills/test-analysis-extensions/extensions/python.md以极紧凑的表格形式沉淀了 pytest 与 unittest 在测试发现、断言、跳过、等待、耦合、生命周期与标签上的全部关键事实并内嵌了多条“不要误报”的校准规则。对开发者而言它是一份可直接照做的 Python 测试审查清单对仓库内的分析技能而言它是保证多语言分析语言中立、口径统一的权威参考数据。结合 test-analysis-extensions/SKILL.md 的说明——扩展文件是“数据”而非“教条”它们告诉技能如何检测而不是如何思考——使用时应始终结合被测代码的实际语义做出最终判断。【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考