Skip to content

Commit 75a679a

Browse files
committed
Allow multiple observers passed to XCTMain, add test
1 parent 8e1de85 commit 75a679a

File tree

2 files changed

+143
-3
lines changed

2 files changed

+143
-3
lines changed

Sources/XCTest/Public/XCTestMain.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ public func XCTMain(_ testCases: [XCTestCaseEntry]) -> Never {
6464
}
6565

6666
public func XCTMain(_ testCases: [XCTestCaseEntry], arguments: [String]) -> Never {
67-
XCTMain(testCases, arguments: arguments, observation: PrintObserver())
67+
XCTMain(testCases, arguments: arguments, observers: [PrintObserver()])
6868
}
6969

7070
public func XCTMain(
7171
_ testCases: [XCTestCaseEntry],
7272
arguments: [String],
73-
observation: XCTestObservation
73+
observers: [XCTestObservation]
7474
) -> Never {
7575
let testBundle = Bundle.main
7676

@@ -137,7 +137,9 @@ public func XCTMain(
137137
case .run(selectedTestNames: _):
138138
// Add a test observer that prints test progress to stdout.
139139
let observationCenter = XCTestObservationCenter.shared
140-
observationCenter.addTestObserver(observation)
140+
for observer in observers {
141+
observationCenter.addTestObserver(observer)
142+
}
141143

142144
observationCenter.testBundleWillStart(testBundle)
143145
rootTestSuite.run()
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// RUN: %{swiftc} %s -o %T/MultipleObservers
2+
// RUN: %T/MultipleObservers > %t || true
3+
// RUN: %{xctest_checker} %t %s
4+
5+
#if os(macOS)
6+
import SwiftXCTest
7+
#else
8+
import XCTest
9+
#endif
10+
11+
class Observer: XCTestObservation {
12+
var startedBundlePaths = [String]()
13+
var startedTestSuites = [XCTestSuite]()
14+
var startedTestCaseNames = [String]()
15+
var failureDescriptions = [String]()
16+
var finishedTestCaseNames = [String]()
17+
var finishedTestSuites = [XCTestSuite]()
18+
var finishedBundlePaths = [String]()
19+
20+
func testBundleWillStart(_ testBundle: Bundle) {
21+
startedBundlePaths.append(testBundle.bundlePath)
22+
}
23+
24+
func testSuiteWillStart(_ testSuite: XCTestSuite) {
25+
startedTestSuites.append(testSuite)
26+
}
27+
28+
func testCaseWillStart(_ testCase: XCTestCase) {
29+
startedTestCaseNames.append(testCase.name)
30+
}
31+
32+
func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: Int) {
33+
failureDescriptions.append(description)
34+
}
35+
36+
func testCaseDidFinish(_ testCase: XCTestCase) {
37+
finishedTestCaseNames.append(testCase.name)
38+
}
39+
40+
func testSuiteDidFinish(_ testSuite: XCTestSuite) {
41+
print("In \(#function): \(testSuite.name)")
42+
}
43+
44+
func testBundleDidFinish(_ testBundle: Bundle) {
45+
print("In \(#function)")
46+
}
47+
}
48+
49+
let observer1 = Observer()
50+
let observer2 = Observer()
51+
52+
class Observation: XCTestCase {
53+
static var allTests = {
54+
return [
55+
("test_one", test_one),
56+
("test_two", test_two),
57+
("test_three", test_three),
58+
]
59+
}()
60+
61+
func test_one() {
62+
XCTAssertEqual(observer1.startedBundlePaths.count, 1)
63+
XCTAssertEqual(observer2.startedBundlePaths.count, 1)
64+
XCTAssertEqual(
65+
observer1.startedTestSuites.count, 3,
66+
"Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
67+
XCTAssertEqual(
68+
observer2.startedTestSuites.count, 3,
69+
"Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
70+
XCTAssertEqual(observer1.startedTestCaseNames, ["Observation.test_one"])
71+
XCTAssertEqual(observer2.startedTestCaseNames, ["Observation.test_one"])
72+
XCTAssertEqual(observer1.failureDescriptions, [])
73+
XCTAssertEqual(observer2.failureDescriptions, [])
74+
XCTAssertEqual(observer1.finishedTestCaseNames, [])
75+
XCTAssertEqual(observer2.finishedTestCaseNames, [])
76+
XCTAssertEqual(observer1.finishedBundlePaths.count, 0)
77+
XCTAssertEqual(observer2.finishedBundlePaths.count, 0)
78+
79+
XCTFail("fail!")
80+
XCTAssertEqual(observer1.failureDescriptions, ["failed - fail!"])
81+
XCTAssertEqual(observer2.failureDescriptions, ["failed - fail!"])
82+
}
83+
84+
func test_two() {
85+
XCTAssertEqual(observer1.startedBundlePaths.count, 1)
86+
XCTAssertEqual(observer2.startedBundlePaths.count, 1)
87+
XCTAssertEqual(
88+
observer1.startedTestSuites.count, 3,
89+
"Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
90+
XCTAssertEqual(
91+
observer2.startedTestSuites.count, 3,
92+
"Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
93+
XCTAssertEqual(observer1.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
94+
XCTAssertEqual(observer2.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
95+
XCTAssertEqual(observer1.finishedTestCaseNames,["Observation.test_one"])
96+
XCTAssertEqual(observer2.finishedTestCaseNames,["Observation.test_one"])
97+
XCTAssertEqual(observer1.finishedBundlePaths.count, 0)
98+
XCTAssertEqual(observer2.finishedBundlePaths.count, 0)
99+
100+
XCTestObservationCenter.shared.removeTestObserver(observer1)
101+
XCTestObservationCenter.shared.removeTestObserver(observer2)
102+
}
103+
104+
func test_three() {
105+
XCTAssertEqual(observer1.startedBundlePaths.count, 1)
106+
XCTAssertEqual(observer2.startedBundlePaths.count, 1)
107+
XCTAssertEqual(observer1.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
108+
XCTAssertEqual(observer2.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
109+
XCTAssertEqual(observer1.finishedTestCaseNames,["Observation.test_one"])
110+
XCTAssertEqual(observer2.finishedTestCaseNames,["Observation.test_one"])
111+
XCTAssertEqual(observer1.finishedBundlePaths.count, 0)
112+
XCTAssertEqual(observer2.finishedBundlePaths.count, 0)
113+
114+
XCTestObservationCenter.shared.addTestObserver(observer1)
115+
XCTestObservationCenter.shared.addTestObserver(observer2)
116+
}
117+
}
118+
119+
// There's no guarantee as to the order in which these two observers will be
120+
// called, so we match any order here.
121+
122+
// CHECK: In testSuiteDidFinish\(_:\): Observation
123+
// CHECK: In testSuiteDidFinish\(_:\): Observation
124+
125+
XCTMain(
126+
[testCase(Observation.allTests)],
127+
arguments: CommandLine.arguments,
128+
observers: [observer1, observer2]
129+
)
130+
131+
// CHECK: In testSuiteDidFinish\(_:\): .*\.xctest
132+
// CHECK: In testSuiteDidFinish\(_:\): .*\.xctest
133+
134+
// CHECK: In testSuiteDidFinish\(_:\): All tests
135+
// CHECK: In testSuiteDidFinish\(_:\): All tests
136+
137+
// CHECK: In testBundleDidFinish\(_:\)
138+
// CHECK: In testBundleDidFinish\(_:\)

0 commit comments

Comments
 (0)