diff --git a/Sources/Testing/Traits/ParallelizationTrait.swift b/Sources/Testing/Traits/ParallelizationTrait.swift index 9eb1bd2a5..c91e01761 100644 --- a/Sources/Testing/Traits/ParallelizationTrait.swift +++ b/Sources/Testing/Traits/ParallelizationTrait.swift @@ -31,6 +31,14 @@ public struct ParallelizationTrait: TestTrait, SuiteTrait {} // MARK: - TestScoping extension ParallelizationTrait: TestScoping { + public func scopeProvider(for test: Test, testCase: Test.Case?) -> Self? { + // When applied to a test function, this trait should provide scope to the + // test function itself, not its individual test cases, since that allows + // Runner to correctly interpret the configuration setting to disable + // parallelization. + test.isSuite || testCase == nil ? self : nil + } + public func provideScope(for test: Test, testCase: Test.Case?, performing function: @Sendable () async throws -> Void) async throws { guard var configuration = Configuration.current else { throw SystemError(description: "There is no current Configuration when attempting to provide scope for test '\(test.name)'. Please file a bug report at https://github.com/swiftlang/swift-testing/issues/new") diff --git a/Tests/TestingTests/TestSupport/TestingAdditions.swift b/Tests/TestingTests/TestSupport/TestingAdditions.swift index 4648f96af..5c596785e 100644 --- a/Tests/TestingTests/TestSupport/TestingAdditions.swift +++ b/Tests/TestingTests/TestSupport/TestingAdditions.swift @@ -103,6 +103,25 @@ extension Runner { /// - fileID: The `#fileID` string whose module should be used to locate /// the test function to run. /// - configuration: The configuration to use for running. + init( + selecting testName: String, + inModuleOf fileID: String = #fileID, + configuration: Configuration = .init() + ) async { + let plan = await Runner.Plan(selecting: testName, inModuleOf: fileID, configuration: configuration) + self.init(plan: plan, configuration: configuration) + } +} + +extension Runner.Plan { + /// Initialize an instance of this type that selects the free test function + /// named `testName` in the module specified in `fileID`. + /// + /// - Parameters: + /// - testName: The name of the test function this instance should run. + /// - fileID: The `#fileID` string whose module should be used to locate + /// the test function to run. + /// - configuration: The configuration to use for running. init( selecting testName: String, inModuleOf fileID: String = #fileID, @@ -116,9 +135,7 @@ extension Runner { await self.init(configuration: configuration) } -} -extension Runner.Plan { /// Initialize an instance of this type with the specified suite type. /// /// - Parameters: diff --git a/Tests/TestingTests/Traits/ParallelizationTraitTests.swift b/Tests/TestingTests/Traits/ParallelizationTraitTests.swift index 776e5c320..6c4963dc5 100644 --- a/Tests/TestingTests/Traits/ParallelizationTraitTests.swift +++ b/Tests/TestingTests/Traits/ParallelizationTraitTests.swift @@ -12,8 +12,11 @@ @Suite("Parallelization Trait Tests", .tags(.traitRelated)) struct ParallelizationTraitTests { - @Test(".serialized trait serializes parameterized test") - func serializesParameterizedTestFunction() async { + @Test(".serialized trait serializes parameterized test", arguments: await [ + Runner.Plan(selecting: OuterSuite.self), + Runner.Plan(selecting: "globalParameterized(i:)"), + ]) + func serializesParameterizedTestFunction(plan: Runner.Plan) async { var configuration = Configuration() configuration.isParallelizationEnabled = true @@ -33,7 +36,6 @@ struct ParallelizationTraitTests { } } - let plan = await Runner.Plan(selecting: OuterSuite.self, configuration: configuration) let runner = Runner(plan: plan, configuration: configuration) await runner.run() @@ -59,3 +61,8 @@ private struct OuterSuite { } } } + +@Test(.hidden, .serialized, arguments: 0 ..< 10_000) +private func globalParameterized(i: Int) { + Issue.record("PARAMETERIZED\(i)") +}