Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Detects duplicate boilerplate, copy-paste tests, and structural maintainability issues across .NET test suites. Use when the user asks to reduce repetition, consolidate similar test methods, convert copy-paste tests to data-driven parameterized tests, suggest a better test structure, or identify refactoring opportunities. Identifies repeated construction, assertion patterns, copy-paste methods convertible to DataRow/Theory/TestCase, redundant setup/teardown, and shared infrastructure. Produces a
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 85% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-21 | ✓→✗ | ▼ Worse | 209% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 84% | 0% |
| case-06 | ✓→✓ | = Same ✓ | 136% | 0% |
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.
writing-mstest-tests)test-anti-patterns)| 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 |
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] |
Scan for these categories:
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 testsPotential refactorings:
CreateSut(), CreateDefaultOrder())[TestInitialize]/constructor/[SetUp] for shared constructionExample — before:
csharp[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:
csharpprivate static OrderProcessor CreateProcessor(int stock = 100) { return new OrderProcessor(new FakeLogger(), new FakeEmailService(), new FakeInventory(stock)); }
Look for the same sequence of assertions appearing in 3+ test methods.
Indicators:
Assert.AreEqual calls across methodsPotential refactorings:
AssertValidOrder(order, expectedTotal, expectedStatus))Verify method that checks a standard set of propertiesLook for test methods with near-identical bodies differing only in input values or a single parameter.
Indicators:
[DataRow]/[Theory]/[TestCase]Method_Input1_Result, Method_Input2_ResultPotential refactorings:
[DataRow]/[InlineData]/[TestCase][DynamicData]/[MemberData]/[TestCaseSource] for complex inputs[DataRow] with DisplayName over [DynamicData] when all values are compile-time constants. Reserve [DynamicData] for computed or complex values.DisplayName for non-obvious parameter values. [DataRow("Gold", 100.0, 90.0)] is self-explanatory; [DataRow(3, 7, 42)] is not.Look for initialization or cleanup code repeated across test classes.
Indicators:
[TestInitialize]/[SetUp] methods with similar bodiesusing/IDisposable cleanup pattern across classesPotential refactorings:
Look for structural patterns shared across test classes.
Indicators:
HttpClient setup with similar DelegatingHandler patternsPotential refactorings:
Before reporting, filter findings through these rules:
new Calculator() or new List<int>() is not meaningful boilerplate. Don't recommend builders for new User(1, "Alice") either.Present findings in this structure:
| 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 |
Other measured skills in the registry, with their headline benchmark lift.