@@ -212,6 +212,14 @@ Below are the proposed interfaces:
212
212
/// A protocol that allows customizing the execution of a test function (and
213
213
/// each of its cases) or a test suite by performing custom code before or after
214
214
/// it runs.
215
+ ///
216
+ /// Types conforming to this protocol may be used in conjunction with a
217
+ /// ``Trait``-conforming type by implementing the
218
+ /// ``Trait/customTestExecutor-1dwpt`` property, allowing custom traits to
219
+ /// customize the execution of tests. Consolidating common set-up and tear-down
220
+ /// logic for tests which have similar needs allows each test function to be
221
+ /// more succinct with less repetitive boilerplate so it can focus on what makes
222
+ /// it unique.
215
223
public protocol CustomTestExecuting : Sendable {
216
224
/// Execute a function for the specified test and/or test case.
217
225
///
@@ -222,20 +230,29 @@ public protocol CustomTestExecuting: Sendable {
222
230
/// test function (including all cases if it is parameterized.)
223
231
/// - test: The test under which `function` is being performed.
224
232
/// - testCase: The test case, if any, under which `function` is being
225
- /// performed. This is `nil` when invoked on a suite.
233
+ /// performed. When invoked on a suite, the value of this argument is
234
+ /// `nil`.
226
235
///
227
236
/// - Throws: Whatever is thrown by `function`, or an error preventing
228
- /// execution from running correctly.
237
+ /// execution from running correctly. An error thrown from this method is
238
+ /// recorded as an issue associated with `test`. If an error is thrown
239
+ /// before `function` is called, the corresponding test will not run.
229
240
///
230
- /// This function is called for each ``Trait`` on a test suite or test
231
- /// function which has a non-`nil` value for ``Trait/customTestExecutor-1dwpt``.
232
- /// It allows additional work to be performed before or after the test runs.
241
+ /// When the testing library is preparing to run a test, it finds all traits
242
+ /// applied to that test (including those inherited from containing suites)
243
+ /// and asks each for the value of its
244
+ /// ``Trait/customTestExecutor-1dwpt`` property. It then calls this method on
245
+ /// all non-`nil` instances, giving each an opportunity to perform
246
+ /// arbitrary work before or after invoking `function`.
233
247
///
234
- /// This function is invoked once for the test its associated trait is applied
248
+ /// This method should either invoke `function` once before returning or throw
249
+ /// an error if it is unable to perform its custom logic successfully.
250
+ ///
251
+ /// This method is invoked once for the test its associated trait is applied
235
252
/// to, and then once for each test case in that test, if applicable. If a
236
- /// test is skipped, this function is not invoked for that test or its cases.
253
+ /// test is skipped, this method is not invoked for that test or its cases.
237
254
///
238
- /// Issues recorded by this function are associated with `test`.
255
+ /// Issues recorded by this method are associated with `test`.
239
256
func execute (_ function : @Sendable () async throws -> Void , for test : Test, testCase : Test.Case? ) async throws
240
257
}
241
258
@@ -244,7 +261,10 @@ public protocol Trait: Sendable {
244
261
245
262
/// The type of the custom test executor for this trait.
246
263
///
247
- /// The default type is `Never`.
264
+ /// The default type is `Never`, which cannot be instantiated. This means the
265
+ /// value of the ``customTestExecutor-1dwpt`` property for all traits with the
266
+ /// default custom executor type is `nil`, meaning such traits will not
267
+ /// perform any custom execution for the tests they're applied to.
248
268
associatedtype CustomTestExecutor : CustomTestExecuting = Never
249
269
250
270
/// The custom test executor for this trait, if any.
@@ -254,30 +274,27 @@ public protocol Trait: Sendable {
254
274
/// test execution. This is the most straightforward way to implement a trait
255
275
/// which customizes the execution of tests.
256
276
///
257
- /// However, if the value of this property is an instance of another type
277
+ /// If the value of this property is an instance of a different type
258
278
/// conforming to ``CustomTestExecuting``, that instance will be used to
259
- /// perform custom test execution instead. Otherwise, the default value of
260
- /// this property is `nil` (with the default type `Never?`), meaning that
261
- /// custom test execution will not be performed for tests this trait is
262
- /// applied to.
279
+ /// perform custom test execution instead.
280
+ ///
281
+ /// The default value of this property is `nil` (with the default type
282
+ /// `Never?`), meaning that instances of this type will not perform any custom
283
+ /// test execution for tests they are applied to.
263
284
var customTestExecutor: CustomTestExecutor? { get }
264
285
}
265
286
266
- extension Trait {
267
- // ...
268
-
269
- // The default implementation, which returns `nil`.
270
- public var customTestExecutor: CustomTestExecutor? { get }
271
- }
272
-
273
287
extension Trait where CustomTestExecutor == Self {
274
288
// Returns `self`.
275
289
public var customTestExecutor: CustomTestExecutor? { get }
276
290
}
277
291
278
- extension Never : CustomTestExecuting {
279
- public func execute (_ function : @Sendable () async throws -> Void , for test : Test, testCase : Test.Case? ) async throws
292
+ extension Trait where CustomTestExecutor == Never {
293
+ // Returns `nil`.
294
+ public var customTestExecutor: CustomTestExecutor? { get }
280
295
}
296
+
297
+ extension Never : CustomTestExecuting {}
281
298
```
282
299
283
300
Here is a complete example of the usage scenario described earlier, showcasing
0 commit comments