Exp Test Maintainability
.NET (Microsoft)OfficialPublished by .NET (Microsoft)
- Skill
- Research and analysis
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill performs a static analysis of .NET test code (MSTest, xUnit, NUnit, TUnit) to detect patterns that hinder maintainability. It focuses on identifying repeated object construction, assertion sequences, copy-paste test methods, and redundant setup logic. The skill produces a structured report detailing refactoring opportunities with concrete before-and-after code examples, while adhering to strict calibration rules to avoid flagging intentional test verbosity or simple constructors.
What it does
- Detects repeated object construction patterns across multiple test methods.
- Identifies identical assertion sequences suitable for custom helpers.
- Finds copy-paste test methods that can be converted to parameterized tests.
- Locates redundant setup or teardown logic across test classes.
- Provides a structured analysis report with specific file and method locations.
- Offers concrete before-and-after refactoring suggestions for identified issues.
When to use it
- When you want to reduce test suite boilerplate and improve readability.
- When you need to identify opportunities to consolidate similar test methods.
- When you are looking to convert repetitive tests into data-driven parameterized tests.
- When you need to identify shared setup or teardown logic that could be centralized.
- When you want to assess the structural maintainability of a .NET test project.
Advantages
- Reduces code duplication in test suites without sacrificing test isolation.
- Provides actionable, concrete refactoring guidance rather than abstract advice.
- Uses a 3+ occurrence threshold to prevent over-refactoring of clear, simple tests.
- Supports multiple major .NET testing frameworks.
- Includes trade-off analysis for every suggested refactoring.
Usage examples
- “Analyze my test suite for boilerplate and suggest ways to reduce repetition.”
- The agent scans the provided test files, identifies repeated object creation or assertion patterns occurring 3+ times, and generates a report with refactoring suggestions like extracting factory methods.
- “I have many tests that look identical except for the input values. Can you help me clean them up?”
- The agent identifies these copy-paste methods and suggests converting them into parameterized tests using framework-specific attributes like DataRow, Theory, or TestCase.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/dotnet/exp-test-maintainability/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip exp-test-maintainability.zip -d .agents/skills
Documentation by .NET (Microsoft)
Test Maintainability Assessment
Analyze .NET test code for maintainability issues: duplicated boilerplate, copy-paste test methods, and structural repetition across test methods and classes. Produce a report of refactoring opportunities with concrete before/after suggestions. The goal is analysis only — do not modify any files.
When to Use
User asks to find duplicated code or boilerplate in tests
User wants to know where test code can be DRY-ed up
User asks to reduce test duplication, improve test readability, or clean up test boilerplate
User asks for refactoring opportunities in a test suite
User wants to identify shared setup or teardown candidates
User asks "what patterns repeat across my tests?"
User wants to centralize test data, introduce builders or helpers
When Not to Use
User wants to write new tests from scratch (use
writing-mstest-tests)User wants to detect anti-patterns or code smells (use
test-anti-patterns)User wants to actually perform the refactoring (help them directly, this skill only analyzes)
Inputs
| Input | Required | Description |
|---|---|---|
| Test code | Yes | One or more test files or a test project directory to analyze |
| Production code | No | The code under test, for context on what abstractions might help |
| Scope | No | Whether to analyze within a single class or across multiple classes |
Workflow
Step 1: Gather the test code
Read all test files the user provides or references. If the user points to a directory or project, scan for all test files using these framework markers:
| Framework | Test class markers | Test method markers |
|---|---|---|
| MSTest | [TestClass] | [TestMethod], [DataTestMethod] |
| xUnit | (none — convention-based) | [Fact], [Theory] |
| NUnit | [TestFixture] | [Test], [TestCase], [TestCaseSource] |
| TUnit | (none — convention-based) | [Test] |
Step 2: Identify maintainability issues
Scan for these categories:
Category 1: Repeated object construction
Look for the same object being constructed in 3+ test methods with identical or near-identical parameters.
Indicators:
new ClassName(...)appearing with identical arguments in multiple testsMultiple tests creating the same "system under test" with similar configuration
Repeated mock/fake/stub creation with the same setup
Potential refactorings:
Extract a factory method or test helper (e.g.,
CreateSut(),CreateDefaultOrder())Use
[TestInitialize]/constructor/[SetUp]for shared constructionIntroduce a builder pattern for complex objects with many variations
Example — before:
[TestMethod]
public void Process_ValidOrder_Succeeds()
{
var logger = new FakeLogger();
var email = new FakeEmailService();
var inventory = new FakeInventory(stock: 100);
var processor = new OrderProcessor(logger, email, inventory);
// ...
}
[TestMethod]
public void Process_EmptyItems_Fails()
{
var logger = new FakeLogger();
var email = new FakeEmailService();
var inventory = new FakeInventory(stock: 100);
var processor = new OrderProcessor(logger, email, inventory);
// ...
}After — extract factory:
private static OrderProcessor CreateProcessor(int stock = 100)
{
return new OrderProcessor(new FakeLogger(), new FakeEmailService(), new FakeInventory(stock));
}Category 2: Repeated assertion patterns
Look for the same sequence of assertions appearing in 3+ test methods.
Indicators:
Multiple tests asserting the same set of properties on a result object
Repeated null-check-then-value-check sequences
Same collection of
Assert.AreEqualcalls across methods
Potential refactorings:
Extract a custom assertion helper (e.g.,
AssertValidOrder(order, expectedTotal, expectedStatus))Use framework-specific assertion extensions
Introduce a
Verifymethod that checks a standard set of properties
Category 3: Copy-paste test methods
Look for test methods with near-identical bodies differing only in input values or a single parameter.
Indicators:
3+ methods with the same structure but different literal values
Methods that could be collapsed into
[DataRow]/[Theory]/[TestCase]Test names that follow a pattern like
Method_Input1_Result,Method_Input2_Result
Potential refactorings:
Convert to parameterized tests with
[DataRow]/[InlineData]/[TestCase]Use
[DynamicData]/[MemberData]/[TestCaseSource]for complex inputsPrefer
[DataRow]withDisplayNameover[DynamicData]when all values are compile-time constants. Reserve[DynamicData]for computed or complex values.Add
DisplayNamefor non-obvious parameter values.[DataRow("Gold", 100.0, 90.0)]is self-explanatory;[DataRow(3, 7, 42)]is not.
Category 4: Duplicated setup/teardown logic
Look for initialization or cleanup code repeated across test classes.
Indicators:
Multiple
[TestInitialize]/[SetUp]methods with similar bodiesRepeated database seeding, file creation, or HTTP client configuration
Same
using/IDisposablecleanup pattern across classes
Potential refactorings:
Extract a shared test base class or fixture
Use composition with a shared helper class
Create a test context factory
Category 5: Repeated test infrastructure
Look for structural patterns shared across test classes.
Indicators:
Same mock interfaces configured identically in multiple classes
Repeated
HttpClientsetup with similarDelegatingHandlerpatternsSame logging/configuration scaffolding across test classes
Potential refactorings:
Extract a shared test fixture or helper library
Create reusable fake implementations
Introduce a test harness class
Step 3: Apply calibration rules
Before reporting, filter findings through these rules:
Only report at 3+ occurrences. Two similar setups are not boilerplate — they may be intentional clarity.
Don't flag simple constructors.
new Calculator()ornew List<int>()is not meaningful boilerplate. Don't recommend builders fornew User(1, "Alice")either.Respect intentional verbosity. If each test is self-contained and reads clearly on its own, explicit setup per test is a valid choice. Note it but don't flag it as a problem.
Distinguish structural similarity from true duplication. Tests that follow AAA (Arrange-Act-Assert) will look similar by nature. Only flag when the actual code (not just the structure) is duplicated.
Consider the blast radius of refactoring. A helper shared across 20 tests creates coupling. Note the trade-off.
If tests are already well-maintained, say so. A report finding only minor opportunities is perfectly valid. Acknowledge what's already good.
Step 4: Report findings
Present findings in this structure:
Summary — How many patterns found, broken down by category. If the test suite is clean, lead with that.
Findings by category — For each pattern found:
Category name and description
Locations: list the specific test methods and files involved
The duplicated code pattern (show a representative sample)
Suggested refactoring with a concrete before/after example
Estimated impact: how many lines/methods would be simplified
Refactoring priority — Rank findings by:
Occurrence count (more occurrences = higher value)
Complexity of the duplicated code (complex setup > simple construction)
Risk (low-risk extractions first)
Trade-offs — For each suggestion, note:
What readability is gained
What locality/independence is lost
Whether it's worth it given the occurrence count
Validation
[ ] Every finding includes specific file and method locations
[ ] Every finding shows the actual duplicated code, not just a description
[ ] Every suggestion includes a concrete before/after example
[ ] Findings are filtered through the 3+ occurrence threshold
[ ] Simple constructors are not flagged
[ ] Trade-offs are acknowledged for each suggestion
[ ] If tests are clean, the report says so upfront
Common Pitfalls
| Pitfall | Solution |
|---|---|
| Flagging AAA structure as duplication | The Arrange-Act-Assert pattern is not boilerplate — flag only when the actual code repeats |
| Suggesting extraction for 2 occurrences | Wait for 3+ before recommending extraction |
| Recommending base classes for everything | Prefer composition (helpers, factories) over inheritance |
| Ignoring the readability cost | Every extraction adds indirection — note the trade-off |
Flagging simple new X() as boilerplate | Only flag complex construction with multiple parameters or configuration |
| Recommending DRY at the expense of test isolation | Tests that share mutable state through helpers become coupled — warn about this |
Files
- ATTRIBUTION.mdAdded by AutoGineer867 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md9.6 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- .NET (Microsoft)
- Publisher
- .NET (Microsoft) (Official)
- Source
- dotnet/skills · plugins/dotnet-experimental/skills/exp-test-maintainability · commit 96c3d68
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by .NET (Microsoft).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download exp-test-maintainability.zip