Skip to content

Support class-level [Retry] attribute (#7556)#8566

Merged
Evangelink merged 2 commits into
mainfrom
dev/amauryleve/issue-7556-retry-class-support
May 25, 2026
Merged

Support class-level [Retry] attribute (#7556)#8566
Evangelink merged 2 commits into
mainfrom
dev/amauryleve/issue-7556-retry-class-support

Conversation

@Evangelink
Copy link
Copy Markdown
Member

Resolves #7556.

Summary

Adds support for decorating [TestClass] types with [Retry(N)] (or any RetryBaseAttribute-derived attribute). When a class-level retry is present, every test method in the class retries on failure with the specified count. A method-level retry attribute, when present, fully overrides the class-level one (smaller, equal or larger).

Assembly-level retry is intentionally out of scope here (the user only asked for classes, and assembly-level retry is already supported via Microsoft.Testing.Extensions.Retry for MTP users).

Behavior

Class-level Method-level Effective
- [Retry(N)] [Retry(N)] (existing)
[Retry(N)] - [Retry(N)] (new)
[Retry(N)] [Retry(M)] [Retry(M)] (method wins)
2+ at class any throws TypeInspectionException (new message UTA_MultipleAttributesOnTestClass)
any 2+ at method throws TypeInspectionException (existing message)

Class-level duplicates are always validated, even when a method-level override is present, so misuse on the test class is never silenced.

RetryAttribute/RetryBaseAttribute keep Inherited = false — base-class retry does not flow to a derived test class. There is a regression test for this.

Changes

  • RetryBaseAttribute/RetryAttribute: AttributeUsage extended to Method | Class; added remarks doc explaining override semantics.
  • TestMethodInfo.GetRetryAttribute: rewritten to walk method then class attributes via a shared GetSingleRetryAttribute helper.
  • Resource.resx: new UTA_MultipleAttributesOnTestClass entry (xlf regenerated).
  • UseRetryWithTestMethodAnalyzer (MSTEST0035): now also registers SymbolKind.NamedType and flags [Retry] on non-test classes; diagnostic text updated to mention test classes (xlf regenerated).

Tests

  • TestMethodInfoTests: 6 new unit tests covering class-level pickup, method-overrides-class (both larger and smaller), non-inheritance from a base class, and class-level duplicate validation (with and without a method-level override).
  • UseRetryWithTestMethodAnalyzerTests: 3 new tests covering [TestClass][Retry], [Retry] on non-test class, and custom-derived TestClassAttribute.
  • RetryTests (acceptance): new ClassLevelRetryTests end-to-end scenario exercising class-level retry plus per-method override.

Resolves #7556.

- Extend RetryAttribute / RetryBaseAttribute targets to include classes (Inherited = false, AllowMultiple = false).

- TestMethodInfo now resolves retry from method first, then declaring class. Method-level retry fully overrides class-level. Multiple retry attributes at either level still throw TypeInspectionException.

- New resource UTA_MultipleAttributesOnTestClass with localized xlf entries.

- Update MSTEST0035 analyzer to also flag [Retry] on non-test classes; updated diagnostic text to mention test classes.

- New unit tests in TestMethodInfoTests, UseRetryWithTestMethodAnalyzerTests and a new acceptance test ClassLevelRetryTests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 25, 2026 13:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds MSTest support for applying [Retry] (or any RetryBaseAttribute-derived attribute) at the test-class level, making it the default for all test methods in that class while allowing method-level [Retry] to fully override it. This spans the MSTest framework attribute definitions, adapter execution-time resolution/validation, analyzer guidance, and unit + acceptance test coverage.

Changes:

  • Extend RetryBaseAttribute/RetryAttribute to allow AttributeTargets.Class and document class-vs-method override semantics.
  • Update adapter execution (TestMethodInfo) to resolve retry from method first, then class, and add a dedicated error for multiple class-level retry attributes.
  • Update MSTEST0035 analyzer/resources to allow [Retry] on test classes (and keep flagging invalid usages), with new unit and acceptance tests.
Show a summary per file
File Description
test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Execution/TestMethodInfoTests.cs Adds unit tests covering class-level retry resolution, method override semantics, non-inheritance, and duplicate class-level validation.
test/UnitTests/MSTest.Analyzers.UnitTests/UseRetryWithTestMethodAnalyzerTests.cs Adds analyzer tests for [Retry] on [TestClass], non-test classes, and custom TestClassAttribute derivations.
test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RetryTests.cs Adds end-to-end acceptance scenario verifying class-level retry applies and method-level retry overrides.
src/TestFramework/TestFramework/Attributes/TestMethod/RetryBaseAttribute.cs Allows class-level usage and documents precedence/non-inheritance behavior.
src/TestFramework/TestFramework/Attributes/TestMethod/RetryAttribute.cs Allows class-level usage and documents full override semantics and non-inheritance.
src/Analyzers/MSTest.Analyzers/UseRetryWithTestMethodAnalyzer.cs Extends MSTEST0035 to also analyze types, permitting retry on test classes while flagging non-test types/methods.
src/Analyzers/MSTest.Analyzers/Resources.resx Updates analyzer title/message to include “test method or test class”.
src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf Updates localized resource entry metadata for changed analyzer strings.
src/Adapter/MSTestAdapter.PlatformServices/Resources/Resource.resx Adds new adapter resource string for multiple class-level retry attributes.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.zh-Hant.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.zh-Hans.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.tr.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.ru.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.pt-BR.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.pl.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.ko.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.ja.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.it.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.fr.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.es.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.de.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Resources/xlf/Resource.cs.xlf Adds new localized resource entry for class-level duplicate retry attribute error.
src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodInfo.Execution.cs Adds a dedicated exception helper for multiple class-level retry attributes.
src/Adapter/MSTestAdapter.PlatformServices/Execution/TestMethodInfo.cs Updates retry attribute resolution to consider method then class, validating duplicates at both levels.

Copilot's findings

  • Files reviewed: 36/36 changed files
  • Comments generated: 0

Copy link
Copy Markdown
Member Author

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

Review Summary

19/21 dimensions clean — 2 dimensions with findings (all NITs).

# Dimension Verdict
17 Documentation Accuracy 🟢 2 NIT
15 Code Structure & Simplification 🟢 1 NIT

Clean Dimensions (19/21)

All other dimensions passed review:

  • Algorithmic Correctness: Logic correctly implements method-overrides-class semantics with proper validation of both levels
  • Threading & Concurrency: No shared mutable state; uses cached reflection appropriately
  • Public API & Binary Compatibility: Extends AttributeUsage on existing attributes (additive change); no breaking changes; XML docs added
  • Performance: Uses GetCustomAttributesCached consistently; no hot-path regressions
  • Cross-TFM Compatibility: No TFM-specific code; uses standard reflection APIs
  • Resource Management: No new disposable resources introduced
  • Defensive Coding: Validates duplicate class-level attributes even when method-level override exists (prevents silent misuse)
  • Localization: New resource string UTA_MultipleAttributesOnTestClass properly added to .resx; .xlf files regenerated correctly
  • Test Isolation: Tests use independent test classes with no shared static state
  • Assertion Quality: Tests verify exact behavior (4 runs for class-level retry, 2 runs for method override)
  • Test Completeness: 6 new unit tests cover class-level pickup, override (larger/smaller), non-inheritance, duplicate validation (with/without method override); 1 new acceptance test verifies end-to-end scenario
  • Analyzer Quality: UseRetryWithTestMethodAnalyzer correctly extended to validate [Retry] on test classes and flag non-test classes; 3 new analyzer tests cover the new scenarios
  • Security: No security-relevant changes
  • Flakiness Patterns: No timing dependencies or shared state
  • Data-Driven Test Coverage: N/A
  • Naming & Conventions: Consistent with codebase conventions
  • IPC Wire Compatibility: N/A
  • Build Infrastructure: N/A
  • Scope & PR Discipline: Single concern (class-level retry); well-scoped

Findings Detail

Documentation Accuracy (2 NITs)

  • Inline comment would clarify ?? operator precedence semantics (line 199)
  • XML doc on GetSingleRetryAttribute could be clearer about error-throwing purpose

Code Structure (1 NIT)

  • isClassLevel parameter could be renamed or replaced with enum for clarity (line 201)

Verdict

All findings are NITs — no blocking or major issues. The implementation is correct, well-tested, and follows MSTest conventions. The PR is ready to merge after addressing the nit-level documentation/readability suggestions if desired.

Great work on the comprehensive test coverage and thoughtful handling of the edge cases (duplicate validation even with method override, non-inheritance verification)! 🎉

Generated by Expert Code Review (on open) for issue #8566 · ● 1.6M

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink merged commit 97c5565 into main May 25, 2026
39 checks passed
@Evangelink Evangelink deleted the dev/amauryleve/issue-7556-retry-class-support branch May 25, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RetryAttribute to support decoration of class and/or assembly

2 participants