ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

.NET 测试反模式审计实战:用 test-anti-patterns 技能揪出“假自信“测试

.NET 测试反模式审计实战:用 test-anti-patterns 技能揪出“假自信“测试 .NET 测试反模式审计实战用 test-anti-patterns 技能揪出假自信测试【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills导读本指南基于skills17/skills仓库中 test-anti-patterns 技能定义系统讲解如何对任意支持语言含 .NET/C#、Python、TypeScript/JavaScript、Java、Go、Ruby、Rust、Swift、Kotlin、PowerShell、C的测试代码进行快速、务实的反模式诊断并产出一份按严重级别Critical / High / Medium / Low排序的审计报告。读完本文你将掌握一套完整可落地的测试审计工作流——从语言识别、测试代码采集、反模式扫描、严重度校准到最终报告的深度标准与结构规范并能结合仓库中的真实评估用例eval.yaml 及 8 组 fixtures识别出测试全绿但什么也没验证的假自信陷阱。技能定位审计而非修改test-anti-patterns的核心职责是只读诊断审计一个测试文件或整套测试产出按严重级别排序的诊断报告覆盖测试可靠性reliability、可维护性maintainability与诊断价值diagnostic value三方面问题。它面向的场景非常明确适用场景When to Use用户要求评审测试质量或查找测试异味test smells用户想弄清测试为何 flaky 或不可靠用户问我的测试好吗或我的测试哪里有问题用户请求一次测试审计或测试代码评审用户在决定改进方向之前希望先拿到诊断结论明确不适用的场景When Not to Use用户诉求应使用的技能从零编写新测试code-testing-agent直接实施修复而非诊断相应的 write/edit 技能修复 MSTestAssert.AreEqual实参顺序颠倒writing-mstest-tests将 MSTestDynamicData从IEnumerableobject[]改为ValueTuplewriting-mstest-tests运行或执行测试run-tests.NET在测试框架或版本间迁移迁移类技能收集原始 .NET 覆盖率、项目级覆盖率/CRAP 指标、命名目标 CRAPrun-tests/coverage-analysis/crap-score判断测试能否捕获某 bug、行为/伪变异缺口test-gap-analysis测试构成分类、happy-vs-error 分类、trait 分布test-tagging需要学术分类法的深度形式化测试异味审计test-smell-detection其中与 test-smell-detection 的边界值得特别说明后者使用 testsmells.org 的 19 种学术分类法进行正式、可引用的异味审计而test-anti-patterns定位为快速务实的日常评审工具两者不要混用。输入与发现策略技能接受三个可选输入输入必填说明测试范围Test scope否要分析的测试文件、类、目录或项目省略时从当前工作区自动发现生产代码Production code否被测代码用于提供测试应当验证什么的上下文具体关注点Specific concern否聚焦某一方面如 flakiness 或 naming以收窄评审范围值得注意的是技能的 contextBase directory只是文档存储位置不是用户的工作区绝不能以它为基准解析目标文件。省略路径时应依据仓库 manifest 和常规测试标记来发现测试文件若某个读取器声称路径不存在而工作区搜索能找到则应规范化精确路径后重试。六步审计工作流Step 1识别语言并加载扩展优先从当前工作区解析指定的测试路径不要急着向用户索要输入。识别语言与框架后尝试一次匹配的test-analysis-extensions扩展若该辅助技能不可用立即继续使用本技能内置的框架规则绝不让辅助工具阻塞审计。语言扩展参考文件位于 test-analysis-extensions/extensions 目录例如 dotnet.md 覆盖 MSTest、xUnit、NUnit、TUnit 四种框架。以 .NET 为例扩展文件提供了测试方法标记MSTest[TestClass]/[TestMethod]/[DataTestMethod]、xUnit[Fact]/[Theory]、NUnit[TestFixture]/[Test]/[TestCase]、TUnit[Test]框架原生断言 API 对照表如 MSTestAssert.ThrowsExactlyT()、xUnitAssert.ThrowsT()、NUnitAssert.That(() ..., Throws.TypeOfT())、TUnit 的异步await Assert.That(...).ThrowsT()Sleep/延时模式Thread.Sleep、await Task.Delay、SpinWait.SpinUntilSkip/Ignore 注解MSTest[Ignore]、xUnit[Fact(Skip ...)]、NUnit[Ignore(...)]、TUnit[Skip(...)]Mystery Guest 指标硬编码路径的文件访问、未用内存提供程序的DbContext、未覆写HttpMessageHandler的HttpClient、环境变量依赖等Step 2采集测试代码读取解析范围内每一个测试文件。使用扩展发现标记若已加载否则使用本技能内置标记如[TestClass]/[Fact]/[Test]、test_*.py、*.test.*、*_test.go、*_spec.rb、#[test]、*.Tests.ps1、TEST(...)、TEST_CASE(...)。如果提供生产代码也务必一并读取——这对发现测试耦合于实现细节而非行为至关重要。仓库评估用例 eval.yaml 中的多个场景如 mixed-severity、self-referential都显式提供了生产代码文件作为审计上下文。Step 3扫描反模式将每个测试文件对照下方反模式目录逐项检查按严重级别分组报告发现。在起草报告前先建立一份私密的完整性台账completeness ledger每个测试方法、每个类级 fixture/资源各占一行记录其 oracle断言基准或缺失、异常处理、状态/时间依赖与处置结论。台账中每一行都必须要么关联到某个发现、要么被明确判定为健康才能发布报告。特别地actual ! oldValue是弱变异 oracle它接受任何错误的新值。应当要求精确的期望值。必须纳入未使用或未释放的类级资源——只扫描方法体会漏掉像静态HttpClient这样的字段。提供生产代码时可顺带标注与发现相邻的明显未测契约但不要做穷尽式分支或变异分析这类更宽泛的问题应交由test-gap-analysis。Critical——制造假自信的测试Tests that give false confidence反模式特征无断言No assertions测试方法执行了代码但从未断言任何内容。通过但无断言的测试什么都证明不了。.NET 中表现为缺少Assert.*pytest 中为无assert且无pytest.raises的函数Jest 中无expect(...)JUnit 中无assert*/assertThatGo 中从不调用t.Error*、t.Fatal*或 testifyRSpec 中为无expect的块Pester 中无Should。Mock 调用验证verify(mock)、expect(mock).toHaveBeenCalled、Should -Invoke是真实的断言。异步断言缺少 awaitJS/TS、.NET、Python、Kotlin、Swiftexpect(promise).resolves.toBe(x)没有await/return、pytest-asyncio 测试未 await 协程、xUnit 的async Task测试调用Assert.ThrowsAsync却不await、Kotest 挂起测试没有runTest、Swift Testing 异步测试没有await。这类测试即使在底层断言本会失败时也会静默通过。Coverage touching覆盖率触摸测试类按字母序或声明序系统性地调用类型上的每个公共成员却不断言有意义的产出。每个测试通常形如var result sut.MethodName(...)或result sut.method_name(...)、sut.methodName()、sut.MethodName(t)没有断言或只有一个琐碎的 null/None/nil 检查。意图是推高覆盖率指标而非验证行为。区别于单个无断言测试该模式是系统性地覆盖整个 API 表面却无真实验证。自引用断言Self-referential assertion期望值由同一实际值计算而来如Assert.AreEqual(dto.Name, dto.Name)、Assert.AreEqual(result, result)或等价写法。注意不要因为合法的身份identity、克隆clone、序列化或往返round-trip契约把输出与输入比较就贴上此标签——那些断言是可以失败的。应检查输入是否经历了变换以及是否缺失了独立已知的表示、字段、引用身份或非法输入断言。吞异常Swallowed exceptionstry { ... } catch { }、catch (Exception)后不重抛也不断言.NET裸except:或except Exception:配passPythontry { ... } catch (e) {}JS/TS/Javadefer recover()不 re-panic 且无断言Gorescue StandardError无断言Ruby测试中Result::unwrap_or(...)吞掉错误Rust空catch块Kotlin/Swift。仅在 catch 块中断言try { Act(); } catch (Exception ex) { Assert.Fail(ex.Message); }及其他语言等价物——应改用Assert.ThrowsException/pytest.raises/expect(fn).toThrow/assertThrows/assert.Error(t, err)/#[should_panic]/Should -Throw/EXPECT_THROW。这种写法在未抛异常时测试照样通过即使结果错误。恒真断言Always-true assertionsAssert.IsTrue(true)、Assert.AreEqual(x, x)、assert True、expect(true).toBe(true)、assert.True(t, true)、assert!(true)或任何永不失败的条件下构造的断言。注释掉的断言Commented-out assertions断言被禁用但测试仍运行制造出覆盖的假象。High——很可能造成痛苦的测试Tests likely to cause pain反模式特征Flaky 指标用于同步的墙钟睡眠/等待Thread.Sleep/Task.Delay.NET、time.sleepPython、setTimeout/await new Promise(r setTimeout(...))JS/TS、Thread.sleepJava/Kotlin、time.SleepGo、sleepRuby/Bash、std::thread::sleepRust、Start-SleepPester、std::this_thread::sleep_forC。无抽象的墙钟读取DateTime.Now/UtcNow、datetime.now()/datetime.utcnow()、Date.now()/new Date()、System.currentTimeMillis()、time.Now()、Time.now、Instant::now()、Date()/Date.now、Get-Date、std::chrono::system_clock::now。未播种的随机性new Random()、random.random()/random.randint()、Math.random()、rand.Int()无 seed、randRuby、rand::random()Rust。环境相关路径硬编码C:\...、/tmp/...、网络主机。测试顺序依赖跨测试修改的静态/全局可变状态未完全重置状态的 setup[TestInitialize]、setUp、beforeEach、before(:each)、BeforeEach、t.Cleanup单独运行失败但整套运行时通过或反之的测试。各语言示例static字段.NET/Java、模块级全局Python、测试文件顶层let/constJS/TS、var包级全局Go、类变量Ruby、static mut/lazy_static!/OnceCellRust、$script:变量PowerShell。过度 MockOver-mockingmock 设置行数多于实际测试逻辑验证 mock 上的精确调用序列而非结果mock 测试自身拥有的类型。各语言Moq/NSubstitute/FakeItEasy.NET、unittest.mock/pytest-mockPython、Jest auto-mocks/SinonJS/TS、Mockito/PowerMockJava、gomock/testify mockGo、RSpec mocks/mochaRuby、mockallRust、MockKKotlin、MockcmdletPester、gmockC。.NET 深度 mock 审计请使用exp-mock-usage-analysis。实现耦合通过反射测试私有方法MethodInfo.Invoke、Pythongetattr、TS(thing as any)、JavaField.setAccessible(true)、RubyObject#send、Rust 内部pub(crate)访问断言内部状态而非可观察行为验证协作者上的精确方法调用次数而非业务结果。宽泛异常断言Assert.ThrowsExceptionException(...).NET/pytest.raises(Exception)/ 无消息匹配器的expect(fn).toThrow(Error)/assertThrows(Exception.class, ...)Java/ 不检查类型的assert.Error(t, err)/ 无类的expect { ... }.to raise_errorRSpec/ 无expected ...的#[should_panic]/ 无-ExpectedMessage的Should -Throw/ 使用EXPECT_ANY_THROW而非EXPECT_THROW(stmt, SpecificType)。弱变换 oracle规范化、大小写、裁剪、映射或转换测试提供的输入已经是期望形式因此即使实现是 no-op 也能通过虽然断言可能捕获其他缺陷。应使用必须发生变化的输入并断言独立推导的期望值。生产者/消费者往返测试很有用但当两侧可能共享同一缺陷时它不能替代独立的格式断言。Medium——可维护性与清晰度问题反模式特征命名差Poor naming测试名如Test1、TestMethod、test无法描述场景或结果。有扩展时用扩展约定否则遵循同一套件内既有命名约定。魔法值Magic values在 arrange/assert 中出现无法解释的数字或字符串Assert.AreEqual(42, result)/assert result 42/expect(result).toBe(42)——42 到底是什么意思重复测试Duplicate tests三个或更多方法体几乎相同、仅单个输入值不同的测试方法应参数化[DataRow]/[Theory]/[TestCase].NET、pytest.mark.parametrizepytest、test.each/it.eachJest/Vitest、ParameterizedTestValueSourceJUnit 5、DataProviderTestNG、Go 表驱动测试、where/共享示例RSpec、#[rstest]Rust、ParameterizedTestMethodSourceKotlin、-ForEach/-TestCasesPester、INSTANTIATE_TEST_SUITE_PGoogleTest、SECTION/GENERATECatch2、TEST_CASE_TEMPLATEdoctest。.NET 详细重复分析可使用exp-test-maintainability。注意覆盖不同边界条件的两个测试如零 vs 负数不是重复——不同边界条件的独立测试能提供更清晰的失败诊断是有效实践。巨型测试Giant tests超过约 30 行的测试方法或一次测试多个行为。失败时难以诊断。重复断言的断言消息Assert.AreEqual(expected, actual, Expected and actual are not equal)/assert x y, x is not equal to y/assertEquals(x, y, values not equal)不提供任何信息。消息应描述业务含义。缺少 AAA / Given-When-Then 分离Arrange/Act/Assert或 BDD 框架如 RSpec、Kotest behavior specs、Pester 的 Given/When/Then各阶段交错或无法区分。Low——风格与卫生问题反模式特征未使用的测试基础设施什么都不做的 setup/teardown 钩子——[TestInitialize]/[SetUp]/[BeforeEach]、setUp/BeforeEach/BeforeAll、beforeEach/beforeAll、before(:each)/before(:all)、BeforeEach/BeforeAllPester、setUpWithErrorXCTest——以及从未被调用的测试辅助方法。未管理的资源测试创建了可释放/可关闭资源却不清理HttpClient/Stream无using.NET、文件/连接无with块或try/finallyPython、FileInputStream无try-with-resourcesJava、缺少defer file.Close()Go、连接无ensureRuby、不依赖Drop/忘记closeRust、任何语言中缺少临时文件/数据库清理。打印调试测试开发期间遗留的Console.WriteLine/Debug.WriteLine/print()/console.log/System.out.println/fmt.Println/puts/dbg!/Write-Host/std::cout语句。命名约定不一致同一测试类/模块/文件中混用命名风格如一部分用Method_Scenario_Expected另一部分用ShouldDoSomething。Step 4诚实地校准严重度在报告之前依据以下规则逐条复核每个发现Critical/High只针对导致测试假自信或不可靠的问题。任何无论正确与否总是通过的测试都是 Critical。共享可变状态在作为潜在隔离风险时是 High但当用户报告了真实的顺序依赖失败、或代码证明一个测试必须先于另一个运行时应升级为Critical。异步断言缺await是 Critical静默通过。Medium只针对确实损害可维护性的问题——5 个近乎相同的测试、真正无意义的命名如Test1/test/it1。Low外观性命名不匹配、轻微风格偏好、可写得更好的断言消息。拿不准就定 Low。始终一致地使用调用方的严重度词汇若调用方要求 Critical / Warning / Info将潜在可靠性风险映射到 Warning、维护/外观问题映射到 Info已被证实的假自信或当前顺序依赖根因保持 Critical不要仅为了让每个要求的层级非空而降级。严重度描述的是已被证实的失败模式而非某条发现配了多少文字。将系统性发现与其各实例分离横跨一个门面facade的 coverage touching 是一个 Critical 系统性发现其证据列出每个受影响的测试。所有无断言的实例包括最后一个门面方法保持同样的假自信严重度。报告写1 finding / 6 affected tests1 个发现/6 个受影响测试而不是六个发现再加一个汇总发现也不要仅为拼凑多个层级而降级某个实例。不要把普通的缺测误评为反模式相邻的未测分支、异常路径和边界可能是值得补的覆盖机会应单独列出、不计入反模式计数除非某个弱的既有测试正是造成该缺口的原因。它们不会因为套件存在系统级 Critical 问题而变成 Critical。不是问题清单各语言细微差异Go 和 Rust 的表驱动循环配合子测试t.Run/for case in cases { ... }是惯例写法不是 Conditional Test Logic不要标记。pytest 的裸assert是规范断言形式不是缺少断言库不要标记。Go 测试用if got ! want { t.Errorf(...) }是规范相等性写法不要当作临时拼凑标记。针对不同边界条件零 vs 负数 vs null的独立测试不要标记为重复。显式逐测试 setup 而非[TestInitialize]/beforeEach这改善了隔离。短小而清晰、理论上可以合并的测试。使用非平凡输入的往返或序列化相等性这是有效的 metamorphic 证据不是自我比较但当生产者与消费者可能共享缺陷时仍建议补充一个独立表示。仅用已变换输入测试的变换不要计入同义反复tautology计数但当移除变换后仍会通过时应报告该弱 oracle改用必须变化的输入并钉死独立期望输出。克隆值相等性保留它当契约承诺深拷贝时补充不同引用或变异独立性证据。当直通pass-through就是生产契约时校验器或访问器返回原值缺少非法输入用例是覆盖缺口不是现有断言是同义反复的证据。最重要的一条如果测试写得很好要在开头明确说出来。不要为了证明评审价值而虚增严重度。一个只发现零 Critical/High、只有少量 Low 建议的评审是有效且有价值的结果。先用测试做得好的地方开头。Step 5报告发现深度标准——一份比独立人工评审还浅的整洁报告就是失败。落笔前必须满足全部六条盘点范围内每个测试总结前先建立完整的方法/字段清单。对 coverage touching 这类系统性模式至少枚举一次每个受影响测试而不是只给代表性示例。静默跳过测试或如未使用的static HttpClient字段这样的 fixture的发现表是不完整的。要写明评审数量。判定 oracle 前先核实生产契约检查实际的变换、DTO 字段与承诺的身份/克隆语义。绝不凭空捏造字段也绝不在生产代码有意有损lossy时要求无损往返。对每个可疑相等性先写下独立已知的 oracle 再下发现结论。若断言比较的是非平凡输入的变换输出、克隆状态、快照、mock 验证或框架原生断言上下文先解释它为何可能失败再称之为同义反复或无断言。反之当变换测试使用已规范化的输入时要指出该输入无法区分真实变换与 no-op并提供变化的输入加精确期望输出。对成对的生产者/消费者 API保留往返测试并额外添加一个独立表示 oracle而不是替换掉有效的 metamorphic 证据。让每个 Critical/High 修复都完整且具体给出替换后的断言和精确期望值算出的折扣、确切的 CSV 行、完整的期望对象而不是// assert something here占位符。点出明显相邻缺口而不扩散成变异分析——提供生产代码时在与发现直接相关的未测 throws、null 结果、边界值、往返/区域性敏感风险上用Adjacent coverage gaps相邻覆盖缺口小节标注。穷尽式逐分支行为缺口使用test-gap-analysis。保持报告内部一致汇总计数必须等于已枚举的发现。发布一个定稿结论所有再考量在落笔前完成绝不在输出中留下等等这不对/这个应该失败但没失败的反复推敲痕迹。让非发现也干脆利落对干净或基本干净的小套件点名你已排除的可疑结构以及使每个结构成立的框架规则。不要用通用检查清单或臆测性改进掩盖干净的结论。发现按以下结构呈现Summary汇总——发现总数按严重级别Critical / High / Medium / Low拆分。测试写得好就先肯定。Critical 和 High 发现——逐条列出反模式名称、具体位置文件、方法名、行号、为什么是问题、具体修复有助时给出 before/after 代码。Medium 和 Low 发现——用户不要求全细节时用表格汇总。Positive observations正面观察——指出测试做得好的地方sealed class、具体异常类型、数据驱动测试、清晰的 AAA 结构、正确使用 fakes、良好命名。不要只报负面。发布前为每个发现分配稳定身份合并行无论列出多少方法都算一个发现独立行各自计数。用这些行重新计算汇总。affected tests受影响测试作为另一个数字保留这样捆绑发现不会造成隐藏的计数不一致。Step 6按优先级排序建议发现较多时给出修复顺序Critical——立即修复这些测试可能在制造假自信High——尽快修复这些导致 flaky 或维护负担Medium/Low——在相关修改的顺带机会中修复验证清单技能自带发布前自检清单可作为审计报告的验收标准范围内每个测试方法都被计入写明评审数量无静默跳过身份与往返发现符合生产契约且只使用真实字段每个发现都包含具体位置而非泛泛警告每个 Critical/High 发现都含具体修复与精确期望值相邻未测错误路径与边界值被点出汇总计数与枚举发现一致分组发现区分发现数与受影响测试数相邻覆盖机会未被虚增为 Critical 反模式发现报告覆盖所有类别断言、隔离、命名、结构正面观察与问题并列呈现建议按严重度排序常见陷阱速查陷阱解决方案把风格问题报成 critical命名与格式属于 Medium/Low绝不 Critical建议重写而非定向修复展示最小 diff——改断言不是重写整个测试误判有意的设计选择若Thread.Sleep/time.sleep/time.Sleep出现在真正测试时序的集成测试中那不是反模式。要考虑上下文。在干净代码上制造假阳性测试遵循最佳实践就直说。评审结论 0 Critical, 0 High, 1 Low 完全有效。不要虚增发现来证明评审价值。把独立边界测试标为重复零与负数两个测试测的是不同边界。只有 3 个真正同体、仅差一个值的测试才算重复。把外观问题评成 Medium命名不匹配如方法名说ArgumentException却断言ArgumentOutOfRangeException是 Low 而非 Medium——测试仍能正确工作。无视测试框架使用语言扩展中加载的框架术语不要用 MSTest 术语描述 pytest 套件。只见树木不见森林若 80% 测试无断言以该系统性问题开头而非逐条罗列。为整洁牺牲深度严重度表与正面观察不能替代对每个测试的覆盖、修复中的精确期望值、相邻错误路径/边界缺口。报告中自相矛盾先推理再为每个发现写一条定稿结论——绝不输出等等这不对/应该失败但没失败的反复。计数对不上汇总的各级别总数必须与列出的发现一致。仓库中的真实评估证据test-anti-patterns技能在该仓库中配有完整的评估体系 tests/dotnet-test/test-anti-patterns/eval.yaml包含 8 个能力评估场景每个场景都用精心构造的 fixtures 检验技能的诊断能力可作为理解本技能的活教材mixed-severityUserRepositoryTests.csGetUser_NonExistentId_ReturnsNull无断言只留注释AddUser_DuplicateId_ThrowsException吞异常使测试抛与不抛都通过DeleteUser_RemovesFromRepository用Assert.AreEqual(repo.Count, repo.Count)自比较永远通过UpdateUser_ChangesName用user.Name ! Alice弱变异 oracleAddUser_NullUser_ThrowsArgumentNullException用宽泛的Assert.ThrowsExceptionException还有从未释放且看似未用的静态HttpClient字段。flaky-coupledOrderServiceTests.cs静态_processedOrders从不清理导致Test2依赖Test1先运行Thread.Sleep(2000)与DateTime.Now制造 flaky通过反射访问私有_orders字段是实现耦合ProcessOrder_InvalidId_Throws用宽泛Exception类型。duplicate-magicDiscountServiceTests.cs六个ApplyDiscount测试几乎同体、仅差输入值应参数化为[DataRow]CalculateShipping中的 42/7/3 是未解释魔法值TestTaxCalculation把多场景塞进单测试。assertion-problemsCalculatorTests.csAdd_TwoNumbers_ReturnsSum只有 TODO 无断言Subtract_TwoNumbers_ReturnsDifference用Assert.IsTrue(true)恒真断言Divide_ByZero_ThrowsException在 catch 中吞异常Divide_TwoNumbers_ReturnsQuotient用Assert.AreEqual(result, result)自比较Add_Negative_Works的断言消息 Expected and actual are not equal 只是重复断言本身属 Low。coverage-touchingProductCatalogTests.cs每个公共方法都被调用但大多无断言或只有Assert.IsNotNull典型系统性覆盖率膨胀——覆盖率达 95% 仍漏掉定价、搜索、CSV 导出格式与批量折扣计算中的 bug。self-referentialSerializerTests.cs区分真正的自我比较与合法的身份/克隆/序列化/往返契约NormalizeName_AlreadyNormalized_NoChange与UpperCase_ToUpper_Works输入HELLO已是大写是弱变换测试ToString_ParseBack_Identity是有效往返证据但建议补独立文本格式 oracle。pytest-mixedtest_user_service.py验证 Python 侧标记——无断言的test_add_user_runs_without_error、吞异常的test_get_missing_swallows_exception、assert svc.count() svc.count()自比较、宽泛pytest.raises(Exception)、time.sleep/datetime.datetime.now()flaky、模块级_SHARED_SERVICE顺序依赖、四个近乎相同的test_repeated_value_assertion_*应参数化同时确认不误报 pytest 裸assert。well-writtenPaymentProcessorTests.cs检验不制造假阳性——sealed 测试类、具体异常类型ArgumentOutOfRangeException、[DataRow]数据驱动测试、清晰 AAA、正确使用FakeGateway假件应得到 0 Critical, 0 High 的干净结论。此外评估对每个场景还校验了报告的内部一致性严重度汇总计数与枚举发现必须相等、每个发现都点名具体位置、Critical/High 有具体修复、按严重度给出修复优先级并严格禁止审计过程中调用 bash/edit/create 工具只读约束见各场景的reject_tools。这套评估既验证了技能本身的诊断能力也反过来为你提供了什么样的测试审计报告才算合格的黄金标准——它本身就是一份可对照的实践基准。小结test-anti-patterns是一把聚焦假自信测试的务实手术刀它以四级严重度反模式目录为骨架以先建完整性台账、再核实生产契约、后定稿结论的报告纪律为灵魂配合六步工作流与严苛的深度标准确保每次审计既覆盖全部被测代码又给出可直接落地的精确修复。无论你是维护者想评估套件健康状况还是 Agent 需要为 LLM 生成可信的测试诊断这套方法论都值得直接复用——仓库中的 eval.yaml 及其 8 组 fixtures 提供了最真实的演练场。【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表