From 1e227131f5fd77ea337b760f45f47cf2fbf8275d Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Wed, 28 May 2025 15:58:35 -0500 Subject: [PATCH 1/3] Expand parameterized testing documentation to mention try/await support and showcase helper pattern Fixes rdar://130929060 --- Sources/Testing/Test+Macro.swift | 32 +++++++++++++------ .../Testing.docc/ParameterizedTesting.md | 31 ++++++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Sources/Testing/Test+Macro.swift b/Sources/Testing/Test+Macro.swift index be0b5a91b..2ca599956 100644 --- a/Sources/Testing/Test+Macro.swift +++ b/Sources/Testing/Test+Macro.swift @@ -217,8 +217,10 @@ public macro Test( /// - collection: A collection of values to pass to the associated test /// function. /// -/// During testing, the associated test function is called once for each element -/// in `collection`. +/// The expression passed to `collection` may be prefixed with `try` or `await`, +/// and is lazily evaluated only if the testing library determines that the +/// associated test will run. During testing, the associated test function is +/// called once for each element in `collection`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -270,8 +272,11 @@ extension Test { /// - collection1: A collection of values to pass to `testFunction`. /// - collection2: A second collection of values to pass to `testFunction`. /// -/// During testing, the associated test function is called once for each pair of -/// elements in `collection1` and `collection2`. +/// The expressions passed to `collection1` and `collection2` may be prefixed +/// with `try` or `await`, and are lazily evaluated only if the testing library +/// determines that the associated test will run. During testing, the associated +/// test function is called once for each pair of elements in `collection1` and +/// `collection2`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -298,8 +303,11 @@ public macro Test( /// - collection1: A collection of values to pass to `testFunction`. /// - collection2: A second collection of values to pass to `testFunction`. /// -/// During testing, the associated test function is called once for each pair of -/// elements in `collection1` and `collection2`. +/// The expressions passed to `collection1` and `collection2` may be prefixed +/// with `try` or `await`, and are lazily evaluated only if the testing library +/// determines that the associated test will run. During testing, the associated +/// test function is called once for each pair of elements in `collection1` and +/// `collection2`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -324,8 +332,10 @@ public macro Test( /// - zippedCollections: Two zipped collections of values to pass to /// `testFunction`. /// -/// During testing, the associated test function is called once for each element -/// in `zippedCollections`. +/// The expression passed to `zippedCollections` may be prefixed with `try` or +/// `await`, and is lazily evaluated only if the testing library determines that +/// the associated test will run. During testing, the associated test function +/// is called once for each element in `zippedCollections`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -352,8 +362,10 @@ public macro Test( /// - zippedCollections: Two zipped collections of values to pass to /// `testFunction`. /// -/// During testing, the associated test function is called once for each element -/// in `zippedCollections`. +/// The expression passed to `zippedCollections` may be prefixed with `try` or +/// `await`, and is lazily evaluated only if the testing library determines that +/// the associated test will run. During testing, the associated test function +/// is called once for each element in `zippedCollections`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. diff --git a/Sources/Testing/Testing.docc/ParameterizedTesting.md b/Sources/Testing/Testing.docc/ParameterizedTesting.md index c4310e8e6..46c012fa4 100644 --- a/Sources/Testing/Testing.docc/ParameterizedTesting.md +++ b/Sources/Testing/Testing.docc/ParameterizedTesting.md @@ -101,6 +101,37 @@ func makeLargeOrder(count: Int) async throws { - Note: Very large ranges such as `0 ..< .max` may take an excessive amount of time to test, or may never complete due to resource constraints. +### Pass the same arguments to multiple test functions + +If you want to pass the same collection of arguments to two or more +parameterized test functions, you can extract the arguments to a separate +function or property and call it from each `@Test` macro. For example: + +```swift +extension Food { + static var bestSelling: [Food] { + get async throws { /* ... */ } + } +} + +@Test(arguments: try await Food.bestSelling) +func orderEntree(food: Food) { + let foodTruck = FoodTruck() + #expect(foodTruck.order(food)) +} + +@Test(arguments: try await Food.bestSelling) +func packageLeftovers(food: Food) throws { + let foodTruck = FoodTruck() + let container = try #require(foodTruck.container(fitting: food)) + try container.add(food) +} +``` + +> Tip: Expressions passed to `arguments:` can be prefixed with `try` or `await` +> and are lazily evaluated only if the testing library determines that the +> associated test will run. + ### Test with more than one collection It's possible to test more than one collection. Consider the following test From de2cd442b3d1068321eff4cda1191b4b6d294786 Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Thu, 29 May 2025 15:19:38 -0500 Subject: [PATCH 2/3] Stylistic updates from PR review --- Sources/Testing/Test+Macro.swift | 46 ++++++++++--------- .../Testing.docc/ParameterizedTesting.md | 4 +- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Sources/Testing/Test+Macro.swift b/Sources/Testing/Test+Macro.swift index 2ca599956..44e9d3d72 100644 --- a/Sources/Testing/Test+Macro.swift +++ b/Sources/Testing/Test+Macro.swift @@ -217,10 +217,10 @@ public macro Test( /// - collection: A collection of values to pass to the associated test /// function. /// -/// The expression passed to `collection` may be prefixed with `try` or `await`, -/// and is lazily evaluated only if the testing library determines that the -/// associated test will run. During testing, the associated test function is -/// called once for each element in `collection`. +/// You can prefix the expression you pass to `collection` with `try` or `await`. +/// The testing library evaluates the expression lazily only if it determines +/// that the associated test will run. During testing, the testing library calls +/// the associated test function once for each element in `collection`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -272,11 +272,11 @@ extension Test { /// - collection1: A collection of values to pass to `testFunction`. /// - collection2: A second collection of values to pass to `testFunction`. /// -/// The expressions passed to `collection1` and `collection2` may be prefixed -/// with `try` or `await`, and are lazily evaluated only if the testing library -/// determines that the associated test will run. During testing, the associated -/// test function is called once for each pair of elements in `collection1` and -/// `collection2`. +/// You can prefix the expressions you pass to `collection1` or `collection2` +/// with `try` or `await`. The testing library evaluates the expressions lazily +/// only if it determines that the associated test will run. During testing, the +/// testing library calls the associated test function once for each pair of +/// elements in `collection1` and `collection2`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -303,11 +303,11 @@ public macro Test( /// - collection1: A collection of values to pass to `testFunction`. /// - collection2: A second collection of values to pass to `testFunction`. /// -/// The expressions passed to `collection1` and `collection2` may be prefixed -/// with `try` or `await`, and are lazily evaluated only if the testing library -/// determines that the associated test will run. During testing, the associated -/// test function is called once for each pair of elements in `collection1` and -/// `collection2`. +/// You can prefix the expressions you pass to `collection1` or `collection2` +/// with `try` or `await`. The testing library evaluates the expressions lazily +/// only if it determines that the associated test will run. During testing, the +/// testing library calls the associated test function once for each pair of +/// elements in `collection1` and `collection2`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -332,10 +332,11 @@ public macro Test( /// - zippedCollections: Two zipped collections of values to pass to /// `testFunction`. /// -/// The expression passed to `zippedCollections` may be prefixed with `try` or -/// `await`, and is lazily evaluated only if the testing library determines that -/// the associated test will run. During testing, the associated test function -/// is called once for each element in `zippedCollections`. +/// You can prefix the expression you pass to `zippedCollections` with `try` or +/// `await`. The testing library evaluates the expression lazily only if it +/// determines that the associated test will run. During testing, the testing +/// library calls the associated test function once for each element in +/// `zippedCollections`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. @@ -362,10 +363,11 @@ public macro Test( /// - zippedCollections: Two zipped collections of values to pass to /// `testFunction`. /// -/// The expression passed to `zippedCollections` may be prefixed with `try` or -/// `await`, and is lazily evaluated only if the testing library determines that -/// the associated test will run. During testing, the associated test function -/// is called once for each element in `zippedCollections`. +/// You can prefix the expression you pass to `zippedCollections` with `try` or +/// `await`. The testing library evaluates the expression lazily only if it +/// determines that the associated test will run. During testing, the testing +/// library calls the associated test function once for each element in +/// `zippedCollections`. /// /// @Comment { /// - Bug: The testing library should support variadic generics. diff --git a/Sources/Testing/Testing.docc/ParameterizedTesting.md b/Sources/Testing/Testing.docc/ParameterizedTesting.md index 46c012fa4..c84be0c14 100644 --- a/Sources/Testing/Testing.docc/ParameterizedTesting.md +++ b/Sources/Testing/Testing.docc/ParameterizedTesting.md @@ -128,8 +128,8 @@ func packageLeftovers(food: Food) throws { } ``` -> Tip: Expressions passed to `arguments:` can be prefixed with `try` or `await` -> and are lazily evaluated only if the testing library determines that the +> Tip: You can prefix expressions passed to `arguments:` with `try` or `await`. +> The testing library evaluates them lazily only if it determines that the > associated test will run. ### Test with more than one collection From 7098aa7d3037d0f580c32bab88454bcbe3d35a57 Mon Sep 17 00:00:00 2001 From: Stuart Montgomery Date: Fri, 30 May 2025 14:20:15 -0500 Subject: [PATCH 3/3] Review feedback --- Sources/Testing/Testing.docc/ParameterizedTesting.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/Testing/Testing.docc/ParameterizedTesting.md b/Sources/Testing/Testing.docc/ParameterizedTesting.md index c84be0c14..2dada707e 100644 --- a/Sources/Testing/Testing.docc/ParameterizedTesting.md +++ b/Sources/Testing/Testing.docc/ParameterizedTesting.md @@ -105,7 +105,7 @@ func makeLargeOrder(count: Int) async throws { If you want to pass the same collection of arguments to two or more parameterized test functions, you can extract the arguments to a separate -function or property and call it from each `@Test` macro. For example: +function or property and pass it to each `@Test` attribute. For example: ```swift extension Food { @@ -115,13 +115,13 @@ extension Food { } @Test(arguments: try await Food.bestSelling) -func orderEntree(food: Food) { +func `Order entree`(food: Food) { let foodTruck = FoodTruck() #expect(foodTruck.order(food)) } @Test(arguments: try await Food.bestSelling) -func packageLeftovers(food: Food) throws { +func `Package leftovers`(food: Food) throws { let foodTruck = FoodTruck() let container = try #require(foodTruck.container(fitting: food)) try container.add(food)