Goal and Rationale
Two analyzers had untested code paths:
GlobalTestFixtureShouldBeValidAnalyzer (MSTEST0050) — HasValidFixtureMethodSignature has two guards not exercised by existing tests:
ContainingType.IsGenericType && !allowGenericType — fires for generic classes; not previously tested
Inherits(testClassAttributeSymbol) — recognises derived TestClassAttributes; only the base attribute was tested
DuplicateTestMethodAttributeAnalyzer (MSTEST0060) — two paths not covered:
- Analyzer has no
[TestClass] guard: fires on duplicate TestMethod-derived attributes on any method, even outside a [TestClass]; not tested
- Fixer first-wins strategy: when a derived attribute appears before
[TestMethod], the fixer keeps the derived one and removes [TestMethod]; only the reverse order was tested
Approach
Added 4 [TestMethod] entries (2 per test file):
| Test |
File |
What it covers |
WhenGlobalTestInitializeInGenericClass_Diagnostic |
GlobalTestFixtureShouldBeValidAnalyzerTests.cs |
ContainingType.IsGenericType && !allowGenericType → diagnostic |
WhenGlobalTestCleanupWithDerivedTestClassAttribute_NoDiagnostic |
GlobalTestFixtureShouldBeValidAnalyzerTests.cs |
Inherits(testClassAttributeSymbol) recognises derived attr → no diagnostic |
WhenTestMethodHasDuplicateAttributesOutsideTestClass_Diagnostic |
DuplicateTestMethodAttributeAnalyzerTests.cs |
analyzer has no [TestClass] guard → fires in non-TestClass |
WhenDerivedAttributeIsFirstAndTestMethodIsSecond_CodeFix_KeepsDerivedAttribute |
DuplicateTestMethodAttributeAnalyzerTests.cs |
first-wins: [MyTestMethod]\n[TestMethod] → keeps [MyTestMethod], removes [TestMethod] |
Coverage Impact
|
Before |
After |
Tests in GlobalTestFixtureShouldBeValidAnalyzerTests |
15 |
17 |
Tests in DuplicateTestMethodAttributeAnalyzerTests |
12 |
14 |
Trade-offs
Purely additive — no production code changes, no new dependencies.
Test Status
All 31/31 tests pass (net8.0, Debug):
Test run summary: Passed!
total: 31
failed: 0
succeeded: 31
duration: 7s 030ms
Reproducibility
.dotnet/dotnet test test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj \
-f net8.0 --no-build -c Debug \
--filter "FullyQualifiedName~GlobalTestFixtureShouldBeValidAnalyzerTests|FullyQualifiedName~DuplicateTestMethodAttributeAnalyzerTests"
🤖 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. · 143.1 AIC · ⌖ 19.8 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
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (173 of 173 lines)
From 33f5d9166f02a72d30106b227fb8be8dc3c1cea5 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Fri, 3 Jul 2026 23:27:10 +0000
Subject: [PATCH] test: add edge case tests for
GlobalTestFixtureShouldBeValidAnalyzer (MSTEST0050) and
DuplicateTestMethodAttributeAnalyzer (MSTEST0060)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GlobalTestFixtureShouldBeValidAnalyzerTests (+2 tests):
- WhenGlobalTestInitializeInGenericClass_Diagnostic: generic containing type
is rejected by allowGenericType:false guard (ContainingType.IsGenericType path)
- WhenGlobalTestCleanupWithDerivedTestClassAttribute_NoDiagnostic: derived
TestClassAttribute satisfies the Inherits(testClassAttributeSymbol) guard
DuplicateTestMethodAttributeAnalyzerTests (+2 tests):
- WhenTestMethodHasDuplicateAttributesOutsideTestClass_Diagnostic: analyzer
has no TestClass guard — fires on duplicate TestMethod attrs in any class
- WhenDerivedAttributeIsFirstAndTestMethodIsSecond_CodeFix_KeepsDerivedAttribute:
fixer first-wins strategy — keeps the first TestMethod-derived attribute
encountered; derived attribute before [TestMethod] is retained
All 31/31 tests pass.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
...plicateTestMethodAttributeAnalyzerTests.cs | 75 +++++++++++++++++++
...alTestFixtureShouldBeValidAnalyzerTests.cs | 45 +++++++++++
2 files changed, 120 insertions(+)
diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DuplicateTestMethodAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DuplicateTestMethodAttributeAnalyzerTests.cs
index b86a0b9..ca4f9fd 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/DuplicateTestMethodAttributeAnalyzerTests.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DuplicateTestMethodAttributeAnalyzerTests.cs
@@ -378,4 +378,79 @@ public void TestMethod1()
await VerifyCS.VerifyCodeFixAsync(code, fix
... (truncated)
Goal and Rationale
Two analyzers had untested code paths:
GlobalTestFixtureShouldBeValidAnalyzer (MSTEST0050) —
HasValidFixtureMethodSignaturehas two guards not exercised by existing tests:ContainingType.IsGenericType && !allowGenericType— fires for generic classes; not previously testedInherits(testClassAttributeSymbol)— recognises derivedTestClassAttributes; only the base attribute was testedDuplicateTestMethodAttributeAnalyzer (MSTEST0060) — two paths not covered:
[TestClass]guard: fires on duplicate TestMethod-derived attributes on any method, even outside a[TestClass]; not tested[TestMethod], the fixer keeps the derived one and removes[TestMethod]; only the reverse order was testedApproach
Added 4
[TestMethod]entries (2 per test file):WhenGlobalTestInitializeInGenericClass_DiagnosticGlobalTestFixtureShouldBeValidAnalyzerTests.csContainingType.IsGenericType && !allowGenericType→ diagnosticWhenGlobalTestCleanupWithDerivedTestClassAttribute_NoDiagnosticGlobalTestFixtureShouldBeValidAnalyzerTests.csInherits(testClassAttributeSymbol)recognises derived attr → no diagnosticWhenTestMethodHasDuplicateAttributesOutsideTestClass_DiagnosticDuplicateTestMethodAttributeAnalyzerTests.cs[TestClass]guard → fires in non-TestClassWhenDerivedAttributeIsFirstAndTestMethodIsSecond_CodeFix_KeepsDerivedAttributeDuplicateTestMethodAttributeAnalyzerTests.cs[MyTestMethod]\n[TestMethod]→ keeps[MyTestMethod], removes[TestMethod]Coverage Impact
GlobalTestFixtureShouldBeValidAnalyzerTestsDuplicateTestMethodAttributeAnalyzerTestsTrade-offs
Purely additive — no production code changes, no new dependencies.
Test Status
All 31/31 tests pass (
net8.0,Debug):Reproducibility
Add this agentic workflows to your repo
To install this agentic workflow, run
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/global-fixture-duplicate-attribute-edge-cases-1778338e6c1a574c.[Click here to create the pull request](https://github.com/microsoft/testfx/compare/main...test-assist/global-fixture-duplicate-attribute-edge-cases-1778338e6c1a574c?expand=1&title=%5Btest-improver%5D%20test%3A%20add%20edge%20case%20tests%20for%20GlobalTestFixtureShouldBeValidAnalyzer%20(MSTEST0050)%20and%20DuplicateTestMethodAttributeAnalyzer%20(MSTE%0A%5BContent%20truncated%20due%20to%20length%5D)
To fix the permissions issue, go to Settings → Actions → General and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ
Show patch preview (173 of 173 lines)