Skip to content

Commit 199cc22

Browse files
neonichuMaxDesiatov
authored andcommitted
Improve test tool diagnostics (#6893)
- Merge the two 99% identical implementations of `buildTestsIfNeeded()` - Handle the case where a non-test product is passed to `--test-product` - Handle the case where we cannot find the test product after the build
1 parent 5cd990b commit 199cc22

File tree

1 file changed

+40
-42
lines changed

1 file changed

+40
-42
lines changed

Sources/Commands/SwiftTestTool.swift

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,22 @@ import protocol TSCUtility.ProgressAnimationProtocol
3737

3838
private enum TestError: Swift.Error {
3939
case invalidListTestJSONData(context: String, underlyingError: Error? = nil)
40-
case testsExecutableNotFound
40+
case testsNotFound
41+
case testProductNotFound(productName: String)
42+
case productIsNotTest(productName: String)
4143
case multipleTestProducts([String])
4244
case xctestNotAvailable
4345
}
4446

4547
extension TestError: CustomStringConvertible {
4648
var description: String {
4749
switch self {
48-
case .testsExecutableNotFound:
50+
case .testsNotFound:
4951
return "no tests found; create a target in the 'Tests' directory"
52+
case .testProductNotFound(let productName):
53+
return "there is no test product named '\(productName)'"
54+
case .productIsNotTest(let productName):
55+
return "the product '\(productName)' is not a test"
5056
case .invalidListTestJSONData(let context, let underlyingError):
5157
let underlying = underlyingError != nil ? ", underlying error: \(underlyingError!)" : ""
5258
return "invalid list test JSON structure, produced by \(context)\(underlying)"
@@ -467,26 +473,7 @@ public struct SwiftTestTool: SwiftCommand {
467473
/// - Returns: The paths to the build test products.
468474
private func buildTestsIfNeeded(swiftTool: SwiftTool) throws -> [BuiltTestProduct] {
469475
let buildParameters = try swiftTool.buildParametersForTest(options: self.options, sharedOptions: self.sharedOptions)
470-
let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters)
471-
472-
let subset = self.sharedOptions.testProduct.map(BuildSubset.product) ?? .allIncludingTests
473-
try buildSystem.build(subset: subset)
474-
475-
// Find the test product.
476-
let testProducts = buildSystem.builtTestProducts
477-
guard !testProducts.isEmpty else {
478-
throw TestError.testsExecutableNotFound
479-
}
480-
481-
if let testProductName = self.sharedOptions.testProduct {
482-
guard let selectedTestProduct = testProducts.first(where: { $0.productName == testProductName }) else {
483-
throw TestError.testsExecutableNotFound
484-
}
485-
486-
return [selectedTestProduct]
487-
} else {
488-
return testProducts
489-
}
476+
return try Commands.buildTestsIfNeeded(swiftTool: swiftTool, buildParameters: buildParameters, testProduct: self.sharedOptions.testProduct)
490477
}
491478

492479
/// Private function that validates the commands arguments
@@ -595,26 +582,7 @@ extension SwiftTestTool {
595582

596583
private func buildTestsIfNeeded(swiftTool: SwiftTool) throws -> [BuiltTestProduct] {
597584
let buildParameters = try swiftTool.buildParametersForTest(enableCodeCoverage: false, shouldSkipBuilding: sharedOptions.shouldSkipBuilding)
598-
let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters)
599-
600-
let subset = self.sharedOptions.testProduct.map(BuildSubset.product) ?? .allIncludingTests
601-
try buildSystem.build(subset: subset)
602-
603-
// Find the test product.
604-
let testProducts = buildSystem.builtTestProducts
605-
guard !testProducts.isEmpty else {
606-
throw TestError.testsExecutableNotFound
607-
}
608-
609-
if let testProductName = self.sharedOptions.testProduct {
610-
guard let selectedTestProduct = testProducts.first(where: { $0.productName == testProductName }) else {
611-
throw TestError.testsExecutableNotFound
612-
}
613-
614-
return [selectedTestProduct]
615-
} else {
616-
return testProducts
617-
}
585+
return try Commands.buildTestsIfNeeded(swiftTool: swiftTool, buildParameters: buildParameters, testProduct: self.sharedOptions.testProduct)
618586
}
619587
}
620588
}
@@ -1190,3 +1158,33 @@ private extension Basics.Diagnostic {
11901158
.warning("No matching test cases were run")
11911159
}
11921160
}
1161+
1162+
/// Builds the "test" target if enabled in options.
1163+
///
1164+
/// - Returns: The paths to the build test products.
1165+
private func buildTestsIfNeeded(swiftTool: SwiftTool, buildParameters: BuildParameters, testProduct: String?) throws -> [BuiltTestProduct] {
1166+
let buildSystem = try swiftTool.createBuildSystem(customBuildParameters: buildParameters)
1167+
1168+
let subset = testProduct.map(BuildSubset.product) ?? .allIncludingTests
1169+
try buildSystem.build(subset: subset)
1170+
1171+
// Find the test product.
1172+
let testProducts = buildSystem.builtTestProducts
1173+
guard !testProducts.isEmpty else {
1174+
if let testProduct {
1175+
throw TestError.productIsNotTest(productName: testProduct)
1176+
} else {
1177+
throw TestError.testsNotFound
1178+
}
1179+
}
1180+
1181+
if let testProductName = testProduct {
1182+
guard let selectedTestProduct = testProducts.first(where: { $0.productName == testProductName }) else {
1183+
throw TestError.testProductNotFound(productName: testProductName)
1184+
}
1185+
1186+
return [selectedTestProduct]
1187+
} else {
1188+
return testProducts
1189+
}
1190+
}

0 commit comments

Comments
 (0)