Skip to content

[test-improver] test: add edge case tests for MSTEST0020 and MSTEST0021 analyzers #9648

Description

@github-actions

Goal and Rationale

Add edge case tests for two "prefer OOP pattern" analyzers that both lack coverage of scenarios outside the normal [TestClass] context:

  • MSTEST0020 (PreferConstructorOverTestInitializeAnalyzer) — verify the fixer handles a parameterized-only constructor and a non-[TestClass] container correctly
  • MSTEST0021 (PreferDisposeOverTestCleanupAnalyzer) — verify the analyzer fires and the fixer works when [TestCleanup] appears in a class without [TestClass]

Changes

PreferConstructorOverTestInitializeAnalyzerTests.cs (+2 tests)

Test What it covers
WhenTestInitializeNotInTestClass_Diagnostic Analyzer fires even when the containing class lacks [TestClass]; fixer replaces the method with a public constructor
WhenTestClassHasOnlyParameterizedCtorAndTestInitialize_Diagnostic Fixer merges [TestInitialize] body into the first non-static constructor, even when that constructor has parameters

PreferDisposeOverTestCleanupAnalyzerTests.cs (+1 test)

Test What it covers
WhenTestCleanupNotInTestClass_Diagnostic Analyzer fires even when the containing class lacks [TestClass]; fixer adds IDisposable to the base list and replaces the method with Dispose()

Coverage Impact

No production code changed — purely additive tests.

Approach

Both analyzers (PreferConstructorOverTestInitializeAnalyzer and PreferDisposeOverTestCleanupAnalyzer) check for the presence of [TestInitialize]/[TestCleanup] attributes on methods without verifying the containing class carries [TestClass]. The new tests document this intentional behavior and verify that the code fixers produce well-formed output in each scenario.

Test Status

Debug build: 0 warnings, 0 errors.
All 1350 tests pass (1347 pre-existing + 3 new).

🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Test Improver workflow. · 182.1 AIC · ⌖ 16.2 AIC · ⊞ 13K · [◷]( · )

Add this agentic workflows to your repo

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/test-improver.md@main

Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch test-assist/mstest0020-0021-edge-cases-09fb0bbe58d0e202.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (158 of 158 lines)
From aba2b0360abfcaf3e5e7dd488ebcc513b6716ca4 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Sun, 5 Jul 2026 23:29:00 +0000
Subject: [PATCH] test: add edge case tests for MSTEST0020 and MSTEST0021
 analyzers

PreferConstructorOverTestInitializeAnalyzer (MSTEST0020), +2 tests:
- WhenTestInitializeNotInTestClass_Diagnostic: analyzer fires on a
  [TestInitialize] method in a class without [TestClass]; fixer
  replaces it with a public constructor.
- WhenTestClassHasOnlyParameterizedCtorAndTestInitialize_Diagnostic:
  fixer merges TestInitialize body into the first non-static constructor
  found, even when that constructor has parameters.

PreferDisposeOverTestCleanupAnalyzer (MSTEST0021), +1 test:
- WhenTestCleanupNotInTestClass_Diagnostic: analyzer fires on a
  [TestCleanup] method in a class without [TestClass]; fixer adds
  IDisposable to the class and creates a Dispose() method.

All 1350 tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 ...structorOverTestInitializeAnalyzerTests.cs | 73 +++++++++++++++++++
 ...eferDisposeOverTestCleanupAnalyzerTests.cs | 32 ++++++++
 2 files changed, 105 insertions(+)

diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs
index d6a1f2d..98d7293 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs
@@ -404,6 +404,79 @@ private void SomePrivateMethod()
         await VerifyCS.VerifyCodeFixAsync(code, fixedCode);
     }
 
+    [TestMethod]
+    public async Task WhenTestInitializeNotInTestClass_Diagnostic()
+    {
+        // The analyzer fires regardless of whether the containing class has [TestClass].
+        string code = """
+            
... (truncated)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions