Skip to content

[SDTEST-3812] Dedupe duplicate .datadogTesting trait on nested suites#262

Merged
ypopovych merged 1 commit into
mainfrom
sdtest-3812-dedupe-nested-datadog-testing-trait
May 27, 2026
Merged

[SDTEST-3812] Dedupe duplicate .datadogTesting trait on nested suites#262
ypopovych merged 1 commit into
mainfrom
sdtest-3812-dedupe-nested-datadog-testing-trait

Conversation

@ypopovych

@ypopovych ypopovych commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Bug: when both an outer and a nested @Suite carry .datadogTesting, Swift Testing chains a trait instance per annotation level around the inner scope. Each instance opens its own retry group for the inner tests, producing duplicate test reports in the Datadog UI (issue SwiftTesting with Nested Annotated Suites causes duplicate test report #257).
  • Fix: track the current TestID in a @TaskLocal (lastTestTraitApplied); when provideScope(for:testCase:) is re-entered for the same TestID, short-circuit to function() without opening another scope. Scope provider chains run nested in the same task, so task-locals propagate from the outer trait instance to the inner one.
  • Mirror wrapper: Testing.Test.Case.ID, Test.Case.Argument, Test.Parameter, and Testing.TypeInfo are all marked @_spi(ForToolsIntegrationOnly) and can't be referenced directly. Added Mirror-based accessors on Testing.Test.Case (ddArgumentIDs, ddDiscriminator, ddIsStable, ddID, ddArguments) that reach the same (arguments, discriminator, isStable) triple Swift Testing uses for Test.Case.ID, plus DDArgument(value, name, type) for parameter formatting.
  • Cleanup: SwiftTestRun.parameters now reads value / name / type from the Mirror data, replacing the regex parser on String(describing: testCase). The standalone SwiftTestRunParametersParserTests are removed — they tested the deleted parser; the end-to-end coverage now lives in testParameterized.

Closes SDTEST-3812 / #257.

Test plan

  • xcodebuild -scheme DatadogSDKTesting -destination 'platform=macOS,arch=arm64' test — 22 tests, 7 suites pass.
  • New DDNestedAnnotatedSuiteTests fails on main (status → [pass, pass] == expect.status → [pass]) and passes with the fix — confirmed by reverting the trait change and re-running.
  • DDSuiteNamingTests (nested non-annotated case) still passes — proves the TestID-keyed dedupe doesn't over-skip when only one chained trait instance exists.
  • testParameterized(p1:p2:) exercises the Mirror walk on three distinct parameterized cases and asserts the exact (name, value, type) JSON shape (Swift.Int / Swift.String with reflection-quoted string values).
  • CI green across macOS / iOS / tvOS / watchOS / visionOS unit-test platforms.

🤖 Generated with Claude Code

When both an outer and a nested @suite carried .datadogTesting, Swift
Testing chained a trait instance for each annotation level around the
inner scope. Each instance opened its own retry group for tests in the
inner suite, producing two test runs per test (visible as duplicate
results in the Datadog UI; reported in #257).

Short-circuit duplicate chained trait instances by tracking the current
TestID in a task-local: when provideScope(for:testCase:) sees the same
TestID an outer chained instance already set, pass straight through to
function() without opening a new scope.

TestID is keyed on Testing.Test.ID plus a Mirror-derived shadow of
Testing.Test.Case.ID (argumentIDs / discriminator / isStable). The
SPI-marked Test.Case.ID, Test.Case.Argument, Test.Parameter, and
TypeInfo cannot be referenced directly, so this commit also adds
Mirror-based accessors on Testing.Test.Case (ddArgumentIDs, ddArguments,
ddDiscriminator, ddIsStable, ddID). SwiftTestRun.parameters now reads
argument value / name / type from the Mirror data, replacing the
regex-on-String(describing:) parser (and its tests).

Regression coverage: DDNestedAnnotatedSuiteTests verifies a nested
annotated suite reports its inner test exactly once. testParameterized
remains the canary for the Mirror walk on parameterized cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@ypopovych
ypopovych requested review from a team as code owners May 26, 2026 20:13
@ypopovych
ypopovych merged commit e5e3555 into main May 27, 2026
12 checks passed
@ypopovych
ypopovych deleted the sdtest-3812-dedupe-nested-datadog-testing-trait branch May 27, 2026 09:35
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.

2 participants