test-tagging
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTest Trait Tagging
测试特性标记
Analyze an existing test suite and apply a standardized set of trait tags to each test method, giving teams visibility into their test distribution (positive vs. negative, critical-path coverage, smoke tests, etc.).
分析现有测试套件,并为每个测试方法应用一套标准化的特性标签,帮助团队了解其测试分布情况(正向测试 vs 负向测试、核心路径覆盖情况、冒烟测试等)。
When to Use
适用场景
- Auditing a test project to understand the mix of test types
- Adding trait attributes to untagged tests
- Generating a summary report of trait distribution across a test suite
- Reviewing whether critical paths have sufficient coverage
- 审计测试项目,了解测试类型的构成
- 为未标记的测试添加特性属性
- 生成测试套件的特性分布汇总报告
- 检查核心路径是否有足够的覆盖
When Not to Use
不适用场景
- Writing new tests from scratch (use )
writing-mstest-tests - Running or filtering tests (use )
run-tests - Migrating between test frameworks
- 从零开始编写新测试(使用 )
writing-mstest-tests - 运行或筛选测试(使用 )
run-tests - 在测试框架之间迁移
Inputs
输入项
| Input | Required | Description |
|---|---|---|
| Test project or files | Yes | Path to the test project, folder, or specific test files to analyze |
| Scope | No | |
| Framework | No | Auto-detected. Override with |
| 输入项 | 是否必填 | 说明 |
|---|---|---|
| 测试项目或文件 | 是 | 要分析的测试项目、文件夹或特定测试文件的路径 |
| 范围 | 否 | |
| 框架 | 否 | 自动检测。若检测失败,可手动指定为 |
Trait Taxonomy
特性分类体系
Use exactly these trait names and values. Do not invent new trait values outside this table.
| Trait Value | Meaning | Heuristics |
|---|---|---|
| Verifies expected behavior under normal/valid conditions | Asserts success, valid output, expected state, no exceptions for valid input |
| Verifies correct handling of invalid input, errors, or edge cases | Asserts exceptions, error codes, validation failures, rejects bad input |
| Tests limits, thresholds, empty/null inputs, min/max values | Operates on |
| Core workflow that must never break; breakage blocks users | Tests the primary success scenario of a key public API or user-facing feature |
| Quick sanity check that the system is operational | Fast, no complex setup, verifies basic wiring (e.g., service resolves, endpoint returns 200) |
| Reproduces a specific previously-reported bug | References a bug ID, issue number, or describes a fix in its name or comments |
| Crosses process, network, or persistence boundaries | Uses real database, HTTP client, file system, external service, or multi-component setup |
| Full user workflow spanning the entire application stack | Exercises a complete scenario from entry point to final result, distinct from single-boundary |
| Validates timing, throughput, or resource consumption | Asserts on elapsed time, memory, allocations, or uses benchmark harness |
| Verifies authentication, authorization, input sanitization, or secrets handling | Tests for SQL injection, XSS, CSRF, unauthorized access, token validation, permission checks |
| Validates thread safety, parallelism, or async correctness | Uses |
| Tests retry logic, timeouts, circuit breakers, or graceful degradation | Asserts behavior under transient failures, network drops, or service unavailability (e.g., Polly policies) |
| Mutates shared or external state that is hard to roll back | Deletes records, drops resources, modifies global config -- useful for CI isolation decisions |
| Verifies settings loading, defaults, environment behavior | Tests missing config keys, invalid values, environment variable fallbacks, options validation |
| Known to intermittently fail (meta-tag for test health tracking) | Mark tests the team knows are unreliable; used to quarantine or prioritize stabilization |
A single test may have multiple traits (e.g., both and ). At minimum, every test should receive one of or .
negativeboundarypositivenegative请严格使用以下特性名称和取值,请勿使用此表格以外的特性取值。
| 特性取值 | 含义 | 判断依据 |
|---|---|---|
| 验证正常/有效条件下的预期行为 | 断言成功、有效输出、预期状态,有效输入无异常 |
| 验证对无效输入、错误或边缘情况的正确处理 | 断言异常、错误码、验证失败、拒绝不良输入 |
| 测试限制、阈值、空/Null输入、最小/最大值 | 操作 |
| 绝对不能中断的核心工作流;中断会阻碍用户操作 | 测试关键公共API或用户面向功能的主要成功场景 |
| 快速 sanity 检查,验证系统是否可正常运行 | 执行速度快,无复杂配置,验证基础连接(如:服务可解析、端点返回200) |
| 复现特定的已报告Bug | 名称或注释中引用Bug ID、问题编号,或描述修复内容 |
| 跨进程、网络或持久化边界 | 使用真实数据库、HTTP客户端、文件系统、外部服务,或多组件配置 |
| 跨越整个应用栈的完整用户工作流 | 执行从入口点到最终结果的完整场景,区别于单一边界的 |
| 验证时序、吞吐量或资源消耗 | 断言耗时、内存、内存分配,或使用基准测试工具 |
| 验证认证、授权、输入清理或密钥处理 | 测试SQL注入、XSS、CSRF、未授权访问、令牌验证、权限检查 |
| 验证线程安全、并行性或异步正确性 | 使用 |
| 测试重试逻辑、超时、熔断或优雅降级 | 断言瞬态故障、网络中断或服务不可用时的行为(如:Polly策略) |
| 修改难以回滚的共享或外部状态 | 删除记录、销毁资源、修改全局配置——有助于CI隔离决策 |
| 验证配置加载、默认值、环境行为 | 测试缺失的配置键、无效值、环境变量回退、选项验证 |
| 已知会间歇性失败(用于测试健康跟踪的元标签) | 标记团队已知不可靠的测试;用于隔离或优先稳定处理 |
单个测试可拥有多个特性(例如:同时标记和)。每个测试至少应标记或中的一个。
negativeboundarypositivenegativeWorkflow
工作流程
Step 1: Detect the test framework
步骤1:检测测试框架
Examine project files and source code to determine the framework — see the skill for the complete detection table (package references, test markers, assertion APIs, and skip annotations).
dotnet-test-frameworks检查项目文件和源代码以确定框架——完整的检测规则请参考技能(包引用、测试标记、断言API和跳过注解)。
dotnet-test-frameworksStep 2: Scan existing traits
步骤2:扫描现有特性
Check which tests already have trait attributes:
| Framework | Existing Attribute | Example |
|---|---|---|
| MSTest | | |
| xUnit | | |
| NUnit | | |
Record which tests already have tags to avoid duplication.
检查哪些测试已拥有特性属性:
| 框架 | 现有属性 | 示例 |
|---|---|---|
| MSTest | | |
| xUnit | | |
| NUnit | | |
记录已标记的测试,避免重复添加。
Step 3: Classify each test method
步骤3:对每个测试方法分类
For each test method without traits, analyze:
- Method name -- names containing ,
Invalid,Fail,Error,Throw,Reject,BadInput,NullsuggestNegativenegative - Assertion type -- ,
Assert.ThrowsException,Assert.ThrowssuggestShould().Throw()negative - Input values -- ,
null,"",0,-1,int.MaxValue, empty collections suggestint.MinValueboundary - Setup complexity -- minimal setup with basic assertions suggests ; external dependencies suggest
smokeintegration - Comments and names -- references to issue numbers or "regression" / "bug" / "fix for #..." suggest
regression - Timing assertions -- ,
Stopwatch, elapsed-time checks suggestBenchmarkDotNetperformance - Feature centrality -- tests on primary public API entry points or critical user workflows suggest
critical-path - Security patterns -- validates auth, checks permissions, sanitizes input, tests for injection, handles tokens/secrets suggest
security - Parallel/async constructs -- ,
Task.WhenAll, locks,Parallel.ForEach,SemaphoreSlim, race condition names suggestConcurrentDictionaryconcurrency - Fault injection -- simulates failures, tests retries, timeouts, or circuit breakers suggest
resilience - State mutation -- deletes external records, drops resources, modifies shared/global state suggest
destructive - Full-stack flow -- test spans entry point through data layer to final response, covering a complete user scenario suggest
end-to-end - Config/settings -- loads configuration, tests missing keys, validates options, checks environment variables suggest
configuration - Known instability -- test has /
[Ignore]comments about flakiness, or names contain "flaky"/"intermittent" suggest[Skip]flaky - Default -- if the test verifies a normal success path, tag
positive
When in doubt between and , read the assertion: if it asserts success -> ; if it asserts failure -> .
positivenegativepositivenegative对于每个未标记特性的测试方法,分析以下内容:
- 方法名称——包含、
Invalid、Fail、Error、Throw、Reject、BadInput、Null的名称表明是Negative测试negative - 断言类型——、
Assert.ThrowsException、Assert.Throws表明是Should().Throw()测试negative - 输入值——、
null、""、0、-1、int.MaxValue、空集合表明是int.MinValue测试boundary - 配置复杂度——最小配置+基础断言表明是测试;依赖外部服务表明是
smoke测试integration - 注释和名称——引用问题编号或包含"regression"/"bug"/"fix for #..."表明是测试
regression - 时序断言——、
Stopwatch、耗时检查表明是BenchmarkDotNet测试performance - 核心特性——测试主要公共API入口点或关键用户工作流表明是测试
critical-path - 安全模式——验证认证、检查权限、清理输入、测试注入、处理令牌/密钥表明是测试
security - 并行/异步结构——、
Task.WhenAll、锁、Parallel.ForEach、SemaphoreSlim、竞态条件名称表明是ConcurrentDictionary测试concurrency - 故障注入——模拟故障、测试重试、超时或熔断表明是测试
resilience - 状态修改——删除外部记录、销毁资源、修改共享/全局状态表明是测试
destructive - 全栈流程——测试从入口点到数据层再到最终响应的完整用户场景表明是测试
end-to-end - 配置/设置——加载配置、测试缺失键、验证选项、检查环境变量表明是测试
configuration - 已知不稳定性——测试带有/
[Ignore]注释说明不稳定,或名称包含"flaky"/"intermittent"表明是[Skip]测试flaky - 默认值——若测试验证正常成功路径,标记为
positive
若无法确定是还是,查看断言内容:断言成功则标记;断言失败则标记。
positivenegativepositivenegativeStep 4: Apply trait attributes
步骤4:应用特性属性
Add the appropriate attribute to each test method. Place trait attributes on the line directly above or below the existing test attribute.
MSTest:
csharp
[TestMethod]
[TestCategory("negative")]
[TestCategory("boundary")]
public void Parse_NullInput_ThrowsArgumentNullException() { ... }xUnit:
csharp
[Fact]
[Trait("Category", "positive")]
[Trait("Category", "critical-path")]
public void CreateOrder_ValidItems_ReturnsConfirmation() { ... }NUnit:
csharp
[Test]
[Category("regression")]
[Category("negative")]
public void Calculate_OverflowInput_ReturnsError() // Fix for #1234
{ ... }为每个测试方法添加适当的属性。将特性属性放在现有测试属性的上一行或下一行。
MSTest:
csharp
[TestMethod]
[TestCategory("negative")]
[TestCategory("boundary")]
public void Parse_NullInput_ThrowsArgumentNullException() { ... }xUnit:
csharp
[Fact]
[Trait("Category", "positive")]
[Trait("Category", "critical-path")]
public void CreateOrder_ValidItems_ReturnsConfirmation() { ... }NUnit:
csharp
[Test]
[Category("regression")]
[Category("negative")]
public void Calculate_OverflowInput_ReturnsError() // Fix for #1234
{ ... }Step 5: Generate trait summary
步骤5:生成特性汇总
After tagging, produce a summary table:
undefined标记完成后,生成汇总表格:
undefinedTrait Distribution
特性分布
| Trait | Count | % of Total |
|---|---|---|
| positive | 42 | 53.8% |
| negative | 22 | 28.2% |
| boundary | 8 | 10.3% |
| critical-path | 12 | 15.4% |
| smoke | 3 | 3.8% |
| regression | 5 | 6.4% |
| integration | 4 | 5.1% |
| end-to-end | 2 | 2.6% |
| performance | 1 | 1.3% |
| security | 3 | 3.8% |
| concurrency | 2 | 2.6% |
| resilience | 1 | 1.3% |
| destructive | 1 | 1.3% |
| configuration | 2 | 2.6% |
| flaky | 1 | 1.3% |
| Total tests | 78 | -- |
Note: Percentages exceed 100% because tests can have multiple traits.
Include observations such as:
- Ratio of positive to negative tests
- Whether critical-path tests exist for key public APIs
- Any tests that could not be confidently classified (list them for manual review)| 特性 | 数量 | 占比 |
|---|---|---|
| positive | 42 | 53.8% |
| negative | 22 | 28.2% |
| boundary | 8 | 10.3% |
| critical-path | 12 | 15.4% |
| smoke | 3 | 3.8% |
| regression | 5 | 6.4% |
| integration | 4 | 5.1% |
| end-to-end | 2 | 2.6% |
| performance | 1 | 1.3% |
| security | 3 | 3.8% |
| concurrency | 2 | 2.6% |
| resilience | 1 | 1.3% |
| destructive | 1 | 1.3% |
| configuration | 2 | 2.6% |
| flaky | 1 | 1.3% |
| 总测试数 | 78 | -- |
注:占比总和超过100%,因为单个测试可拥有多个特性。
同时包含以下观察结果:
- 正向测试与负向测试的比例
- 关键公共API是否有核心路径测试
- 无法准确分类的测试(列出以便人工审核)Validation
验证项
- Every test method has at least one trait attribute (or
positiveat minimum)negative - No invented trait values outside the taxonomy table
- Existing trait attributes were preserved, not duplicated
- The trait summary table was generated
- The project still builds after changes ()
dotnet build
- 每个测试方法至少拥有一个特性属性(至少标记或
positive)negative - 未使用分类体系以外的特性取值
- 保留了现有特性属性,未重复添加
- 生成了特性汇总表格
- 修改后项目仍可正常构建()
dotnet build
Common Pitfalls
常见陷阱
| Pitfall | Solution |
|---|---|
| Guessing traits without reading the test body | Always read assertions and setup to classify accurately |
Tagging a test only as | Every test should also be |
Using | Match the attribute style to the detected framework |
| Duplicating an existing category attribute | Check for pre-existing traits in Step 2 before adding |
Over-tagging as | Reserve for tests on primary public entry points, not every helper |
| 陷阱 | 解决方案 |
|---|---|
| 未阅读测试内容就猜测特性 | 务必阅读断言和配置内容以准确分类 |
仅标记 | 每个测试还应标记 |
在xUnit项目中使用 | 根据检测到的框架匹配对应的属性格式 |
| 重复添加已存在的分类属性 | 步骤2中检查现有特性后再添加新属性 |
过度标记 | 仅用于主要公共入口点的测试,而非所有辅助测试 |