-
Notifications
You must be signed in to change notification settings - Fork 145
Move test repetition down to the test case level #1528
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -333,6 +333,9 @@ public struct __CommandLineArguments_v0: Sendable { | |
| /// The value of the `--repeat-until` argument. | ||
| public var repeatUntil: String? | ||
|
|
||
| /// Whether or not to use the per-test-case repetition mode. | ||
| var usePerTestCaseRepetition: Bool = false | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: Can we include documentation aligning with the other Bool properties in this type? |
||
|
|
||
| /// The value of the `--attachments-path` argument. | ||
| public var attachmentsPath: String? | ||
| } | ||
|
|
@@ -537,6 +540,9 @@ func parseCommandLineArguments(from args: [String]) throws -> __CommandLineArgum | |
| if let repeatUntil = args.argumentValue(forLabel: "--repeat-until") { | ||
| result.repeatUntil = repeatUntil | ||
| } | ||
| if args.contains("--experimental-per-test-case-repetition") { | ||
| result.usePerTestCaseRepetition = true | ||
| } | ||
|
|
||
| return result | ||
| } | ||
|
|
@@ -665,6 +671,9 @@ public func configurationForEntryPoint(from args: __CommandLineArguments_v0) thr | |
| } | ||
| configuration.repetitionPolicy = repetitionPolicy | ||
|
|
||
| // Opt in to per-test-case repetition | ||
| configuration.shouldUseLegacyPlanLevelRepetition = !args.usePerTestCaseRepetition | ||
|
|
||
| #if !SWT_NO_EXIT_TESTS | ||
| // Enable exit test handling via __swiftPMEntryPoint(). | ||
| configuration.exitTestHandler = ExitTest.handlerForEntryPoint() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,6 +132,11 @@ public struct Configuration: Sendable { | |
| } | ||
| } | ||
|
|
||
| /// Whether to perform test repetition at the plan level or on a per-test- | ||
| /// case basis. | ||
| @_spi(Experimental) | ||
| public var shouldUseLegacyPlanLevelRepetition: Bool = true | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's include |
||
|
|
||
| /// Whether or not, and how, to iterate the test plan repeatedly. | ||
| /// | ||
| /// By default, the value of this property allows for a single iteration. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,6 +29,9 @@ extension Runner { | |
| /// The test case that is running on the current task, if any. | ||
| var testCase: Test.Case? | ||
|
|
||
| /// The current iteration of the test repetition policy, if any. | ||
| var iteration: Int? | ||
|
|
||
| /// The runtime state related to the runner running on the current task, | ||
| /// if any. | ||
| @TaskLocal | ||
|
|
@@ -71,15 +74,22 @@ extension Configuration { | |
| /// | ||
| /// - Parameters: | ||
| /// - configuration: The new value to set for ``Configuration/current``. | ||
| /// - addingToAll: Whether to add this configuration to the set of implicitly-tracked ``Configuration``s that are told about detached Issues. | ||
| /// - body: A function to call. | ||
| /// | ||
| /// - Returns: Whatever is returned by `body`. | ||
| /// | ||
| /// - Throws: Whatever is thrown by `body`. | ||
| static func withCurrent<R>(_ configuration: Self, perform body: () throws -> R) rethrows -> R { | ||
| let id = configuration._addToAll() | ||
| static func withCurrent<R>( | ||
| _ configuration: Self, | ||
| addingToAll: Bool = true, | ||
| perform body: () throws -> R | ||
| ) rethrows -> R { | ||
| let id = addingToAll ? configuration._addToAll() : nil | ||
| defer { | ||
| configuration._removeFromAll(identifiedBy: id) | ||
| if let id { | ||
| configuration._removeFromAll(identifiedBy: id) | ||
| } | ||
| } | ||
|
|
||
| var runtimeState = Runner.RuntimeState.current ?? .init() | ||
|
|
@@ -92,15 +102,22 @@ extension Configuration { | |
| /// | ||
| /// - Parameters: | ||
| /// - configuration: The new value to set for ``Configuration/current``. | ||
| /// - addingToAll: Whether to add this configuration to the set of implicitly-tracked ``Configuration``s that are told about detached Issues. | ||
| /// - body: A function to call. | ||
| /// | ||
| /// - Returns: Whatever is returned by `body`. | ||
| /// | ||
| /// - Throws: Whatever is thrown by `body`. | ||
| static func withCurrent<R>(_ configuration: Self, perform body: () async throws -> R) async rethrows -> R { | ||
| let id = configuration._addToAll() | ||
| static func withCurrent<R>( | ||
| _ configuration: Self, | ||
| addingToAll: Bool = true, | ||
| perform body: () async throws -> R | ||
| ) async rethrows -> R { | ||
| let id = addingToAll ? configuration._addToAll() : nil | ||
| defer { | ||
| configuration._removeFromAll(identifiedBy: id) | ||
| if let id { | ||
| configuration._removeFromAll(identifiedBy: id) | ||
| } | ||
| } | ||
|
|
||
| var runtimeState = Runner.RuntimeState.current ?? .init() | ||
|
|
@@ -198,7 +215,7 @@ extension Configuration { | |
| } | ||
| } | ||
|
|
||
| // MARK: - Current test and test case | ||
| // MARK: - Current test, test case, and iteration | ||
|
|
||
| extension Test { | ||
| /// The test that is running on the current task, if any. | ||
|
|
@@ -233,6 +250,28 @@ extension Test { | |
| try await test.withCancellationHandling(body) | ||
| } | ||
| } | ||
|
|
||
| /// The current iteration of the currently-running test case, if any. | ||
| static var currentIteration: Int? { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add documentation for this property? |
||
| Runner.RuntimeState.current?.iteration | ||
| } | ||
|
|
||
| /// Call a function while the value of ``Test/currentIteration`` is set. | ||
| /// | ||
| /// - Parameters: | ||
| /// - iteration: The new value to set for ``Test/currentIteration``. | ||
| /// - body: A function to call. | ||
| /// | ||
| /// - Returns: Whatever is returned by `body`. | ||
| /// | ||
| /// - Throws: Whatever is thrown by `body`. | ||
| static func withCurrentIteration<R>(_ iteration: Int?, perform body: () async throws -> R) async rethrows -> R { | ||
| var runtimeState = Runner.RuntimeState.current ?? .init() | ||
| runtimeState.iteration = iteration | ||
| return try await Runner.RuntimeState.$current.withValue(runtimeState) { | ||
| try await body() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| extension Test.Case { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.