[SDTEST-3812] Dedupe duplicate .datadogTesting trait on nested suites#262
Merged
Merged
Conversation
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]>
anmarchenko
approved these changes
May 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@Suitecarry.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).TestIDin a@TaskLocal(lastTestTraitApplied); whenprovideScope(for:testCase:)is re-entered for the sameTestID, short-circuit tofunction()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.Testing.Test.Case.ID,Test.Case.Argument,Test.Parameter, andTesting.TypeInfoare all marked@_spi(ForToolsIntegrationOnly)and can't be referenced directly. AddedMirror-based accessors onTesting.Test.Case(ddArgumentIDs,ddDiscriminator,ddIsStable,ddID,ddArguments) that reach the same(arguments, discriminator, isStable)triple Swift Testing uses forTest.Case.ID, plusDDArgument(value, name, type)for parameter formatting.SwiftTestRun.parametersnow readsvalue/name/typefrom the Mirror data, replacing the regex parser onString(describing: testCase). The standaloneSwiftTestRunParametersParserTestsare removed — they tested the deleted parser; the end-to-end coverage now lives intestParameterized.Closes SDTEST-3812 / #257.
Test plan
xcodebuild -scheme DatadogSDKTesting -destination 'platform=macOS,arch=arm64' test— 22 tests, 7 suites pass.DDNestedAnnotatedSuiteTestsfails onmain(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 theTestID-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.Stringwith reflection-quoted string values).🤖 Generated with Claude Code