Fix MSTEST0063 to detect invalid constructors on derived TestClass attributes - #9851
Conversation
…tributes TestClassConstructorShouldBeValidAnalyzer used an exact-match check (SymbolEqualityComparer.Default.Equals) for TestClassAttribute, so derived attributes like [STATestClass] or custom [MyTestClass] were silently skipped. MSTest discovers such classes at runtime via Inherits() logic, so a private/internal constructor causes a runtime failure but no analyzer warning. Switch the guard to IsTestClass() (which uses Inherits()) to match the runtime discovery logic, and add four tests covering derived and custom TestClass attributes. Fixes #9836 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: d1590213-39c9-4b3d-9fa4-1d10ac4961cc
There was a problem hiding this comment.
Pull request overview
Updates MSTEST0063 to validate constructors on classes using derived TestClassAttribute types.
Changes:
- Uses the shared inheritance-aware
IsTestClass()helper. - Adds coverage for built-in and custom derived attributes.
Show a summary per file
| File | Description |
|---|---|
TestClassConstructorShouldBeValidAnalyzer.cs |
Enables derived test-class attribute detection. |
TestClassConstructorShouldBeValidAnalyzerTests.cs |
Tests valid and invalid constructor scenarios. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Medium
There was a problem hiding this comment.
Clean fix. The IsTestClass helper (via Inherits) correctly walks the attribute type hierarchy, which is exactly what was missing with the old SymbolEqualityComparer.Default.Equals exact-match check. This is consistent with how other analyzers (TestClassShouldHaveTestMethodAnalyzer, PublicMethodShouldBeTestMethodAnalyzer, etc.) already guard their IsTestClass checks.
Tests cover both [STATestClass] (built-in derived) and a custom derived attribute, with positive and negative cases. No issues found.
🧪 Test quality grade — PR #9851
This advisory comment was generated automatically. Grades are heuristic
|
🔴 Build Failure AnalysisBuild: FAILED (236.6s) · 5 errors · 1 warning Root CauseAll 4 compilation errors are the same issue — analyzer rule CA1416 (platform compatibility) on two call sites in
(Each error is reported twice — once per TFM.) The interface method Suggested FixAdd
|
There was a problem hiding this comment.
🤖 Automated content by GitHub Copilot. Generated by the Build Failure Analysis workflow. · 45.4 AIC · ⌖ 5.79 AIC · ⊞ 7.3K · ◷
|
The CA1416 build failure is a pre-existing issue in It's being handled separately (branch |
|
/backport to rel/4.3 |
|
Started backporting to rel/4.3: https://github.com/microsoft/testfx/actions/runs/29831582249 |
…tributes by @Evangelink in #9851 (backport to rel/4.3) (#10115) Co-authored-by: Amaury Levé <amauryleve@microsoft.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes #9836
Problem
TestClassConstructorShouldBeValidAnalyzer(MSTEST0063) validates that[TestClass]-decorated classes have a public parameterless constructor or a publicTestContext-parameter constructor.The guard in
AnalyzeSymbolused an exact-match check (SymbolEqualityComparer.Default.Equals) againstTestClassAttribute, so classes decorated with derived test-class attributes — including the built-in[STATestClass]and any customclass MyAttr : TestClassAttribute— were silently skipped. Because MSTest discovers such classes at runtime viaInherits()logic, a private/internal constructor causes a runtime instantiation failure with no analyzer warning.Fix
Replace the exact-match guard with the shared
IsTestClass()helper, which callsInherits()and matches the runtime discovery behavior:Tests
Four new tests added to
TestClassConstructorShouldBeValidAnalyzerTests.cs:[STATestClass]+ private constructor[STATestClass]+ public parameterless constructorTrade-offs
This is a behavior change: previously, classes with derived
[TestClass]attributes and invalid constructors produced no warning; after this fix they do. This is the correct behavior — the fix brings the analyzer in line with MSTest's runtime class-discovery logic.Build and
MSTest.Analyzers.UnitTests(net472 + net8.0) pass locally.