@@ -240,62 +240,69 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
240
240
_ = try ? localFileSystem. removeFileTree ( buildParameters. testOutputPath)
241
241
}
242
242
243
- if !self . options. shouldRunInParallel {
244
- if options. testLibraryOptions. enableXCTestSupport {
243
+ var ranSuccessfully = true
244
+
245
+ // Run XCTest.
246
+ if options. testLibraryOptions. enableXCTestSupport {
247
+ if !self . options. shouldRunInParallel {
245
248
let xctestArgs = try xctestArgs ( for: testProducts, swiftCommandState: swiftCommandState)
246
- try await runTestProducts (
249
+ ranSuccessfully = try await runTestProducts (
247
250
testProducts,
248
251
additionalArguments: xctestArgs,
249
252
productsBuildParameters: buildParameters,
250
253
swiftCommandState: swiftCommandState,
251
254
library: . xctest
252
- )
253
- }
254
- if options. testLibraryOptions. enableSwiftTestingLibrarySupport {
255
- try await runTestProducts (
256
- testProducts,
257
- additionalArguments: [ ] ,
258
- productsBuildParameters: buildParameters,
255
+ ) && ranSuccessfully
256
+ } else {
257
+ let testSuites = try TestingSupport . getTestSuites (
258
+ in: testProducts,
259
259
swiftCommandState: swiftCommandState,
260
- library: . swiftTesting
260
+ enableCodeCoverage: options. enableCodeCoverage,
261
+ shouldSkipBuilding: options. sharedOptions. shouldSkipBuilding,
262
+ experimentalTestOutput: options. enableExperimentalTestOutput,
263
+ sanitizers: globalOptions. build. sanitizers
261
264
)
262
- }
263
- } else {
264
- let testSuites = try TestingSupport . getTestSuites (
265
- in: testProducts,
266
- swiftCommandState: swiftCommandState,
267
- enableCodeCoverage: options. enableCodeCoverage,
268
- shouldSkipBuilding: options. sharedOptions. shouldSkipBuilding,
269
- experimentalTestOutput: options. enableExperimentalTestOutput,
270
- sanitizers: globalOptions. build. sanitizers
271
- )
272
- let tests = try testSuites
273
- . filteredTests ( specifier: options. testCaseSpecifier)
274
- . skippedTests ( specifier: options. skippedTests ( fileSystem: swiftCommandState. fileSystem) )
265
+ let tests = try testSuites
266
+ . filteredTests ( specifier: options. testCaseSpecifier)
267
+ . skippedTests ( specifier: options. skippedTests ( fileSystem: swiftCommandState. fileSystem) )
275
268
276
- // Run the tests using the parallel runner.
277
- let runner = ParallelTestRunner (
278
- bundlePaths: testProducts. map { $0. bundlePath } ,
279
- cancellator: swiftCommandState. cancellator,
280
- toolchain: toolchain,
281
- numJobs: options. numberOfWorkers ?? ProcessInfo . processInfo. activeProcessorCount,
282
- buildOptions: globalOptions. build,
283
- productsBuildParameters: buildParameters,
284
- shouldOutputSuccess: swiftCommandState. logLevel <= . info,
285
- observabilityScope: swiftCommandState. observabilityScope
286
- )
269
+ // Run the tests using the parallel runner.
270
+ let runner = ParallelTestRunner (
271
+ bundlePaths: testProducts. map { $0. bundlePath } ,
272
+ cancellator: swiftCommandState. cancellator,
273
+ toolchain: toolchain,
274
+ numJobs: options. numberOfWorkers ?? ProcessInfo . processInfo. activeProcessorCount,
275
+ buildOptions: globalOptions. build,
276
+ productsBuildParameters: buildParameters,
277
+ shouldOutputSuccess: swiftCommandState. logLevel <= . info,
278
+ observabilityScope: swiftCommandState. observabilityScope
279
+ )
287
280
288
- let testResults = try runner. run ( tests)
281
+ let testResults = try runner. run ( tests)
289
282
290
- try generateXUnitOutputIfRequested ( for: testResults, swiftCommandState: swiftCommandState)
283
+ try generateXUnitOutputIfRequested ( for: testResults, swiftCommandState: swiftCommandState)
291
284
292
- if !runner. ranSuccessfully {
293
- swiftCommandState. executionStatus = . failure
285
+ ranSuccessfully = ranSuccessfully && runner. ranSuccessfully
294
286
}
287
+ }
295
288
296
- if self . options. enableExperimentalTestOutput, !runner. ranSuccessfully {
297
- try Self . handleTestOutput ( productsBuildParameters: buildParameters, packagePath: testProducts [ 0 ] . packagePath)
298
- }
289
+ // Run Swift Testing (parallel or not, it has a single entry point.)
290
+ if options. testLibraryOptions. enableSwiftTestingLibrarySupport {
291
+ ranSuccessfully = try await runTestProducts (
292
+ testProducts,
293
+ additionalArguments: [ ] ,
294
+ productsBuildParameters: buildParameters,
295
+ swiftCommandState: swiftCommandState,
296
+ library: . swiftTesting
297
+ ) && ranSuccessfully
298
+ }
299
+
300
+ if !ranSuccessfully {
301
+ swiftCommandState. executionStatus = . failure
302
+ }
303
+
304
+ if self . options. enableExperimentalTestOutput, !ranSuccessfully {
305
+ try Self . handleTestOutput ( productsBuildParameters: buildParameters, packagePath: testProducts [ 0 ] . packagePath)
299
306
}
300
307
}
301
308
@@ -390,12 +397,12 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
390
397
productsBuildParameters: BuildParameters ,
391
398
swiftCommandState: SwiftCommandState ,
392
399
library: BuildParameters . Testing . Library
393
- ) async throws {
400
+ ) async throws -> Bool {
394
401
#if os(macOS)
395
402
if library == . swiftTesting {
396
403
// On macOS, the xctest executable provided with Xcode acts as a harness
397
404
// for Swift Testing, so we don't need to run Swift Testing tests separately.
398
- return
405
+ return true
399
406
}
400
407
#endif
401
408
@@ -424,19 +431,11 @@ public struct SwiftTestCommand: AsyncSwiftCommand {
424
431
)
425
432
426
433
// Finally, run the tests.
427
- let ranSuccessfully = runner. test ( outputHandler: {
434
+ return runner. test ( outputHandler: {
428
435
// command's result output goes on stdout
429
436
// ie "swift test" should output to stdout
430
437
print ( $0, terminator: " " )
431
438
} )
432
-
433
- if !ranSuccessfully {
434
- swiftCommandState. executionStatus = . failure
435
- }
436
-
437
- if self . options. enableExperimentalTestOutput, !ranSuccessfully {
438
- try Self . handleTestOutput ( productsBuildParameters: productsBuildParameters, packagePath: testProducts [ 0 ] . packagePath)
439
- }
440
439
}
441
440
442
441
private static func handleTestOutput( productsBuildParameters: BuildParameters , packagePath: AbsolutePath ) throws {
0 commit comments