Skip to content

Cover the fixture-scope branches of MSTEST0075 - #10383

Merged
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/test-improver-analyzer-edge-cases
Aug 3, 2026
Merged

Cover the fixture-scope branches of MSTEST0075#10383
Amaury Levé (Evangelink) merged 1 commit into
mainfrom
dev/amauryleve/test-improver-analyzer-edge-cases

Conversation

@Evangelink

@Evangelink Amaury Levé (Evangelink) commented Aug 2, 2026

Copy link
Copy Markdown
Member

Closes #10349
Closes #10369

(#10349 and #10369 are duplicates of each other — the test-improver workflow filed the same gap twice.)

What this covers

CurrentDirectoryMutationUnderParallelizationAnalyzer decides, per enclosing method, whether to report a current-directory mutation and — if so — where AddResourceLockFixer may place [ResourceLock]. That yields three distinct outcomes, and this file covered none of them: every pre-existing test here pins the plain test-method case.

New test Enclosing method Outcome
WhenTestInitializeSetsCurrentDirectoryViaDirectory_Diagnostic [TestInitialize] Reported; fix placed on the class
WhenAssemblyInitializeSetsCurrentDirectoryViaDirectory_NoDiagnostic [AssemblyInitialize] Silent
WhenGlobalTestInitializeSetsCurrentDirectoryViaDirectory_DiagnosticWithoutFix [GlobalTestInitialize] Reported; no fix offered

Notes on each:

  • [TestInitialize] is a class-scoped fixture, so a [ResourceLock] on the fixture method itself would be ignored — discovery reads locks only from the test class and the test method. The test asserts the fixer's class-scope placement, which is the first class-scope fix assertion in this file. (The sibling CultureMutationUnderParallelizationAnalyzerTests only calls VerifyAnalyzerAsync, so it cannot pin this at all.)
  • [AssemblyInitialize] is serialized ahead of every worker, so it cannot race a concurrent test — flagging it would be a false positive.
  • [GlobalTestInitialize] genuinely races, but a global fixture has no effective lock target: the enclosing class is not one, because locking it would serialize only that class's tests while the fixture kept racing the tests of every other class. So the analyzer reports without offering a fix. This third branch had no coverage in any of the three parallel-safety analyzer test files.

Mutation-verified

These are not decorative — each was checked by breaking the analyzer and confirming exactly one test caught it, with no pre-existing test in the repo noticing:

Injected regression Result
Add AssemblyInitializeAttribute to GetFixtureAttributeSymbols only the [AssemblyInitialize] test fails
Add GlobalTestInitializeAttribute to GetClassScopedFixtureAttributeSymbols only the [GlobalTestInitialize] test fails

The second is the interesting one: that regression would make the fixer emit a class-level [ResourceLock] that does nothing at run time, and before this PR nothing would have caught it.

Validation

Full MSTest.Analyzers.UnitTests suite: net8.0 1688/1688, net472 1632/1632. Build clean, 0 warnings. No production code changed.


The MSTEST0081 half of this backlog is split out into #10386, since it covers a different analyzer and issue.

Copilot AI review requested due to automatic review settings August 2, 2026 22:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds analyzer edge-case coverage for MSTEST0075 and MSTEST0081 without changing production code.

Changes:

  • Tests fixture-method handling and code-fix placement for current-directory mutations.
  • Tests duplicate generic and non-generic filter-provider registrations, including CS0579 behavior.
Show a summary per file
File Description
CurrentDirectoryMutationUnderParallelizationAnalyzerTests.cs Covers test and assembly initialization scenarios.
TestFilterProviderShouldBeValidAnalyzerTests.cs Covers same-shape duplicate provider registrations.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Balanced

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

Summary

This PR adds well-crafted edge-case tests for two analyzers (MSTEST0075 and MSTEST0081), closing three backlog items. No production code is changed.

Review

✅ No issues found. This is a clean, test-only PR that strengthens analyzer coverage.

Highlights

Dimension Assessment
Correctness ✅ Tests correctly exercise the fixture hierarchy ([TestInitialize] → diagnostic, [AssemblyInitialize] → no diagnostic) and the AllowMultiple = false CS0579 interaction
Completeness ✅ Code fix assertion included for the diagnostic case; both TFMs validated; #if NET guard correctly scopes the generic-attribute test
Naming & readability ✅ Method names follow the When..._Outcome convention; inline comments explain why each expectation holds
Test quality ✅ No flakiness vectors; assertions are specific (rule + location + arguments); no over-assertion
Style ✅ Consistent with sibling test files; no trailing whitespace; file ends with newline
Public API ✅ N/A — no production changes
Security ✅ N/A

Minor observation (non-blocking)

The "/tmp" literal in the test snippets is fine for Roslyn in-memory compilation (no real I/O), but if future tests ever execute these snippets end-to-end, a platform-neutral path would be safer. Not actionable here.

Verdict: No changes requested. Ship it. 🚀

@github-actions

This comment has been minimized.

CurrentDirectoryMutationUnderParallelizationAnalyzer decides per enclosing
method whether to report a current-directory mutation and, if so, where the
AddResourceLockFixer may place [ResourceLock]. That produces three outcomes,
none of which had coverage in this file - every existing test here pins the
plain test-method case.

Add one test per outcome:

- WhenTestInitializeSetsCurrentDirectoryViaDirectory_Diagnostic - [TestInitialize]
  is a class-scoped fixture, so the mutation is reported and the fix is placed on
  the *class*, which is where discovery reads resource locks from. This is the
  first class-scope fix assertion in this file.
- WhenAssemblyInitializeSetsCurrentDirectoryViaDirectory_NoDiagnostic -
  [AssemblyInitialize] is serialized ahead of every worker, so it cannot race a
  concurrent test and must stay silent.
- WhenGlobalTestInitializeSetsCurrentDirectoryViaDirectory_DiagnosticWithoutFix -
  [GlobalTestInitialize] genuinely races, but a global fixture has no effective
  lock target (the enclosing class is not one, since locking it would serialize
  only that class's tests while the fixture kept racing every other class), so
  the analyzer reports without offering a fix.

All three are mutation-sensitive: adding AssemblyInitialize to
GetFixtureAttributeSymbols, or GlobalTestInitialize to
GetClassScopedFixtureAttributeSymbols, each fails exactly one of them, and no
pre-existing test in the repo notices either regression.

Closes #10349
Closes #10369

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 38d37b0e-1f72-43cd-923a-1733b2964873
@Evangelink
Amaury Levé (Evangelink) force-pushed the dev/amauryleve/test-improver-analyzer-edge-cases branch from d3bd100 to 4f75f2d Compare August 2, 2026 23:17
Copilot AI review requested due to automatic review settings August 2, 2026 23:17
@Evangelink Amaury Levé (Evangelink) changed the title Add analyzer edge-case tests from the test-improver backlog Cover the fixture-scope branches of MSTEST0075 Aug 2, 2026
@Evangelink
Amaury Levé (Evangelink) enabled auto-merge (squash) August 2, 2026 23:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 1/1 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@Evangelink Amaury Levé (Evangelink) added the state/needs-review Awaiting review from the team. label Aug 2, 2026
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

🧪 Test quality grade — PR #10383

GradeTestMutationNotesHow to improve
A (90–100) new CurrentDirectoryMutationUnderParallelizationAnalyzerTests.
WhenTestInitializeSetsCurrentDirectoryViaDirectory_
Diagnostic
4/4 killed VerifyCodeFixAsync checks diagnostic location, argument, and full code transformation to class-level ResourceLock.
A (90–100) new CurrentDirectoryMutationUnderParallelizationAnalyzerTests.
WhenAssemblyInitializeSetsCurrentDirectoryViaDirectory_
NoDiagnostic
3/3 killed Negative test with clear rationale; VerifyCodeFixAsync(code, code) asserts no diagnostic and no code change.
A (90–100) new CurrentDirectoryMutationUnderParallelizationAnalyzerTests.
WhenGlobalTestInitializeSetsCurrentDirectoryViaDirectory_
DiagnosticWithoutFix
3/3 killed Pins the third branch (report, no fix); third VerifyCodeFixAsync arg == code asserts fixer is intentionally absent.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Re-run with /grade-tests.

🤖 Automated content by GitHub Copilot. Generated by the Grade Tests on PR (on open / sync) workflow. · sonnet46 51.9 AIC · ⌖ 6.84 AIC · ⊞ 11.8K · [◷]( · )

@Evangelink
Amaury Levé (Evangelink) merged commit d28ae33 into main Aug 3, 2026
33 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/test-improver-analyzer-edge-cases branch August 3, 2026 08:19
github-actions Bot added a commit that referenced this pull request Aug 5, 2026
Fills the 'diagnostic without fix' branch gap for global fixtures in
UndeclaredProcessGlobalStateMutationAnalyzer (MSTEST0074) and
CultureMutationUnderParallelizationAnalyzer (MSTEST0076), mirroring the
GlobalTestInitialize coverage already present in
CurrentDirectoryMutationUnderParallelizationAnalyzerTests.cs (MSTEST0075,
PR #10383).

[GlobalTestInitialize] is present in GetFixtureAttributeSymbols but absent
from GetClassScopedFixtureAttributeSymbols, so GetResourceLockFixScope
returns null and no fix is offered even though the diagnostic still fires.
Neither analyzer's test file previously exercised this branch.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-review Awaiting review from the team.

Projects

None yet

3 participants