Skip to content

Commit 2037d73

Browse files
committed
Merge pull request #81 from modocache/observation-bundle
[XCTestObservation] Add test bundle observation
2 parents 360a13a + 8d46300 commit 2037d73

File tree

4 files changed

+69
-10
lines changed

4 files changed

+69
-10
lines changed

Sources/XCTest/XCTestMain.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ internal struct XCTRun {
7979
/// - Parameter testCases: An array of test cases run, each produced by a call to the `testCase` function
8080
/// - seealso: `testCase`
8181
@noreturn public func XCTMain(testCases: [XCTestCaseEntry]) {
82+
let observationCenter = XCTestObservationCenter.sharedTestObservationCenter()
83+
let testBundle = NSBundle.mainBundle()
84+
observationCenter.testBundleWillStart(testBundle)
85+
8286
let filter = TestFiltering()
8387

8488
let overallDuration = measureTimeExecutingBlock {
@@ -99,6 +103,7 @@ internal struct XCTRun {
99103
}
100104

101105
XCTPrint("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
106+
observationCenter.testBundleDidFinish(testBundle)
102107
exit(totalFailures > 0 ? 1 : 0)
103108
}
104109

Sources/XCTest/XCTestObservation.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,22 @@
1111
// Hooks for being notified about progress during a test run.
1212
//
1313

14+
#if os(Linux) || os(FreeBSD)
15+
import Foundation
16+
#else
17+
import SwiftFoundation
18+
#endif
19+
1420
/// `XCTestObservation` provides hooks for being notified about progress during a
1521
/// test run.
1622
/// - seealso: `XCTestObservationCenter`
1723
public protocol XCTestObservation: class {
24+
25+
/// Sent immediately before tests begin as a hook for any pre-testing setup.
26+
/// - Parameter testBundle: The bundle containing the tests that were
27+
/// executed.
28+
func testBundleWillStart(testBundle: NSBundle)
29+
1830
/// Called just before a test begins executing.
1931
/// - Parameter testCase: The test case that is about to start. Its `name`
2032
/// property can be used to identify it.
@@ -34,6 +46,15 @@ public protocol XCTestObservation: class {
3446
/// - Parameter testCase: The test case that finished. Its `name` property
3547
/// can be used to identify it.
3648
func testCaseDidFinish(testCase: XCTestCase)
49+
50+
/// Sent immediately after all tests have finished as a hook for any
51+
/// post-testing activity. The test process will generally exit after this
52+
/// method returns, so if there is long running and/or asynchronous work to
53+
/// be done after testing, be sure to implement this method in a way that
54+
/// it blocks until all such activity is complete.
55+
/// - Parameter testBundle: The bundle containing the tests that were
56+
/// executed.
57+
func testBundleDidFinish(testBundle: NSBundle)
3758
}
3859

3960
// All `XCTestObservation` methods are optional, so empty default implementations are provided

Sources/XCTest/XCTestObservationCenter.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
// Notification center for test run progress events.
1212
//
1313

14+
#if os(Linux) || os(FreeBSD)
15+
import Foundation
16+
#else
17+
import SwiftFoundation
18+
#endif
19+
1420
/// Provides a registry for objects wishing to be informed about progress
1521
/// during the course of a test run. Observers must implement the
1622
/// `XCTestObservation` protocol
@@ -37,6 +43,9 @@ public class XCTestObservationCenter {
3743
observers.remove(testObserver.wrapper)
3844
}
3945

46+
internal func testBundleWillStart(testBundle: NSBundle) {
47+
forEachObserver { $0.testBundleWillStart(testBundle) }
48+
}
4049

4150
internal func testCaseWillStart(testCase: XCTestCase) {
4251
forEachObserver { $0.testCaseWillStart(testCase) }
@@ -50,6 +59,10 @@ public class XCTestObservationCenter {
5059
forEachObserver { $0.testCaseDidFinish(testCase) }
5160
}
5261

62+
internal func testBundleDidFinish(testBundle: NSBundle) {
63+
forEachObserver { $0.testBundleDidFinish(testBundle) }
64+
}
65+
5366
private func forEachObserver(@noescape body: XCTestObservation -> Void) {
5467
for observer in observers {
5568
body(observer.object)

Tests/Functional/Observation/main.swift

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@
44

55
#if os(Linux) || os(FreeBSD)
66
import XCTest
7+
import Foundation
78
#else
89
import SwiftXCTest
10+
import SwiftFoundation
911
#endif
1012

1113
class Observer: XCTestObservation {
14+
var startedBundlePaths = [String]()
1215
var startedTestCaseNames = [String]()
1316
var failureDescriptions = [String]()
1417
var finishedTestCaseNames = [String]()
18+
var finishedBundlePaths = [String]()
19+
20+
func testBundleWillStart(testBundle: NSBundle) {
21+
startedBundlePaths.append(testBundle.bundlePath)
22+
}
1523

1624
func testCaseWillStart(testCase: XCTestCase) {
1725
startedTestCaseNames.append(testCase.name)
@@ -24,9 +32,14 @@ class Observer: XCTestObservation {
2432
func testCaseDidFinish(testCase: XCTestCase) {
2533
finishedTestCaseNames.append(testCase.name)
2634
}
35+
36+
func testBundleDidFinish(testBundle: NSBundle) {
37+
print("In \(#function)")
38+
}
2739
}
2840

2941
let observer = Observer()
42+
XCTestObservationCenter.sharedTestObservationCenter().addTestObserver(observer)
3043

3144
class Observation: XCTestCase {
3245
static var allTests: [(String, Observation -> () throws -> Void)] {
@@ -38,37 +51,44 @@ class Observation: XCTestCase {
3851
}
3952

4053
// CHECK: Test Case 'Observation.test_one' started.
41-
// CHECK: Test Case 'Observation.test_one' passed \(\d+\.\d+ seconds\).
54+
// CHECK: .*/Observation/main.swift:\d+: error: Observation.test_one : failed - fail!
55+
// CHECK: Test Case 'Observation.test_one' failed \(\d+\.\d+ seconds\).
4256
func test_one() {
43-
XCTAssertEqual(observer.startedTestCaseNames, [])
57+
XCTAssertEqual(observer.startedBundlePaths.count, 1)
58+
XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one"])
4459
XCTAssertEqual(observer.failureDescriptions, [])
4560
XCTAssertEqual(observer.finishedTestCaseNames, [])
61+
XCTAssertEqual(observer.finishedBundlePaths.count, 0)
4662

47-
XCTestObservationCenter.sharedTestObservationCenter().addTestObserver(observer)
63+
XCTFail("fail!")
64+
XCTAssertEqual(observer.failureDescriptions, ["failed - fail!"])
4865
}
4966

5067
// CHECK: Test Case 'Observation.test_two' started.
51-
// CHECK: .*/Observation/main.swift:\d+: error: Observation.test_two : failed - fail!
52-
// CHECK: Test Case 'Observation.test_two' failed \(\d+\.\d+ seconds\).
68+
// CHECK: Test Case 'Observation.test_two' passed \(\d+\.\d+ seconds\).
5369
func test_two() {
54-
XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_two"])
70+
XCTAssertEqual(observer.startedBundlePaths.count, 1)
71+
XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
5572
XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
56-
57-
XCTFail("fail!")
58-
XCTAssertEqual(observer.failureDescriptions, ["failed - fail!"])
73+
XCTAssertEqual(observer.finishedBundlePaths.count, 0)
5974

6075
XCTestObservationCenter.sharedTestObservationCenter().removeTestObserver(observer)
6176
}
6277

6378
// CHECK: Test Case 'Observation.test_three' started.
6479
// CHECK: Test Case 'Observation.test_three' passed \(\d+\.\d+ seconds\).
6580
func test_three() {
66-
XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_two"])
81+
XCTAssertEqual(observer.startedBundlePaths.count, 1)
82+
XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
6783
XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
84+
XCTAssertEqual(observer.finishedBundlePaths.count, 0)
85+
86+
XCTestObservationCenter.sharedTestObservationCenter().addTestObserver(observer)
6887
}
6988
}
7089

7190
XCTMain([testCase(Observation.allTests)])
7291

7392
// CHECK: Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
7493
// CHECK: Total executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
94+
// CHECK: In testBundleDidFinish

0 commit comments

Comments
 (0)