Skip to content

Commit f7f7836

Browse files
authored
Add support for correctly discovering async test methods on non-Apple platforms (#3844)
* Update `TestDiscoveryCommand` to wrap async test methods in `asyncTest` function calls. * Add integration test * Adapt to the latest s-t-s-c modeling adjustments.
1 parent f97cba5 commit f7f7836

File tree

5 files changed

+53
-3
lines changed

5 files changed

+53
-3
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// swift-tools-version:4.2
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "Async",
6+
targets: [
7+
.target(name: "Async"),
8+
.testTarget(name: "AsyncTests", dependencies: ["Async"]),
9+
]
10+
)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct Async {
2+
3+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import XCTest
2+
@testable import Async
3+
4+
class AsyncTests: XCTestCase {
5+
6+
func testAsync() async {
7+
}
8+
9+
@MainActor func testMainActor() async {
10+
XCTAssertTrue(Thread.isMainThread)
11+
}
12+
13+
func testNotAsync() {
14+
XCTAssertTrue(Thread.isMainThread)
15+
}
16+
}

Sources/Build/BuildOperationBuildSystemDelegateHandler.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ class CustomLLBuildCommand: SPMLLBuild.ExternalCommand {
4545
}
4646
}
4747

48+
private extension IndexStore.TestCaseClass.TestMethod {
49+
50+
var allTestsEntry: String {
51+
let baseName = name.hasSuffix("()") ? String(name.dropLast(2)) : name
52+
53+
return "(\"\(baseName)\", \(isAsync ? "asyncTest(\(baseName))" : baseName ))"
54+
}
55+
}
56+
4857
final class TestDiscoveryCommand: CustomLLBuildCommand {
4958

5059
private func write(
@@ -61,13 +70,12 @@ final class TestDiscoveryCommand: CustomLLBuildCommand {
6170

6271
for iterator in testsByClassNames {
6372
let className = iterator.key
64-
let testMethods = iterator.value.flatMap{ $0.methods }
73+
let testMethods = iterator.value.flatMap{ $0.testMethods }
6574
stream <<< "\n"
6675
stream <<< "fileprivate extension " <<< className <<< " {" <<< "\n"
6776
stream <<< indent(4) <<< "static let __allTests__\(className) = [" <<< "\n"
6877
for method in testMethods {
69-
let method = method.hasSuffix("()") ? String(method.dropLast(2)) : method
70-
stream <<< indent(8) <<< "(\"\(method)\", \(method))," <<< "\n"
78+
stream <<< indent(8) <<< method.allTestsEntry <<< ",\n"
7179
}
7280
stream <<< indent(4) <<< "]" <<< "\n"
7381
stream <<< "}" <<< "\n"

Tests/FunctionalTests/TestDiscoveryTests.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ class TestDiscoveryTests: XCTestCase {
5151
}
5252
}
5353

54+
func testAsyncMethods() throws {
55+
fixture(name: "Miscellaneous/TestDiscovery/Async") { path in
56+
let (stdout, stderr) = try executeSwiftTest(path)
57+
#if os(macOS)
58+
XCTAssertMatch(stdout, .contains("module Async"))
59+
XCTAssertMatch(stderr, .contains("Executed 3 tests"))
60+
#else
61+
XCTAssertMatch(stdout, .contains("module Async"))
62+
XCTAssertMatch(stdout, .contains("Executed 3 tests"))
63+
#endif
64+
}
65+
}
66+
5467
func testManifestOverride() throws {
5568
#if os(macOS)
5669
try XCTSkipIf(true)

0 commit comments

Comments
 (0)