Merge pull request #77 from modocache/readme-getting-started

[README] Encourage using the Swift build script
diff --git a/Sources/XCTest/PrintObserver.swift b/Sources/XCTest/PrintObserver.swift
new file mode 100644
index 0000000..ee2bada
--- /dev/null
+++ b/Sources/XCTest/PrintObserver.swift
@@ -0,0 +1,77 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  PrintObserver.swift
+//  Prints test progress to stdout.
+//
+
+#if os(Linux) || os(FreeBSD)
+    import Foundation
+#else
+    import SwiftFoundation
+#endif
+
+/// Prints textual representations of each XCTestObservation event to stdout.
+/// Mirrors the Apple XCTest output exactly.
+internal class PrintObserver: XCTestObservation {
+    func testBundleWillStart(_ testBundle: NSBundle) {}
+
+    func testSuiteWillStart(_ testSuite: XCTestSuite) {
+        printAndFlush("Test Suite '\(testSuite.name)' started at \(dateFormatter.stringFromDate(testSuite.testRun!.startDate!))")
+    }
+
+    func testCaseWillStart(_ testCase: XCTestCase) {
+        printAndFlush("Test Case '\(testCase.name)' started at \(dateFormatter.stringFromDate(testCase.testRun!.startDate!))")
+    }
+
+    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
+        let file = filePath ?? "<unknown>"
+        printAndFlush("\(file):\(lineNumber): error: \(testCase.name) : \(description)")
+    }
+
+    func testCaseDidFinish(_ testCase: XCTestCase) {
+        let testRun = testCase.testRun!
+        let verb = testRun.hasSucceeded ? "passed" : "failed"
+        // FIXME: Apple XCTest does not print a period after "(N seconds)".
+        //        The trailing period here should be removed and the functional
+        //        test suite should be updated.
+        printAndFlush("Test Case '\(testCase.name)' \(verb) (\(formatTimeInterval(testRun.totalDuration)) seconds).")
+    }
+
+    func testSuiteDidFinish(_ testSuite: XCTestSuite) {
+        let testRun = testSuite.testRun!
+        let verb = testRun.hasSucceeded ? "passed" : "failed"
+        printAndFlush("Test Suite '\(testSuite.name)' \(verb) at \(dateFormatter.stringFromDate(testRun.stopDate!))")
+
+        let tests = testRun.executionCount == 1 ? "test" : "tests"
+        let failures = testRun.totalFailureCount == 1 ? "failure" : "failures"
+        printAndFlush(
+            "\t Executed \(testRun.executionCount) \(tests), " +
+            "with \(testRun.totalFailureCount) \(failures) (\(testRun.unexpectedExceptionCount) unexpected) " +
+            "in \(formatTimeInterval(testRun.testDuration)) (\(formatTimeInterval(testRun.totalDuration))) seconds"
+        )
+    }
+
+    func testBundleDidFinish(_ testBundle: NSBundle) {}
+
+    private lazy var dateFormatter: NSDateFormatter = {
+        let formatter = NSDateFormatter()
+        formatter.dateFormat = "HH:mm:ss.SSS"
+        return formatter
+    }()
+
+    private func printAndFlush(_ message: String) {
+        print(message)
+        fflush(stdout)
+    }
+
+    private func formatTimeInterval(_ timeInterval: NSTimeInterval) -> String {
+        return String(round(timeInterval * 1000.0) / 1000.0)
+    }
+}
diff --git a/Sources/XCTest/TestFiltering.swift b/Sources/XCTest/TestFiltering.swift
index 49235e6..f101d25 100644
--- a/Sources/XCTest/TestFiltering.swift
+++ b/Sources/XCTest/TestFiltering.swift
@@ -35,7 +35,7 @@
         return { _ in true }
     }
 
-    static func filterTests(entries: [XCTestCaseEntry], filter: TestFilter) -> [XCTestCaseEntry] {
+    static func filterTests(_ entries: [XCTestCaseEntry], filter: TestFilter) -> [XCTestCaseEntry] {
         return entries
             .map { testCase, tests in
                 return (testCase, tests.filter { filter(testCase, $0.0) } )
@@ -68,7 +68,7 @@
         }
     }
 
-    func matches(testCase testCase: XCTestCase.Type, testName: String) -> Bool {
+    func matches(testCase: XCTestCase.Type, testName: String) -> Bool {
         return String(reflecting: testCase) == testCaseName && (self.testName == nil || testName == self.testName)
     }
 }
diff --git a/Sources/XCTest/XCAbstractTest.swift b/Sources/XCTest/XCAbstractTest.swift
new file mode 100644
index 0000000..9ff7f3a
--- /dev/null
+++ b/Sources/XCTest/XCAbstractTest.swift
@@ -0,0 +1,71 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCAbstractTest.swift
+//  An abstract base class that XCTestCase and XCTestSuite inherit from.
+//  The purpose of this class is to mirror the design of Apple XCTest.
+//
+
+/// An abstract base class for testing. `XCTestCase` and `XCTestSuite` extend
+/// `XCTest` to provide for creating, managing, and executing tests. Most
+/// developers will not need to subclass `XCTest` directly.
+public class XCTest {
+    /// Test's name. Must be overridden by subclasses.
+    public var name: String {
+        fatalError("Must be overridden by subclasses.")
+    }
+
+    /// Number of test cases. Must be overridden by subclasses.
+    public var testCaseCount: UInt {
+        fatalError("Must be overridden by subclasses.")
+    }
+
+    /// The `XCTestRun` subclass that will be instantiated when the test is run
+    /// to hold the test's results. Must be overridden by subclasses.
+    public var testRunClass: AnyClass? {
+        fatalError("Must be overridden by subclasses.")
+    }
+
+    /// The test run object that executed the test, an instance of
+    /// testRunClass. If the test has not yet been run, this will be nil.
+    /// - Note: FIXME: This property is meant to be `private(set)`. It is
+    ///   publicly settable for now due to a Swift compiler bug on Linux. To
+    ///   ensure compatibility of tests between swift-corelibs-xctest and Apple
+    ///   XCTest, you should not set this property. See
+    ///   https://bugs.swift.org/browse/SR-1129 for details.
+    public public(set) var testRun: XCTestRun? = nil
+
+    /// The method through which tests are executed. Must be overridden by
+    /// subclasses.
+    public func perform(_ run: XCTestRun) {
+        fatalError("Must be overridden by subclasses.")
+    }
+
+    /// Creates an instance of the `testRunClass` and passes it as a parameter
+    /// to `perform()`.
+    public func run() {
+        guard let testRunType = testRunClass as? XCTestRun.Type else {
+            fatalError("XCTest.testRunClass must be a kind of XCTestRun.")
+        }
+        testRun = testRunType.init(test: self)
+        perform(testRun!)
+    }
+
+    /// Setup method called before the invocation of each test method in the
+    /// class.
+    public func setUp() {}
+
+    /// Teardown method called after the invocation of each test method in the
+    /// class.
+    public func tearDown() {}
+
+    // FIXME: This initializer is required due to a Swift compiler bug on Linux.
+    //        It should be removed once the bug is fixed.
+    public init() {}
+}
\ No newline at end of file
diff --git a/Sources/XCTest/XCTAssert.swift b/Sources/XCTest/XCTAssert.swift
index 403973f..05501f1 100644
--- a/Sources/XCTest/XCTAssert.swift
+++ b/Sources/XCTest/XCTAssert.swift
@@ -11,60 +11,60 @@
 //
 
 private enum _XCTAssertion {
-    case Equal
-    case EqualWithAccuracy
-    case GreaterThan
-    case GreaterThanOrEqual
-    case LessThan
-    case LessThanOrEqual
-    case NotEqual
-    case NotEqualWithAccuracy
-    case Nil
-    case NotNil
-    case True
-    case False
-    case Fail
-    case ThrowsError
+    case equal
+    case equalWithAccuracy
+    case greaterThan
+    case greaterThanOrEqual
+    case lessThan
+    case lessThanOrEqual
+    case notEqual
+    case notEqualWithAccuracy
+    case `nil`
+    case notNil
+    case `true`
+    case `false`
+    case fail
+    case throwsError
 
     var name: String? {
         switch(self) {
-        case .Equal: return "XCTAssertEqual"
-        case .EqualWithAccuracy: return "XCTAssertEqualWithAccuracy"
-        case .GreaterThan: return "XCTAssertGreaterThan"
-        case .GreaterThanOrEqual: return "XCTAssertGreaterThanOrEqual"
-        case .LessThan: return "XCTAssertLessThan"
-        case .LessThanOrEqual: return "XCTAssertLessThanOrEqual"
-        case .NotEqual: return "XCTAssertNotEqual"
-        case .NotEqualWithAccuracy: return "XCTAssertNotEqualWithAccuracy"
-        case .Nil: return "XCTAssertNil"
-        case .NotNil: return "XCTAssertNotNil"
-        case .True: return "XCTAssertTrue"
-        case .False: return "XCTAssertFalse"
-        case .ThrowsError: return "XCTAssertThrowsError"
-        case .Fail: return nil
+        case .equal: return "XCTAssertEqual"
+        case .equalWithAccuracy: return "XCTAssertEqualWithAccuracy"
+        case .greaterThan: return "XCTAssertGreaterThan"
+        case .greaterThanOrEqual: return "XCTAssertGreaterThanOrEqual"
+        case .lessThan: return "XCTAssertLessThan"
+        case .lessThanOrEqual: return "XCTAssertLessThanOrEqual"
+        case .notEqual: return "XCTAssertNotEqual"
+        case .notEqualWithAccuracy: return "XCTAssertNotEqualWithAccuracy"
+        case .`nil`: return "XCTAssertNil"
+        case .notNil: return "XCTAssertNotNil"
+        case .`true`: return "XCTAssertTrue"
+        case .`false`: return "XCTAssertFalse"
+        case .throwsError: return "XCTAssertThrowsError"
+        case .fail: return nil
         }
     }
 }
 
 private enum _XCTAssertionResult {
-    case Success
-    case ExpectedFailure(String?)
-    case UnexpectedFailure(ErrorProtocol)
+    case success
+    case expectedFailure(String?)
+    case unexpectedFailure(ErrorProtocol)
 
-    var expected: Bool {
+    var isExpected: Bool {
         switch self {
-        case .UnexpectedFailure(_): return false
+        case .unexpectedFailure(_): return false
         default: return true
         }
     }
 
-    func failureDescription(assertion: _XCTAssertion) -> String {
+    func failureDescription(_ assertion: _XCTAssertion) -> String {
         let explanation: String
         switch self {
-        case .Success: explanation = "passed"
-        case .ExpectedFailure(let details?): explanation = "failed: \(details)"
-        case .ExpectedFailure(_): explanation = "failed"
-        case .UnexpectedFailure(let error): explanation = "threw error \"\(error)\""
+        case .success: explanation = "passed"
+        case .expectedFailure(let details?): explanation = "failed: \(details)"
+        case .expectedFailure(_): explanation = "failed"
+        case .unexpectedFailure(let error): explanation = "threw error \"\(error)\""
         }
 
         if let name = assertion.name {
@@ -75,20 +75,24 @@
     }
 }
 
-private func _XCTEvaluateAssertion(assertion: _XCTAssertion, @autoclosure message: () -> String = "", file: StaticString = #file, line: UInt = #line, @noescape expression: () throws -> _XCTAssertionResult) {
+private func _XCTEvaluateAssertion(_ assertion: _XCTAssertion, @autoclosure message: () -> String = "", file: StaticString = #file, line: UInt = #line, @noescape expression: () throws -> _XCTAssertionResult) {
     let result: _XCTAssertionResult
     do {
         result = try expression()
     } catch {
-        result = .UnexpectedFailure(error)
+        result = .unexpectedFailure(error)
     }
 
     switch result {
-    case .Success:
+    case .success:
         return
     default:
-        if let handler = XCTFailureHandler {
-            handler(XCTFailure(message: message(), failureDescription: result.failureDescription(assertion), expected: result.expected, file: file, line: line))
+        if let currentTestCase = XCTCurrentTestCase {
+            currentTestCase.recordFailure(
+                withDescription: "\(result.failureDescription(assertion)) - \(message())",
+                inFile: String(file),
+                atLine: line,
+                expected: result.isExpected)
         }
     }
 }
@@ -120,7 +124,7 @@
 ///   ```
 ///   // AssertEmpty.swift
 ///
-///   func AssertEmpty<T>(elements: [T]) {
+///   func AssertEmpty<T>(_ elements: [T]) {
 ///       XCTAssertEqual(elements.count, 0, "Array is not empty")
 ///   }
 ///   ```
@@ -141,245 +145,245 @@
 ///  ```
 ///  // AssertEmpty.swift
 ///
-///  func AssertEmpty<T>(elements: [T], file: StaticString = #file, line: UInt = #line) {
+///  func AssertEmpty<T>(_ elements: [T], file: StaticString = #file, line: UInt = #line) {
 ///      XCTAssertEqual(elements.count, 0, "Array is not empty", file: file, line: line)
 ///  }
 ///  ```
 ///
 ///  Now calling failures in `AssertEmpty` will be reported in the file and on
 ///  the line that the assert function is *called*, not where it is defined.
-public func XCTAssert(@autoclosure expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+public func XCTAssert(@autoclosure _ expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
     XCTAssertTrue(expression, message, file: file, line: line)
 }
 
-public func XCTAssertEqual<T: Equatable>(@autoclosure expression1: () throws -> T?, @autoclosure _ expression2: () throws -> T?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Equal, message: message, file: file, line: line) {
+public func XCTAssertEqual<T: Equatable>(@autoclosure _ expression1: () throws -> T?, @autoclosure _ expression2: () throws -> T?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equal, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 == value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertEqual<T: Equatable>(@autoclosure expression1: () throws -> ArraySlice<T>, @autoclosure _ expression2: () throws -> ArraySlice<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Equal, message: message, file: file, line: line) {
+public func XCTAssertEqual<T: Equatable>(@autoclosure _ expression1: () throws -> ArraySlice<T>, @autoclosure _ expression2: () throws -> ArraySlice<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equal, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 == value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertEqual<T: Equatable>(@autoclosure expression1: () throws -> ContiguousArray<T>, @autoclosure _ expression2: () throws -> ContiguousArray<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Equal, message: message, file: file, line: line) {
+public func XCTAssertEqual<T: Equatable>(@autoclosure _ expression1: () throws -> ContiguousArray<T>, @autoclosure _ expression2: () throws -> ContiguousArray<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equal, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 == value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertEqual<T: Equatable>(@autoclosure expression1: () throws -> [T], @autoclosure _ expression2: () throws -> [T], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Equal, message: message, file: file, line: line) {
+public func XCTAssertEqual<T: Equatable>(@autoclosure _ expression1: () throws -> [T], @autoclosure _ expression2: () throws -> [T], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equal, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 == value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertEqual<T, U: Equatable>(@autoclosure expression1: () throws -> [T: U], @autoclosure _ expression2: () throws -> [T: U], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Equal, message: message, file: file, line: line) {
+public func XCTAssertEqual<T, U: Equatable>(@autoclosure _ expression1: () throws -> [T: U], @autoclosure _ expression2: () throws -> [T: U], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equal, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 == value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertEqualWithAccuracy<T: FloatingPoint>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, accuracy: T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.EqualWithAccuracy, message: message, file: file, line: line) {
+public func XCTAssertEqualWithAccuracy<T: FloatingPoint>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, accuracy: T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.equalWithAccuracy, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if abs(value1.distance(to: value2)) <= abs(accuracy.distance(to: T(0))) {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\") +/- (\"\(accuracy)\")")
+            return .expectedFailure("(\"\(value1)\") is not equal to (\"\(value2)\") +/- (\"\(accuracy)\")")
         }
     }
 }
 
-public func XCTAssertFalse(@autoclosure expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.False, message: message, file: file, line: line) {
+public func XCTAssertFalse(@autoclosure _ expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.`false`, message: message, file: file, line: line) {
         let value = try expression()
         if !value.boolValue {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure(nil)
+            return .expectedFailure(nil)
         }
     }
 }
 
-public func XCTAssertGreaterThan<T: Comparable>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.GreaterThan, message: message, file: file, line: line) {
+public func XCTAssertGreaterThan<T: Comparable>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.greaterThan, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 > value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not greater than (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not greater than (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertGreaterThanOrEqual<T: Comparable>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.GreaterThanOrEqual, message: message, file: file, line: line) {
+public func XCTAssertGreaterThanOrEqual<T: Comparable>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.greaterThanOrEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 >= value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is less than (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is less than (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertLessThan<T: Comparable>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.LessThan, message: message, file: file, line: line) {
+public func XCTAssertLessThan<T: Comparable>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.lessThan, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 < value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is not less than (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is not less than (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertLessThanOrEqual<T: Comparable>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.LessThanOrEqual, message: message, file: file, line: line) {
+public func XCTAssertLessThanOrEqual<T: Comparable>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.lessThanOrEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 <= value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is greater than (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is greater than (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNil(@autoclosure expression: () throws -> Any?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Nil, message: message, file: file, line: line) {
+public func XCTAssertNil(@autoclosure _ expression: () throws -> Any?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.`nil`, message: message, file: file, line: line) {
         let value = try expression()
         if value == nil {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("\"\(value!)\"")
+            return .expectedFailure("\"\(value!)\"")
         }
     }
 }
 
-public func XCTAssertNotEqual<T: Equatable>(@autoclosure expression1: () throws -> T?, @autoclosure _ expression2: () throws -> T?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqual, message: message, file: file, line: line) {
+public func XCTAssertNotEqual<T: Equatable>(@autoclosure _ expression1: () throws -> T?, @autoclosure _ expression2: () throws -> T?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 != value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNotEqual<T: Equatable>(@autoclosure expression1: () throws -> ContiguousArray<T>, @autoclosure _ expression2: () throws -> ContiguousArray<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqual, message: message, file: file, line: line) {
+public func XCTAssertNotEqual<T: Equatable>(@autoclosure _ expression1: () throws -> ContiguousArray<T>, @autoclosure _ expression2: () throws -> ContiguousArray<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 != value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNotEqual<T: Equatable>(@autoclosure expression1: () throws -> ArraySlice<T>, @autoclosure _ expression2: () throws -> ArraySlice<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqual, message: message, file: file, line: line) {
+public func XCTAssertNotEqual<T: Equatable>(@autoclosure _ expression1: () throws -> ArraySlice<T>, @autoclosure _ expression2: () throws -> ArraySlice<T>, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 != value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNotEqual<T: Equatable>(@autoclosure expression1: () throws -> [T], @autoclosure _ expression2: () throws -> [T], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqual, message: message, file: file, line: line) {
+public func XCTAssertNotEqual<T: Equatable>(@autoclosure _ expression1: () throws -> [T], @autoclosure _ expression2: () throws -> [T], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 != value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNotEqual<T, U: Equatable>(@autoclosure expression1: () throws -> [T: U], @autoclosure _ expression2: () throws -> [T: U], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqual, message: message, file: file, line: line) {
+public func XCTAssertNotEqual<T, U: Equatable>(@autoclosure _ expression1: () throws -> [T: U], @autoclosure _ expression2: () throws -> [T: U], @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqual, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if value1 != value2 {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\")")
         }
     }
 }
 
-public func XCTAssertNotEqualWithAccuracy<T: FloatingPoint>(@autoclosure expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, _ accuracy: T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotEqualWithAccuracy, message: message, file: file, line: line) {
+public func XCTAssertNotEqualWithAccuracy<T: FloatingPoint>(@autoclosure _ expression1: () throws -> T, @autoclosure _ expression2: () throws -> T, _ accuracy: T, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notEqualWithAccuracy, message: message, file: file, line: line) {
         let (value1, value2) = (try expression1(), try expression2())
         if abs(value1.distance(to: value2)) > abs(accuracy.distance(to: T(0))) {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("(\"\(value1)\") is equal to (\"\(value2)\") +/- (\"\(accuracy)\")")
+            return .expectedFailure("(\"\(value1)\") is equal to (\"\(value2)\") +/- (\"\(accuracy)\")")
         }
     }
 }
 
-public func XCTAssertNotNil(@autoclosure expression: () throws -> Any?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.NotNil, message: message, file: file, line: line) {
+public func XCTAssertNotNil(@autoclosure _ expression: () throws -> Any?, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.notNil, message: message, file: file, line: line) {
         let value = try expression()
         if value != nil {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure(nil)
+            return .expectedFailure(nil)
         }
     }
 }
 
-public func XCTAssertTrue(@autoclosure expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.True, message: message, file: file, line: line) {
+public func XCTAssertTrue(@autoclosure _ expression: () throws -> Boolean, @autoclosure _ message: () -> String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.`true`, message: message, file: file, line: line) {
         let value = try expression()
         if value.boolValue {
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure(nil)
+            return .expectedFailure(nil)
         }
     }
 }
 
-public func XCTFail(message: String = "", file: StaticString = #file, line: UInt = #line) {
-    _XCTEvaluateAssertion(.Fail, message: message, file: file, line: line) {
-        return .ExpectedFailure(nil)
+public func XCTFail(_ message: String = "", file: StaticString = #file, line: UInt = #line) {
+    _XCTEvaluateAssertion(.fail, message: message, file: file, line: line) {
+        return .expectedFailure(nil)
     }
 }
 
-public func XCTAssertThrowsError<T>(@autoclosure expression: () throws -> T, _ message: String = "", file: StaticString = #file, line: UInt = #line, _ errorHandler: (error: ErrorProtocol) -> Void = { _ in }) {
-    _XCTEvaluateAssertion(.ThrowsError, message: message, file: file, line: line) {
+public func XCTAssertThrowsError<T>(@autoclosure _ expression: () throws -> T, _ message: String = "", file: StaticString = #file, line: UInt = #line, _ errorHandler: (error: ErrorProtocol) -> Void = { _ in }) {
+    _XCTEvaluateAssertion(.throwsError, message: message, file: file, line: line) {
         var caughtErrorOptional: ErrorProtocol?
         do {
             _ = try expression()
@@ -389,9 +393,9 @@
 
         if let caughtError = caughtErrorOptional {
             errorHandler(error: caughtError)
-            return .Success
+            return .success
         } else {
-            return .ExpectedFailure("did not throw error")
+            return .expectedFailure("did not throw error")
         }
     }
 }
diff --git a/Sources/XCTest/XCTestCase.swift b/Sources/XCTest/XCTestCase.swift
index 3ee4013..21d615e 100644
--- a/Sources/XCTest/XCTestCase.swift
+++ b/Sources/XCTest/XCTestCase.swift
@@ -24,34 +24,118 @@
 /// - seealso: `XCTMain`
 public typealias XCTestCaseEntry = (testCaseClass: XCTestCase.Type, allTests: [(String, XCTestCase throws -> Void)])
 
-public class XCTestCase {
+// A global pointer to the currently running test case. This is required in
+// order for XCTAssert functions to report failures.
+internal var XCTCurrentTestCase: XCTestCase?
 
-    /// The name of the test case, consisting of its class name and the method name it will run.
-    /// - Note: FIXME: This property should be readonly, but currently has to be publicly settable due to a
-    ///         toolchain bug on Linux. To ensure compatibility of tests between
-    ///         swift-corelibs-xctest and Apple XCTest, this property should not be modified.
-    public var name: String
+public class XCTestCase: XCTest {
+    private let testClosure: XCTestCase throws -> Void
 
-    public required init() {
-        name = "\(self.dynamicType).<unknown>"
+    /// The name of the test case, consisting of its class name and the method
+    /// name it will run.
+    public override var name: String {
+        return _name
+    }
+    /// A private setter for the name of this test case.
+    /// - Note: FIXME: This property should be readonly, but currently has to
+    ///   be publicly settable due to a Swift compiler bug on Linux. To ensure
+    ///   compatibility of tests between swift-corelibs-xctest and Apple XCTest,
+    ///   this property should not be modified. See
+    ///   https://bugs.swift.org/browse/SR-1129 for details.
+    public var _name: String
+
+    public override var testCaseCount: UInt {
+        return 1
     }
 
-    public func setUp() {
+    /// The set of expectations made upon this test case.
+    /// - Note: FIXME: This is meant to be a `private var`, but is marked as
+    ///   `public` here to work around a Swift compiler bug on Linux. To ensure
+    ///   compatibility of tests between swift-corelibs-xctest and Apple XCTest,
+    ///   this property should not be modified. See
+    ///   https://bugs.swift.org/browse/SR-1129 for details.
+    public var _allExpectations = [XCTestExpectation]()
+
+    public override var testRunClass: AnyClass? {
+        return XCTestCaseRun.self
     }
 
-    public func tearDown() {
+    public override func perform(_ run: XCTestRun) {
+        guard let testRun = run as? XCTestCaseRun else {
+            fatalError("Wrong XCTestRun class.")
+        }
+
+        XCTCurrentTestCase = self
+        testRun.start()
+        invokeTest()
+        failIfExpectationsNotWaitedFor(_allExpectations)
+        testRun.stop()
+        XCTCurrentTestCase = nil
+    }
+
+    /// The designated initializer for SwiftXCTest's XCTestCase.
+    /// - Note: Like the designated initializer for Apple XCTest's XCTestCase,
+    ///   `-[XCTestCase initWithInvocation:]`, it's rare for anyone outside of
+    ///   XCTest itself to call this initializer.
+    public required init(name: String, testClosure: XCTestCase throws -> Void) {
+        _name = "\(self.dynamicType).\(name)"
+        self.testClosure = testClosure
+    }
+
+    /// Invoking a test performs its setUp, invocation, and tearDown. In
+    /// general this should not be called directly.
+    public func invokeTest() {
+        setUp()
+        do {
+            try testClosure(self)
+        } catch {
+            recordFailure(
+                withDescription: "threw error \"\(error)\"",
+                inFile: "<EXPR>",
+                atLine: 0,
+                expected: false)
+        }
+        tearDown()
+    }
+
+    /// Records a failure in the execution of the test and is used by all test
+    /// assertions.
+    /// - Parameter description: The description of the failure being reported.
+    /// - Parameter filePath: The file path to the source file where the failure
+    ///   being reported was encountered.
+    /// - Parameter lineNumber: The line number in the source file at filePath
+    ///   where the failure being reported was encountered.
+    /// - Parameter expected: `true` if the failure being reported was the
+    ///   result of a failed assertion, `false` if it was the result of an
+    ///   uncaught exception.
+    public func recordFailure(withDescription description: String, inFile filePath: String, atLine lineNumber: UInt, expected: Bool) {
+        testRun?.recordFailure(
+            withDescription: description,
+            inFile: filePath,
+            atLine: lineNumber,
+            expected: expected)
+
+        // FIXME: Apple XCTest does not throw a fatal error and crash the test
+        //        process, it merely prevents the remainder of a testClosure
+        //        from execting after it's been determined that it has already
+        //        failed. The following behavior is incorrect.
+        // FIXME: No regression tests exist for this feature. We may break it
+        //        without ever realizing.
+        if !continueAfterFailure {
+            fatalError("Terminating execution due to test failure")
+        }
     }
 }
 
 /// Wrapper function allowing an array of static test case methods to fit
 /// the signature required by `XCTMain`
 /// - seealso: `XCTMain`
-public func testCase<T: XCTestCase>(allTests: [(String, T -> () throws -> Void)]) -> XCTestCaseEntry {
+public func testCase<T: XCTestCase>(_ allTests: [(String, T -> () throws -> Void)]) -> XCTestCaseEntry {
     let tests: [(String, XCTestCase throws -> Void)] = allTests.map { ($0.0, test($0.1)) }
     return (T.self, tests)
 }
 
-private func test<T: XCTestCase>(testFunc: T -> () throws -> Void) -> XCTestCase throws -> Void {
+private func test<T: XCTestCase>(_ testFunc: T -> () throws -> Void) -> XCTestCase throws -> Void {
     return { testCaseType in
         guard let testCase = testCaseType as? T else {
             fatalError("Attempt to invoke test on class \(T.self) with incompatible instance type \(testCaseType.dynamicType)")
@@ -61,12 +145,6 @@
     }
 }
 
-// FIXME: Expectations should be stored in an instance variable defined on
-//        `XCTestCase`, but when so defined Linux tests fail with "hidden symbol
-//        isn't defined". Use a global for the time being, as this seems to
-//        appease the Linux compiler.
-private var XCTAllExpectations = [XCTestExpectation]()
-
 extension XCTestCase {
     
     public var continueAfterFailure: Bool {
@@ -81,90 +159,15 @@
         }
     }
 
-    internal static func invokeTests(tests: [(String, XCTestCase throws -> Void)]) {
-        let observationCenter = XCTestObservationCenter.shared()
-
-        var totalDuration = 0.0
-        var totalFailures = 0
-        var unexpectedFailures = 0
-        let overallDuration = measureTimeExecutingBlock {
-            for (name, test) in tests {
-                let testCase = self.init()
-                testCase.name = "\(testCase.dynamicType).\(name)"
-
-                var failures = [XCTFailure]()
-                XCTFailureHandler = { failure in
-                    observationCenter.testCase(testCase,
-                                               didFailWithDescription: failure.failureMessage,
-                                               inFile: String(failure.file),
-                                               atLine: failure.line)
-
-                    if !testCase.continueAfterFailure {
-                        failure.emit(testCase.name)
-                        fatalError("Terminating execution due to test failure", file: failure.file, line: failure.line)
-                    } else {
-                        failures.append(failure)
-                    }
-                }
-
-                XCTPrint("Test Case '\(testCase.name)' started.")
-
-                observationCenter.testCaseWillStart(testCase)
-
-                testCase.setUp()
-
-                let duration = measureTimeExecutingBlock {
-                    do {
-                        try test(testCase)
-                    } catch {
-                        let unexpectedFailure = XCTFailure(message: "", failureDescription: "threw error \"\(error)\"", expected: false, file: "<EXPR>", line: 0)
-                        XCTFailureHandler!(unexpectedFailure)
-                    }
-                }
-
-                testCase.tearDown()
-                testCase.failIfExpectationsNotWaitedFor(XCTAllExpectations)
-                XCTAllExpectations = []
-
-                observationCenter.testCaseDidFinish(testCase)
-
-                totalDuration += duration
-
-                var result = "passed"
-                for failure in failures {
-                    failure.emit(testCase.name)
-                    totalFailures += 1
-                    if !failure.expected {
-                        unexpectedFailures += 1
-                    }
-                    result = failures.count > 0 ? "failed" : "passed"
-                }
-
-                XCTPrint("Test Case '\(testCase.name)' \(result) (\(printableStringForTimeInterval(duration)) seconds).")
-                XCTAllRuns.append(XCTRun(duration: duration, method: testCase.name, passed: failures.count == 0, failures: failures))
-                XCTFailureHandler = nil
-            }
-        }
-
-        let testCountSuffix = (tests.count == 1) ? "" : "s"
-        let failureSuffix = (totalFailures == 1) ? "" : "s"
-
-        XCTPrint("Executed \(tests.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(unexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
-    }
-
     /// It is an API violation to create expectations but not wait for them to
     /// be completed. Notify the user of a mistake via a test failure.
-    private func failIfExpectationsNotWaitedFor(expectations: [XCTestExpectation]) {
+    private func failIfExpectationsNotWaitedFor(_ expectations: [XCTestExpectation]) {
         if expectations.count > 0 {
-            let failure = XCTFailure(
-                message: "Failed due to unwaited expectations.",
-                failureDescription: "",
-                expected: false,
-                file: expectations.last!.file,
-                line: expectations.last!.line)
-            if let failureHandler = XCTFailureHandler {
-                failureHandler(failure)
-            }
+            recordFailure(
+                withDescription: "Failed due to unwaited expectations.",
+                inFile: String(expectations.last!.file),
+                atLine: expectations.last!.line,
+                expected: false)
         }
     }
 
@@ -188,13 +191,13 @@
     ///   between these environments. To ensure compatibility of tests between
     ///   swift-corelibs-xctest and Apple XCTest, it is not recommended to pass
     ///   explicit values for `file` and `line`.
-    public func expectationWithDescription(description: String, file: StaticString = #file, line: UInt = #line) -> XCTestExpectation {
+    public func expectation(withDescription description: String, file: StaticString = #file, line: UInt = #line) -> XCTestExpectation {
         let expectation = XCTestExpectation(
             description: description,
             file: file,
             line: line,
             testCase: self)
-        XCTAllExpectations.append(expectation)
+        _allExpectations.append(expectation)
         return expectation
     }
 
@@ -223,7 +226,7 @@
     ///   these environments. To ensure compatibility of tests between
     ///   swift-corelibs-xctest and Apple XCTest, it is not recommended to pass
     ///   explicit values for `file` and `line`.
-    public func waitForExpectationsWithTimeout(timeout: NSTimeInterval, file: StaticString = #file, line: UInt = #line, handler: XCWaitCompletionHandler?) {
+    public func waitForExpectations(withTimeout timeout: NSTimeInterval, file: StaticString = #file, line: UInt = #line, handler: XCWaitCompletionHandler? = nil) {
         // Mirror Objective-C XCTest behavior; display an unexpected test
         // failure when users wait without having first set expectations.
         // FIXME: Objective-C XCTest raises an exception for most "API
@@ -231,16 +234,12 @@
         //        the test to stop cold. swift-corelibs-xctest does not stop,
         //        and executes the rest of the test. This discrepancy should be
         //        fixed.
-        if XCTAllExpectations.count == 0 {
-            let failure = XCTFailure(
-                message: "call made to wait without any expectations having been set.",
-                failureDescription: "API violation",
-                expected: false,
-                file: file,
-                line: line)
-            if let failureHandler = XCTFailureHandler {
-                failureHandler(failure)
-            }
+        if _allExpectations.count == 0 {
+            recordFailure(
+                withDescription: "API violation - call made to wait without any expectations having been set.",
+                inFile: String(file),
+                atLine: line,
+                expected: false)
             return
         }
 
@@ -260,8 +259,8 @@
         let timeoutDate = NSDate(timeIntervalSinceNow: timeout)
         repeat {
             unfulfilledDescriptions = []
-            for expectation in XCTAllExpectations {
-                if !expectation.fulfilled {
+            for expectation in _allExpectations {
+                if !expectation.isFulfilled {
                     unfulfilledDescriptions.append(expectation.description)
                 }
             }
@@ -280,20 +279,16 @@
             // Not all expectations were fulfilled. Append a failure
             // to the array of expectation-based failures.
             let descriptions = unfulfilledDescriptions.joined(separator: ", ")
-            let failure = XCTFailure(
-                message: "Exceeded timeout of \(timeout) seconds, with unfulfilled expectations: \(descriptions)",
-                failureDescription: "Asynchronous wait failed",
-                expected: true,
-                file: file,
-                line: line)
-            if let failureHandler = XCTFailureHandler {
-                failureHandler(failure)
-            }
+            recordFailure(
+                withDescription: "Asynchronous wait failed - Exceeded timeout of \(timeout) seconds, with unfulfilled expectations: \(descriptions)",
+                inFile: String(file),
+                atLine: line,
+                expected: true)
         }
 
         // We've recorded all the failures; clear the expectations that
         // were set for this test case.
-        XCTAllExpectations = []
+        _allExpectations = []
 
         // The handler is invoked regardless of whether the test passed.
         if let completionHandler = handler {
@@ -301,8 +296,8 @@
             if unfulfilledDescriptions.count > 0 {
                 // If the test failed, send an error object.
                 error = NSError(
-                    domain: "org.swift.XCTestErrorDomain",
-                    code: 0,
+                    domain: XCTestErrorDomain,
+                    code: XCTestErrorCode.timeoutWhileWaiting.rawValue,
                     userInfo: [:])
             }
             completionHandler(error)
@@ -321,11 +316,18 @@
     ///   notification is observed. It will not be invoked on timeout. Use the
     ///   handler to further investigate if the notification fulfills the 
     ///   expectation.
-    public func expectationForNotification(notificationName: String, object objectToObserve: AnyObject?, handler: XCNotificationExpectationHandler?) -> XCTestExpectation {
+    public func expectation(forNotification notificationName: String, object objectToObserve: AnyObject?, handler: XCNotificationExpectationHandler? = nil) -> XCTestExpectation {
         let objectDescription = objectToObserve == nil ? "any object" : "\(objectToObserve!)"
-        let expectation = self.expectationWithDescription("Expect notification '\(notificationName)' from " + objectDescription)
+        let expectation = self.expectation(withDescription: "Expect notification '\(notificationName)' from " + objectDescription)
         // Start observing the notification with specified name and object.
         var observer: NSObjectProtocol? = nil
+        func removeObserver() {
+            if let observer = observer as? AnyObject {
+                NSNotificationCenter.defaultCenter().removeObserver(observer)
+            }
+        }
+
+        weak var weakExpectation = expectation
         observer = NSNotificationCenter
             .defaultCenter()
             .addObserverForName(notificationName,
@@ -333,20 +335,21 @@
                                 queue: nil,
                                 usingBlock: {
                                     notification in
+                                    guard let expectation = weakExpectation else {
+                                        removeObserver()
+                                        return
+                                    }
+
                                     // If the handler is invoked, the test will
                                     // only pass if true is returned.
                                     if let handler = handler {
                                         if handler(notification) {
                                             expectation.fulfill()
-                                            if let observer = observer as? AnyObject {
-                                                NSNotificationCenter.defaultCenter().removeObserver(observer)
-                                            }
+                                            removeObserver()
                                         }
                                     } else {
                                         expectation.fulfill()
-                                        if let observer = observer as? AnyObject {
-                                            NSNotificationCenter.defaultCenter().removeObserver(observer)
-                                        }
+                                        removeObserver()
                                     }
                 })
         
diff --git a/Sources/XCTest/XCTestCaseRun.swift b/Sources/XCTest/XCTestCaseRun.swift
new file mode 100644
index 0000000..b9e2a75
--- /dev/null
+++ b/Sources/XCTest/XCTestCaseRun.swift
@@ -0,0 +1,42 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCTestCaseRun.swift
+//  A test run for an `XCTestCase`.
+//
+
+/// A test run for an `XCTestCase`.
+public class XCTestCaseRun: XCTestRun {
+    public override func start() {
+        super.start()
+        XCTestObservationCenter.shared().testCaseWillStart(testCase)
+    }
+
+    public override func stop() {
+        super.stop()
+        XCTestObservationCenter.shared().testCaseDidFinish(testCase)
+    }
+
+    public override func recordFailure(withDescription description: String, inFile filePath: String?, atLine lineNumber: UInt, expected: Bool) {
+        super.recordFailure(
+            withDescription: "\(test.name) : \(description)",
+            inFile: filePath,
+            atLine: lineNumber,
+            expected: expected)
+        XCTestObservationCenter.shared().testCase(
+            testCase,
+            didFailWithDescription: description,
+            inFile: filePath,
+            atLine: lineNumber)
+    }
+
+    private var testCase: XCTestCase {
+        return test as! XCTestCase
+    }
+}
diff --git a/Sources/XCTest/XCTestErrors.swift b/Sources/XCTest/XCTestErrors.swift
new file mode 100644
index 0000000..0854972
--- /dev/null
+++ b/Sources/XCTest/XCTestErrors.swift
@@ -0,0 +1,27 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCTestErrors.swift
+//  Constants used in errors produced by the XCTest library.
+//
+
+/// The domain used by errors produced by the XCTest library.
+public let XCTestErrorDomain = "org.swift.XCTestErrorDomain"
+
+/// Error codes for errors in the XCTestErrorDomain.
+public enum XCTestErrorCode : Int {
+    /// Indicates that one or more expectations failed to be fulfilled in time
+    /// during a call to `waitForExpectations(withTimeout:handler:)`
+    case timeoutWhileWaiting
+
+    /// Indicates that a test assertion failed while waiting for expectations
+    /// during a call to `waitForExpectations(withTimeout:handler:)`
+    /// FIXME: swift-corelibs-xctest does not currently produce this error code.
+    case failureWhileWaiting
+}
diff --git a/Sources/XCTest/XCTestExpectation.swift b/Sources/XCTest/XCTestExpectation.swift
index dc20512..5a9631f 100644
--- a/Sources/XCTest/XCTestExpectation.swift
+++ b/Sources/XCTest/XCTestExpectation.swift
@@ -17,7 +17,7 @@
     internal let file: StaticString
     internal let line: UInt
 
-    internal var fulfilled = false
+    internal var isFulfilled = false
     internal weak var testCase: XCTestCase?
 
     internal init(description: String, file: StaticString, line: UInt, testCase: XCTestCase) {
@@ -47,25 +47,23 @@
     ///   between these environments. To ensure compatibility of tests between
     ///   swift-corelibs-xctest and Apple XCTest, it is not recommended to pass
     ///   explicit values for `file` and `line`.
-    public func fulfill(file: StaticString = #file, line: UInt = #line) {
+    public func fulfill(_ file: StaticString = #file, line: UInt = #line) {
         // FIXME: Objective-C XCTest emits failures when expectations are
         //        fulfilled after the test cases that generated those
         //        expectations have completed. Similarly, this should cause an
         //        error as well.
-        if fulfilled {
+        if isFulfilled {
             // Mirror Objective-C XCTest behavior: treat multiple calls to
             // fulfill() as an unexpected failure.
-            let failure = XCTFailure(
-                message: "multiple calls made to XCTestExpectation.fulfill() for \(description).",
-                failureDescription: "API violation",
-                expected: false,
-                file: file,
-                line: line)
-            if let failureHandler = XCTFailureHandler {
-                failureHandler(failure)
+            if let testCase = XCTCurrentTestCase {
+                testCase.recordFailure(
+                    withDescription: "API violation - multiple calls made to XCTestExpectation.fulfill() for \(description).",
+                    inFile: String(file),
+                    atLine: line,
+                    expected: false)
             }
         } else {
-            fulfilled = true
+            isFulfilled = true
         }
     }
 }
diff --git a/Sources/XCTest/XCTestMain.swift b/Sources/XCTest/XCTestMain.swift
index 3f3d95f..e88c15d 100644
--- a/Sources/XCTest/XCTestMain.swift
+++ b/Sources/XCTest/XCTestMain.swift
@@ -20,35 +20,6 @@
     import SwiftFoundation
 #endif
 
-internal func XCTPrint(message: String) {
-    print(message)
-    fflush(stdout)
-}
-
-struct XCTFailure {
-    var message: String
-    var failureDescription: String
-    var expected: Bool
-    var file: StaticString
-    var line: UInt
-
-    var failureMessage: String { return "\(failureDescription) - \(message)" }
-
-    func emit(method: String) {
-        XCTPrint("\(file):\(line): \(expected ? "" : "unexpected ")error: \(method) : \(failureMessage)")
-    }
-}
-
-internal struct XCTRun {
-    var duration: NSTimeInterval
-    var method: String
-    var passed: Bool
-    var failures: [XCTFailure]
-    var unexpectedFailures: [XCTFailure] {
-        get { return failures.filter({ failure -> Bool in failure.expected == false }) }
-    }
-}
-
 /// Starts a test run for the specified test cases.
 ///
 /// This function will not return. If the test cases pass, then it will call `exit(0)`. If there is a failure, then it will call `exit(1)`.
@@ -78,34 +49,43 @@
 ///
 /// - Parameter testCases: An array of test cases run, each produced by a call to the `testCase` function
 /// - seealso: `testCase`
-@noreturn public func XCTMain(testCases: [XCTestCaseEntry]) {
+@noreturn public func XCTMain(_ testCases: [XCTestCaseEntry]) {
+    // Add a test observer that prints test progress to stdout.
     let observationCenter = XCTestObservationCenter.shared()
+    observationCenter.addTestObserver(PrintObserver())
+
+    // Announce that the test bundle will start executing.
     let testBundle = NSBundle.mainBundle()
     observationCenter.testBundleWillStart(testBundle)
 
-    let filter = TestFiltering()
+    // Apple XCTest behaves differently if tests have been filtered:
+    // - The root `XCTestSuite` is named "Selected tests" instead of
+    //   "All tests".
+    // - An `XCTestSuite` representing the .xctest test bundle is not included.
+    let selectedTestName = ArgumentParser().selectedTestName
+    let rootTestSuite: XCTestSuite
+    let currentTestSuite: XCTestSuite
+    if selectedTestName == nil {
+        rootTestSuite = XCTestSuite(name: "All tests")
+        currentTestSuite = XCTestSuite(name: "\(testBundle.bundlePath.lastPathComponent).xctest")
+        rootTestSuite.addTest(currentTestSuite)
+    } else {
+        rootTestSuite = XCTestSuite(name: "Selected tests")
+        currentTestSuite = rootTestSuite
+    }
 
-    let overallDuration = measureTimeExecutingBlock {
-        for (testCase, tests) in TestFiltering.filterTests(testCases, filter: filter.selectedTestFilter) {
-            testCase.invokeTests(tests)
+    let filter = TestFiltering(selectedTestName: selectedTestName)
+    for (testCaseType, tests) in TestFiltering.filterTests(testCases, filter: filter.selectedTestFilter) {
+        let testCaseSuite = XCTestSuite(name: "\(testCaseType)")
+        for (testName, testClosure) in tests {
+            let testCase = testCaseType.init(name: testName, testClosure: testClosure)
+            testCaseSuite.addTest(testCase)
         }
+        currentTestSuite.addTest(testCaseSuite)
     }
 
-    let (totalDuration, totalFailures, totalUnexpectedFailures) = XCTAllRuns.reduce((0.0, 0, 0)) { totals, run in (totals.0 + run.duration, totals.1 + run.failures.count, totals.2 + run.unexpectedFailures.count) }
-    
-    var testCountSuffix = "s"
-    if XCTAllRuns.count == 1 {
-        testCountSuffix = ""
-    }
-    var failureSuffix = "s"
-    if totalFailures == 1 {
-        failureSuffix = ""
-    }
+    rootTestSuite.run()
 
-    XCTPrint("Total executed \(XCTAllRuns.count) test\(testCountSuffix), with \(totalFailures) failure\(failureSuffix) (\(totalUnexpectedFailures) unexpected) in \(printableStringForTimeInterval(totalDuration)) (\(printableStringForTimeInterval(overallDuration))) seconds")
     observationCenter.testBundleDidFinish(testBundle)
-    exit(totalFailures > 0 ? 1 : 0)
+    exit(rootTestSuite.testRun!.totalFailureCount == 0 ? 0 : 1)
 }
-
-internal var XCTFailureHandler: (XCTFailure -> Void)?
-internal var XCTAllRuns = [XCTRun]()
diff --git a/Sources/XCTest/XCTestObservation.swift b/Sources/XCTest/XCTestObservation.swift
index 891f9ca..ce094c4 100644
--- a/Sources/XCTest/XCTestObservation.swift
+++ b/Sources/XCTest/XCTestObservation.swift
@@ -25,12 +25,17 @@
     /// Sent immediately before tests begin as a hook for any pre-testing setup.
     /// - Parameter testBundle: The bundle containing the tests that were
     ///   executed.
-    func testBundleWillStart(testBundle: NSBundle)
+    func testBundleWillStart(_ testBundle: NSBundle)
+
+    /// Sent when a test suite starts executing.
+    /// - Parameter testSuite: The test suite that started. Additional
+    ///   information can be retrieved from the associated XCTestRun.
+    func testSuiteWillStart(_ testSuite: XCTestSuite)
 
     /// Called just before a test begins executing.
     /// - Parameter testCase: The test case that is about to start. Its `name`
     ///   property can be used to identify it.
-    func testCaseWillStart(testCase: XCTestCase)
+    func testCaseWillStart(_ testCase: XCTestCase)
 
     /// Called when a test failure is reported.
     /// - Parameter testCase: The test case that failed. Its `name` property 
@@ -40,12 +45,17 @@
     ///   was reported, if available.
     /// - Parameter lineNumber: The line number in the source file where the
     ///   failure was reported.
-    func testCase(testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt)
+    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt)
 
     /// Called just after a test finishes executing.
     /// - Parameter testCase: The test case that finished. Its `name` property 
     ///   can be used to identify it.
-    func testCaseDidFinish(testCase: XCTestCase)
+    func testCaseDidFinish(_ testCase: XCTestCase)
+
+    /// Sent when a test suite finishes executing.
+    /// - Parameter testSuite: The test suite that finished. Additional
+    ///   information can be retrieved from the associated XCTestRun.
+    func testSuiteDidFinish(_ testSuite: XCTestSuite)
 
     /// Sent immediately after all tests have finished as a hook for any
     /// post-testing activity. The test process will generally exit after this
@@ -54,12 +64,16 @@
     /// it blocks until all such activity is complete.
     /// - Parameter testBundle: The bundle containing the tests that were
     ///   executed.
-    func testBundleDidFinish(testBundle: NSBundle)
+    func testBundleDidFinish(_ testBundle: NSBundle)
 }
 
 // All `XCTestObservation` methods are optional, so empty default implementations are provided
 public extension XCTestObservation {
-    func testCaseWillStart(testCase: XCTestCase) {}
-    func testCase(testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {}
-    func testCaseDidFinish(testCase: XCTestCase) {}
+    func testBundleWillStart(_ testBundle: NSBundle) {}
+    func testSuiteWillStart(_ testSuite: XCTestSuite) {}
+    func testCaseWillStart(_ testCase: XCTestCase) {}
+    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {}
+    func testCaseDidFinish(_ testCase: XCTestCase) {}
+    func testSuiteDidFinish(_ testSuite: XCTestSuite) {}
+    func testBundleDidFinish(_ testBundle: NSBundle) {}
 }
diff --git a/Sources/XCTest/XCTestObservationCenter.swift b/Sources/XCTest/XCTestObservationCenter.swift
index b9d7042..ca2fb29 100644
--- a/Sources/XCTest/XCTestObservationCenter.swift
+++ b/Sources/XCTest/XCTestObservationCenter.swift
@@ -33,37 +33,45 @@
 
     /// Register an observer to receive future events during a test run. The order
     /// in which individual observers are notified about events is undefined.
-    public func addTestObserver(testObserver: XCTestObservation) {
+    public func addTestObserver(_ testObserver: XCTestObservation) {
         observers.insert(testObserver.wrapper)
     }
 
     /// Remove a previously-registered observer so that it will no longer receive
     /// event callbacks.
-    public func removeTestObserver(testObserver: XCTestObservation) {
+    public func removeTestObserver(_ testObserver: XCTestObservation) {
         observers.remove(testObserver.wrapper)
     }
 
-    internal func testBundleWillStart(testBundle: NSBundle) {
+    internal func testBundleWillStart(_ testBundle: NSBundle) {
         forEachObserver { $0.testBundleWillStart(testBundle) }
     }
 
-    internal func testCaseWillStart(testCase: XCTestCase) {
+    internal func testSuiteWillStart(_ testSuite: XCTestSuite) {
+        forEachObserver { $0.testSuiteWillStart(testSuite) }
+    }
+
+    internal func testCaseWillStart(_ testCase: XCTestCase) {
         forEachObserver { $0.testCaseWillStart(testCase) }
     }
 
-    internal func testCase(testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
+    internal func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
         forEachObserver { $0.testCase(testCase, didFailWithDescription: description, inFile: filePath, atLine: lineNumber) }
     }
 
-    internal func testCaseDidFinish(testCase: XCTestCase) {
+    internal func testCaseDidFinish(_ testCase: XCTestCase) {
         forEachObserver { $0.testCaseDidFinish(testCase) }
     }
 
-    internal func testBundleDidFinish(testBundle: NSBundle) {
+    internal func testSuiteDidFinish(_ testSuite: XCTestSuite) {
+        forEachObserver { $0.testSuiteDidFinish(testSuite) }
+    }
+
+    internal func testBundleDidFinish(_ testBundle: NSBundle) {
         forEachObserver { $0.testBundleDidFinish(testBundle) }
     }
 
-    private func forEachObserver(@noescape body: XCTestObservation -> Void) {
+    private func forEachObserver(@noescape _ body: XCTestObservation -> Void) {
         for observer in observers {
             body(observer.object)
         }
diff --git a/Sources/XCTest/XCTestRun.swift b/Sources/XCTest/XCTestRun.swift
new file mode 100644
index 0000000..e6899d3
--- /dev/null
+++ b/Sources/XCTest/XCTestRun.swift
@@ -0,0 +1,151 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCTestRun.swift
+//  A test run collects information about the execution of a test.
+//
+
+#if os(Linux) || os(FreeBSD)
+    import Foundation
+#else
+    import SwiftFoundation
+#endif
+
+/// A test run collects information about the execution of a test. Failures in
+/// explicit test assertions are classified as "expected", while failures from
+/// unrelated or uncaught exceptions are classified as "unexpected".
+public class XCTestRun {
+    /// The test instance provided when the test run was initialized.
+    public let test: XCTest
+
+    /// The time at which the test run was started, or nil.
+    public private(set) var startDate: NSDate?
+
+    /// The time at which the test run was stopped, or nil.
+    public private(set) var stopDate: NSDate?
+
+    /// The number of seconds that elapsed between when the run was started and
+    /// when it was stopped.
+    public var totalDuration: NSTimeInterval {
+        if let stop = stopDate, start = startDate {
+            return stop.timeIntervalSinceDate(start)
+        } else {
+            return 0.0
+        }
+    }
+
+    /// In an `XCTestCase` run, the number of seconds that elapsed between when
+    /// the run was started and when it was stopped. In an `XCTestSuite` run,
+    /// the combined `testDuration` of each test case in the suite.
+    public var testDuration: NSTimeInterval {
+        return totalDuration
+    }
+
+    /// The number of tests in the run.
+    public var testCaseCount: UInt {
+        return test.testCaseCount
+    }
+
+    /// The number of test executions recorded during the run.
+    public private(set) var executionCount: UInt = 0
+
+    /// The number of test failures recorded during the run.
+    public private(set) var failureCount: UInt = 0
+
+    /// The number of uncaught exceptions recorded during the run.
+    public private(set) var unexpectedExceptionCount: UInt = 0
+
+    /// The total number of test failures and uncaught exceptions recorded
+    /// during the run.
+    public var totalFailureCount: UInt {
+        return failureCount + unexpectedExceptionCount
+    }
+
+    /// `true` if all tests in the run completed their execution without
+    /// recording any failures, otherwise `false`.
+    public var hasSucceeded: Bool {
+        guard isStopped else {
+            return false
+        }
+        return totalFailureCount == 0
+    }
+
+    /// Designated initializer for the XCTestRun class.
+    /// - Parameter test: An XCTest instance.
+    /// - Returns: A test run for the provided test.
+    public required init(test: XCTest) {
+        self.test = test
+    }
+
+    /// Start a test run. Must not be called more than once.
+    public func start() {
+        guard !isStarted else {
+            fatalError("Invalid attempt to start a test run that has " +
+                       "already been started: \(self)")
+        }
+        guard !isStopped else {
+            fatalError("Invalid attempt to start a test run that has " +
+                       "already been stopped: \(self)")
+        }
+
+        startDate = NSDate()
+    }
+
+    /// Stop a test run. Must not be called unless the run has been started.
+    /// Must not be called more than once.
+    public func stop() {
+        guard isStarted else {
+            fatalError("Invalid attempt to stop a test run that has " +
+                       "not yet been started: \(self)")
+        }
+        guard !isStopped else {
+            fatalError("Invalid attempt to stop a test run that has " +
+                       "already been stopped: \(self)")
+        }
+
+        executionCount += 1
+        stopDate = NSDate()
+    }
+
+    /// Records a failure in the execution of the test for this test run. Must
+    /// not be called unless the run has been started. Must not be called if the
+    /// test run has been stopped.
+    /// - Parameter description: The description of the failure being reported.
+    /// - Parameter filePath: The file path to the source file where the failure
+    ///   being reported was encountered or nil if unknown.
+    /// - Parameter lineNumber: The line number in the source file at filePath
+    ///   where the failure being reported was encountered.
+    /// - Parameter expected: `true` if the failure being reported was the
+    ///   result of a failed assertion, `false` if it was the result of an
+    ///   uncaught exception.
+    func recordFailure(withDescription description: String, inFile filePath: String?, atLine lineNumber: UInt, expected: Bool) {
+        guard isStarted else {
+            fatalError("Invalid attempt to record a failure for a test run " +
+                       "that has not yet been started: \(self)")
+        }
+        guard !isStopped else {
+            fatalError("Invalid attempt to record a failure for a test run " +
+                       "that has already been stopped: \(self)")
+        }
+
+        if expected {
+            failureCount += 1
+        } else {
+            unexpectedExceptionCount += 1
+        }
+    }
+
+    private var isStarted: Bool {
+        return startDate != nil
+    }
+
+    private var isStopped: Bool {
+        return isStarted && stopDate != nil
+    }
+}
diff --git a/Sources/XCTest/XCTestSuite.swift b/Sources/XCTest/XCTestSuite.swift
new file mode 100644
index 0000000..fe7e307
--- /dev/null
+++ b/Sources/XCTest/XCTestSuite.swift
@@ -0,0 +1,83 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCTestSuite.swift
+//  A collection of test cases.
+//
+
+/// A concrete subclass of XCTest, XCTestSuite is a collection of test cases.
+/// Suites are usually managed by the IDE, but XCTestSuite also provides API
+/// for dynamic test and suite management:
+///
+///     XCTestSuite *suite = [XCTestSuite testSuiteWithName:@"My tests"];
+///     [suite addTest:[MathTest testCaseWithSelector:@selector(testAdd)]];
+///     [suite addTest:[MathTest testCaseWithSelector:@selector(testDivideByZero)]];
+///
+/// Alternatively, a test suite can extract the tests to be run automatically.
+/// To do so, pass the class of your test case class to the suite's constructor:
+///
+///     XCTestSuite *suite = [XCTestSuite testSuiteForTestCaseClass:[MathTest class]];
+///
+/// This creates a suite with all the methods starting with "test" that take no
+/// arguments. Also, a test suite of all the test cases found in the runtime
+/// can be created automatically:
+///
+///     XCTestSuite *suite = [XCTestSuite defaultTestSuite];
+///
+/// This creates a suite of suites with all the XCTestCase subclasses methods
+/// that start with "test" and take no arguments.
+public class XCTestSuite: XCTest {
+    public private(set) var tests = [XCTest]()
+
+    /// The name of this test suite.
+    override public var name: String {
+        return _name
+    }
+    /// A private setter for the name of this test suite.
+    /// - Note: FIXME: This property should be readonly, but currently has to
+    ///   be publicly settable due to a Swift compiler bug on Linux. To ensure
+    ///   compatibility of tests between swift-corelibs-xctest and Apple XCTest,
+    ///   this property should not be modified. See
+    ///   https://bugs.swift.org/browse/SR-1129 for details.
+    public let _name: String
+
+    /// The number of test cases in this suite.
+    public override var testCaseCount: UInt {
+        return tests.reduce(0) { $0 + $1.testCaseCount }
+    }
+
+    public override var testRunClass: AnyClass? {
+        return XCTestSuiteRun.self
+    }
+
+    public override func perform(_ run: XCTestRun) {
+        guard let testRun = run as? XCTestSuiteRun else {
+            fatalError("Wrong XCTestRun class.")
+        }
+
+        run.start()
+        setUp()
+        for test in tests {
+            test.run()
+            testRun.addTest(test.testRun!)
+        }
+        tearDown()
+        run.stop()
+    }
+
+    public init(name: String) {
+        _name = name
+    }
+
+    /// Adds a test (either an `XCTestSuite` or an `XCTestCase` to this
+    /// collection.
+    public func addTest(_ test: XCTest) {
+        tests.append(test)
+    }
+}
\ No newline at end of file
diff --git a/Sources/XCTest/XCTestSuiteRun.swift b/Sources/XCTest/XCTestSuiteRun.swift
new file mode 100644
index 0000000..32faeb8
--- /dev/null
+++ b/Sources/XCTest/XCTestSuiteRun.swift
@@ -0,0 +1,67 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//
+//  XCTestSuiteRun.swift
+//  A test run for an `XCTestSuite`.
+//
+
+#if os(Linux) || os(FreeBSD)
+    import Foundation
+#else
+    import SwiftFoundation
+#endif
+
+/// A test run for an `XCTestSuite`.
+public class XCTestSuiteRun: XCTestRun {
+    /// The combined `testDuration` of each test case run in the suite.
+    public override var totalDuration: NSTimeInterval {
+        return testRuns.reduce(NSTimeInterval(0.0)) { $0 + $1.totalDuration }
+    }
+
+    /// The combined execution count of each test case run in the suite.
+    public override var executionCount: UInt {
+        return testRuns.reduce(0) { $0 + $1.executionCount }
+    }
+
+    /// The combined failure count of each test case run in the suite.
+    public override var failureCount: UInt {
+        return testRuns.reduce(0) { $0 + $1.failureCount }
+    }
+
+    /// The combined unexpected failure count of each test case run in the
+    /// suite.
+    public override var unexpectedExceptionCount: UInt {
+        return testRuns.reduce(0) { $0 + $1.unexpectedExceptionCount }
+    }
+
+    public override func start() {
+        super.start()
+        XCTestObservationCenter.shared().testSuiteWillStart(testSuite)
+    }
+
+    public override func stop() {
+        super.stop()
+        XCTestObservationCenter.shared().testSuiteDidFinish(testSuite)
+    }
+
+    /// The test run for each of the tests in this suite.
+    /// Depending on what kinds of tests this suite is composed of, these could
+    /// be some combination of `XCTestCaseRun` and `XCTestSuiteRun` objects.
+    public private(set) var testRuns = [XCTestRun]()
+
+    /// Add a test run to the collection of `testRuns`.
+    /// - Note: It is rare to call this method outside of XCTest itself.
+    public func addTest(_ testRun: XCTestRun) {
+        testRuns.append(testRun)
+    }
+
+    private var testSuite: XCTestSuite {
+        return test as! XCTestSuite
+    }
+}
diff --git a/Sources/XCTest/XCTimeUtilities.swift b/Sources/XCTest/XCTimeUtilities.swift
deleted file mode 100644
index 8ad47b6..0000000
--- a/Sources/XCTest/XCTimeUtilities.swift
+++ /dev/null
@@ -1,44 +0,0 @@
-// This source file is part of the Swift.org open source project
-//
-// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
-// Licensed under Apache License v2.0 with Runtime Library Exception
-//
-// See http://swift.org/LICENSE.txt for license information
-// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
-//
-//
-//  XCTimeUtilities.swift
-//  Some simple functions for working with "time intervals".
-//
-
-#if os(Linux) || os(FreeBSD)
-    import Glibc
-    import Foundation
-#else
-    import Darwin
-    import SwiftFoundation
-#endif
-
-/// Returns the number of seconds since the reference time as a Double.
-private func currentTimeIntervalSinceReferenceTime() -> NSTimeInterval {
-    var tv = timeval()
-    let currentTime = withUnsafeMutablePointer(&tv, { (t: UnsafeMutablePointer<timeval>) -> NSTimeInterval in
-        gettimeofday(t, nil)
-        return NSTimeInterval(t.pointee.tv_sec) + NSTimeInterval(t.pointee.tv_usec) / 1000000.0
-    })
-    return currentTime
-}
-
-/// Execute the given block and return the time spent during execution
-internal func measureTimeExecutingBlock(@noescape block: () -> Void) -> NSTimeInterval {
-    let start = currentTimeIntervalSinceReferenceTime()
-    block()
-    let end = currentTimeIntervalSinceReferenceTime()
-
-    return end - start
-}
-
-/// Returns a string version of the given time interval rounded to no more than 3 decimal places.
-internal func printableStringForTimeInterval(timeInterval: NSTimeInterval) -> String {
-    return String(round(timeInterval * 1000.0) / 1000.0)
-}
diff --git a/Tests/Functional/Asynchronous/Expectations/main.swift b/Tests/Functional/Asynchronous/Expectations/main.swift
index 0f62496..75f55b6 100644
--- a/Tests/Functional/Asynchronous/Expectations/main.swift
+++ b/Tests/Functional/Asynchronous/Expectations/main.swift
@@ -10,69 +10,73 @@
     import SwiftFoundation
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'ExpectationsTestCase' started at \d+:\d+:\d+\.\d+
 class ExpectationsTestCase: XCTestCase {
-// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:19: error: ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: foo
+// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:23: error: ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: foo
 // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnUnfulfilledExpectation_fails' failed \(\d+\.\d+ seconds\).
     func test_waitingForAnUnfulfilledExpectation_fails() {
-        expectationWithDescription("foo")
-        waitForExpectationsWithTimeout(0.2, handler: nil)
+        expectation(withDescription: "foo")
+        waitForExpectations(withTimeout: 0.2)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:28: error: ExpectationsTestCase.test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: bar, baz
+// CHECK: Test Case 'ExpectationsTestCase.test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:32: error: ExpectationsTestCase.test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: bar, baz
 // CHECK: Test Case 'ExpectationsTestCase.test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails' failed \(\d+\.\d+ seconds\).
     func test_waitingForUnfulfilledExpectations_outputsAllExpectations_andFails() {
-        expectationWithDescription("bar")
-        expectationWithDescription("baz")
-        waitForExpectationsWithTimeout(0.2, handler: nil)
+        expectation(withDescription: "bar")
+        expectation(withDescription: "baz")
+        waitForExpectations(withTimeout: 0.2)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnImmediatelyFulfilledExpectation_passes' started.
+// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnImmediatelyFulfilledExpectation_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnImmediatelyFulfilledExpectation_passes' passed \(\d+\.\d+ seconds\).
     func test_waitingForAnImmediatelyFulfilledExpectation_passes() {
-        let expectation = expectationWithDescription("flim")
+        let expectation = self.expectation(withDescription: "flim")
         expectation.fulfill()
-        waitForExpectationsWithTimeout(0.2, handler: nil)
+        waitForExpectations(withTimeout: 0.2)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnEventuallyFulfilledExpectation_passes' started.
+// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnEventuallyFulfilledExpectation_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnEventuallyFulfilledExpectation_passes' passed \(\d+\.\d+ seconds\).
     func test_waitingForAnEventuallyFulfilledExpectation_passes() {
-        let expectation = expectationWithDescription("flam")
+        let expectation = self.expectation(withDescription: "flam")
         let timer = NSTimer.scheduledTimer(0.1, repeats: false) { _ in
             expectation.fulfill()
         }
         NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
-        waitForExpectationsWithTimeout(1.0, handler: nil)
+        waitForExpectations(withTimeout: 1.0)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnExpectationFulfilledAfterTheTimeout_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:59: error: ExpectationsTestCase.test_waitingForAnExpectationFulfilledAfterTheTimeout_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: hog
+// CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnExpectationFulfilledAfterTheTimeout_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:63: error: ExpectationsTestCase.test_waitingForAnExpectationFulfilledAfterTheTimeout_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: hog
 // CHECK: Test Case 'ExpectationsTestCase.test_waitingForAnExpectationFulfilledAfterTheTimeout_fails' failed \(\d+\.\d+ seconds\).
     func test_waitingForAnExpectationFulfilledAfterTheTimeout_fails() {
-        let expectation = expectationWithDescription("hog")
+        let expectation = self.expectation(withDescription: "hog")
         let timer = NSTimer.scheduledTimer(1.0, repeats: false) { _ in
             expectation.fulfill()
         }
         NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
-        waitForExpectationsWithTimeout(0.1, handler: nil)
+        waitForExpectations(withTimeout: 0.1)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_andAllExpectationsAreFulfilled_passes' started.
+// CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_andAllExpectationsAreFulfilled_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_andAllExpectationsAreFulfilled_passes' passed \(\d+\.\d+ seconds\).
     func test_whenTimeoutIsImmediate_andAllExpectationsAreFulfilled_passes() {
-        let expectation = expectationWithDescription("smog")
+        let expectation = self.expectation(withDescription: "smog")
         expectation.fulfill()
-        waitForExpectationsWithTimeout(0.0, handler: nil)
+        waitForExpectations(withTimeout: 0.0)
     }
 
-// CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:75: error: ExpectationsTestCase.test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails : Asynchronous wait failed - Exceeded timeout of -1.0 seconds, with unfulfilled expectations: dog
+// CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Expectations/main.swift:79: error: ExpectationsTestCase.test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails : Asynchronous wait failed - Exceeded timeout of -1.0 seconds, with unfulfilled expectations: dog
 // CHECK: Test Case 'ExpectationsTestCase.test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails' failed \(\d+\.\d+ seconds\).
     func test_whenTimeoutIsImmediate_butNotAllExpectationsAreFulfilled_fails() {
-        expectationWithDescription("dog")
-        waitForExpectationsWithTimeout(-1.0, handler: nil)
+        expectation(withDescription: "dog")
+        waitForExpectations(withTimeout: -1.0)
     }
 
     static var allTests: [(String, ExpectationsTestCase -> () throws -> Void)] {
@@ -87,8 +91,12 @@
         ]
     }
 }
+// CHECK: Test Suite 'ExpectationsTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 7 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(ExpectationsTestCase.allTests)])
 
-// CHECK: Executed 7 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 7 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 7 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 7 tests, with 4 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Asynchronous/Handler/main.swift b/Tests/Functional/Asynchronous/Handler/main.swift
index 5ff628f..e6f5577 100644
--- a/Tests/Functional/Asynchronous/Handler/main.swift
+++ b/Tests/Functional/Asynchronous/Handler/main.swift
@@ -10,31 +10,35 @@
     import SwiftFoundation
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'HandlerTestCase' started at \d+:\d+:\d+\.\d+
 class HandlerTestCase: XCTestCase {
-// CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreNotFulfilled_handlerCalled_andFails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Handler/main.swift:21: error: HandlerTestCase.test_whenExpectationsAreNotFulfilled_handlerCalled_andFails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: fog
+// CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreNotFulfilled_handlerCalled_andFails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Handler/main.swift:25: error: HandlerTestCase.test_whenExpectationsAreNotFulfilled_handlerCalled_andFails : Asynchronous wait failed - Exceeded timeout of 0.2 seconds, with unfulfilled expectations: fog
 // CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreNotFulfilled_handlerCalled_andFails' failed \(\d+\.\d+ seconds\).
     func test_whenExpectationsAreNotFulfilled_handlerCalled_andFails() {
-        self.expectationWithDescription("fog")
+        self.expectation(withDescription: "fog")
 
         var handlerWasCalled = false
-        self.waitForExpectationsWithTimeout(0.2) { error in
+        self.waitForExpectations(withTimeout: 0.2) { error in
             XCTAssertNotNil(error, "Expectation handlers for unfulfilled expectations should not be nil.")
-            XCTAssertTrue(error!.domain.hasSuffix("XCTestErrorDomain"), "The last component of the error domain should match Objective-C XCTest.")
-            XCTAssertEqual(error!.code, 0, "The error code should match Objective-C XCTest.")
+            XCTAssertEqual(error?.domain, XCTestErrorDomain, "The error domain should be XCTest's own error domain")
+            XCTAssertEqual(error?.code, XCTestErrorCode.timeoutWhileWaiting.rawValue, "The error code should indicate that a timeout occurred")
             handlerWasCalled = true
         }
         XCTAssertTrue(handlerWasCalled)
     }
 
-// CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreFulfilled_handlerCalled_andPasses' started.
+// CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreFulfilled_handlerCalled_andPasses' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'HandlerTestCase.test_whenExpectationsAreFulfilled_handlerCalled_andPasses' passed \(\d+\.\d+ seconds\).
     func test_whenExpectationsAreFulfilled_handlerCalled_andPasses() {
-        let expectation = self.expectationWithDescription("bog")
+        let expectation = self.expectation(withDescription: "bog")
         expectation.fulfill()
 
         var handlerWasCalled = false
-        self.waitForExpectationsWithTimeout(0.2) { error in
+        self.waitForExpectations(withTimeout: 0.2) { error in
             XCTAssertNil(error, "Expectation handlers for fulfilled expectations should be nil.")
             handlerWasCalled = true
         }
@@ -48,8 +52,12 @@
         ]
     }
 }
+// CHECK: Test Suite 'HandlerTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(HandlerTestCase.allTests)])
 
-// CHECK: Executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Asynchronous/Misuse/main.swift b/Tests/Functional/Asynchronous/Misuse/main.swift
index c0a6c8d..5a2fffd 100644
--- a/Tests/Functional/Asynchronous/Misuse/main.swift
+++ b/Tests/Functional/Asynchronous/Misuse/main.swift
@@ -8,28 +8,32 @@
     import SwiftXCTest
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'MisuseTestCase' started at \d+:\d+:\d+\.\d+
 class MisuseTestCase: XCTestCase {
-// CHECK: Test Case 'MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:17: unexpected error: MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails :  - Failed due to unwaited expectations.
+// CHECK: Test Case 'MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:21: error: MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails : Failed due to unwaited expectations.
 // CHECK: Test Case 'MisuseTestCase.test_whenExpectationsAreMade_butNotWaitedFor_fails' failed \(\d+\.\d+ seconds\).
     func test_whenExpectationsAreMade_butNotWaitedFor_fails() {
-        self.expectationWithDescription("the first expectation")
-        self.expectationWithDescription("the second expectation (the file and line number for this one are included in the failure message")
+        self.expectation(withDescription: "the first expectation")
+        self.expectation(withDescription: "the second expectation (the file and line number for this one are included in the failure message")
     }
 
-// CHECK: Test Case 'MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:24: unexpected error: MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails : API violation - call made to wait without any expectations having been set.
+// CHECK: Test Case 'MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:28: error: MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails : API violation - call made to wait without any expectations having been set.
 // CHECK: Test Case 'MisuseTestCase.test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails' failed \(\d+\.\d+ seconds\).
     func test_whenNoExpectationsAreMade_butTheyAreWaitedFor_fails() {
-        self.waitForExpectationsWithTimeout(0.1, handler: nil)
+        self.waitForExpectations(withTimeout: 0.1)
     }
 
-// CHECK: Test Case 'MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:34: unexpected error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
-// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:44: unexpected error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
+// CHECK: Test Case 'MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:38: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
+// CHECK: .*/Tests/Functional/Asynchronous/Misuse/main.swift:48: error: MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails : API violation - multiple calls made to XCTestExpectation.fulfill\(\) for rob.
 // CHECK: Test Case 'MisuseTestCase.test_whenExpectationIsFulfilledMultipleTimes_fails' failed \(\d+\.\d+ seconds\).
     func test_whenExpectationIsFulfilledMultipleTimes_fails() {
-        let expectation = self.expectationWithDescription("rob")
+        let expectation = self.expectation(withDescription: "rob")
         expectation.fulfill()
         expectation.fulfill()
         // FIXME: The behavior here is subtly different from Objective-C XCTest.
@@ -42,7 +46,7 @@
         //        highlights both the lines above and below as failures.
         //        This should be fixed such that the behavior is identical.
         expectation.fulfill()
-        self.waitForExpectationsWithTimeout(0.1, handler: nil)
+        self.waitForExpectations(withTimeout: 0.1)
     }
 
     static var allTests: [(String, MisuseTestCase -> () throws -> Void)] {
@@ -53,8 +57,12 @@
         ]
     }
 }
+// CHECK: Test Suite 'MisuseTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 4 failures \(4 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(MisuseTestCase.allTests)])
 
-// CHECK: Executed 3 tests, with 4 failures \(4 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 3 tests, with 4 failures \(4 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 4 failures \(4 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 4 failures \(4 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift b/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift
index 0be95a1..6601253 100644
--- a/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift
+++ b/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift
@@ -10,55 +10,60 @@
     import SwiftFoundation
 #endif
 
+
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'NotificationExpectationsTestCase' started at \d+:\d+:\d+\.\d+
 class NotificationExpectationsTestCase: XCTestCase {
-// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithName_passes' started.
+// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithName_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithName_passes' passed \(\d+\.\d+ seconds\).
     func test_observeNotificationWithName_passes() {
         let notificationName = "notificationWithNameTest"
-        expectationForNotification(notificationName, object:nil, handler:nil)
+        expectation(forNotification: notificationName, object:nil)
         NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: nil)
-        waitForExpectationsWithTimeout(0.0, handler: nil)
+        waitForExpectations(withTimeout: 0.0)
     }
     
-// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_passes' started.
+// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_passes' passed \(\d+\.\d+ seconds\).
     func test_observeNotificationWithNameAndObject_passes() {
         let notificationName = "notificationWithNameAndObjectTest"
         let dummyObject = NSObject()
-        expectationForNotification(notificationName, object:dummyObject, handler:nil)
+        expectation(forNotification: notificationName, object:dummyObject)
         NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: dummyObject)
-        waitForExpectationsWithTimeout(0.0, handler: nil)
+        waitForExpectations(withTimeout: 0.0)
     }
     
-// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_butExpectingNoObject_passes' started.
+// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_butExpectingNoObject_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithNameAndObject_butExpectingNoObject_passes' passed \(\d+\.\d+ seconds\).
     func test_observeNotificationWithNameAndObject_butExpectingNoObject_passes() {
         let notificationName = "notificationWithNameAndObject_expectNoObjectTest"
-        expectationForNotification(notificationName, object:nil, handler:nil)
+        expectation(forNotification: notificationName, object:nil)
         let dummyObject = NSObject()
         NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object: dummyObject)
-        waitForExpectationsWithTimeout(0.0, handler: nil)
+        waitForExpectations(withTimeout: 0.0)
     }
     
-// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectName_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift:49: error: NotificationExpectationsTestCase.test_observeNotificationWithIncorrectName_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'expectedName' from any object
+// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectName_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift:54: error: NotificationExpectationsTestCase.test_observeNotificationWithIncorrectName_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'expectedName' from any object
 // CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectName_fails' failed \(\d+\.\d+ seconds\).
     func test_observeNotificationWithIncorrectName_fails() {
-        expectationForNotification("expectedName", object: nil, handler:nil)
+        expectation(forNotification: "expectedName", object: nil)
         NSNotificationCenter.defaultCenter().postNotificationName("actualName", object: nil)
-        waitForExpectationsWithTimeout(0.1, handler: nil)
+        waitForExpectations(withTimeout: 0.1)
     }
     
-// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectObject_fails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift:61: error: NotificationExpectationsTestCase.test_observeNotificationWithIncorrectObject_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'notificationWithIncorrectObjectTest' from dummyObject
+// CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectObject_fails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Expectations/main.swift:66: error: NotificationExpectationsTestCase.test_observeNotificationWithIncorrectObject_fails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'notificationWithIncorrectObjectTest' from dummyObject
 // CHECK: Test Case 'NotificationExpectationsTestCase.test_observeNotificationWithIncorrectObject_fails' failed \(\d+\.\d+ seconds\).
     func test_observeNotificationWithIncorrectObject_fails() {
         let notificationName = "notificationWithIncorrectObjectTest"
         let dummyObject: NSString = "dummyObject"
         let anotherDummyObject = NSObject()
-        expectationForNotification(notificationName, object: dummyObject, handler: nil)
+        expectation(forNotification: notificationName, object: dummyObject)
         NSNotificationCenter.defaultCenter().postNotificationName(notificationName, object:anotherDummyObject)
-        waitForExpectationsWithTimeout(0.1, handler: nil)
+        waitForExpectations(withTimeout: 0.1)
     }
     
     static var allTests: [(String, NotificationExpectationsTestCase -> () throws -> Void)] {
@@ -71,8 +76,12 @@
         ]
     }
 }
+// CHECK: Test Suite 'NotificationExpectationsTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 5 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(NotificationExpectationsTestCase.allTests)])
 
-// CHECK: Executed 5 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 5 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 5 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 5 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Asynchronous/Notifications/Handler/main.swift b/Tests/Functional/Asynchronous/Notifications/Handler/main.swift
index dafa868..81bac77 100644
--- a/Tests/Functional/Asynchronous/Notifications/Handler/main.swift
+++ b/Tests/Functional/Asynchronous/Notifications/Handler/main.swift
@@ -10,39 +10,61 @@
     import SwiftFoundation
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'NotificationHandlerTestCase' started at \d+:\d+:\d+\.\d+
 class NotificationHandlerTestCase: XCTestCase {
-// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsFalse_andFails' started.
-// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Handler/main.swift:23: error: NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsFalse_andFails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'returnFalse' from any object
+// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsFalse_andFails' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Handler/main.swift:27: error: NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsFalse_andFails : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'returnFalse' from any object
 // CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsFalse_andFails' failed \(\d+\.\d+ seconds\).
     func test_notificationNameIsObserved_handlerReturnsFalse_andFails() {
-        let _ = self.expectationForNotification("returnFalse", object: nil, handler: {
+        expectation(forNotification: "returnFalse", object: nil, handler: {
             notification in
             return false
         })
         NSNotificationCenter.defaultCenter().postNotificationName("returnFalse", object: nil)
-        waitForExpectationsWithTimeout(0.1, handler: nil)
+        waitForExpectations(withTimeout: 0.1)
     }
     
-// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsTrue_andPasses' started.
+// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsTrue_andPasses' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObserved_handlerReturnsTrue_andPasses' passed \(\d+\.\d+ seconds\).
     func test_notificationNameIsObserved_handlerReturnsTrue_andPasses() {
-        let _ = self.expectationForNotification("returnTrue", object: nil, handler: {
+        expectation(forNotification: "returnTrue", object: nil, handler: {
             notification in
             return true
         })
         NSNotificationCenter.defaultCenter().postNotificationName("returnTrue", object: nil)
-        waitForExpectationsWithTimeout(0.1, handler: nil)
+        waitForExpectations(withTimeout: 0.1)
+    }
+
+// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Tests/Functional/Asynchronous/Notifications/Handler/main.swift:\d+: error: NotificationHandlerTestCase.test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled : Asynchronous wait failed - Exceeded timeout of 0.1 seconds, with unfulfilled expectations: Expect notification 'note' from any object
+// CHECK: Test Case 'NotificationHandlerTestCase.test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled' failed \(\d+\.\d+ seconds\).
+    func test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled() {
+        expectation(forNotification: "note", object: nil, handler: { _ in
+            XCTFail("Should not call the notification expectation handler")
+            return true
+        })
+        waitForExpectations(withTimeout: 0.1, handler: nil)
+        NSNotificationCenter.defaultCenter().postNotificationName("note", object: nil)
     }
     
     static var allTests: [(String, NotificationHandlerTestCase -> () throws -> Void)] {
         return [
                    ("test_notificationNameIsObserved_handlerReturnsFalse_andFails", test_notificationNameIsObserved_handlerReturnsFalse_andFails),
                    ("test_notificationNameIsObserved_handlerReturnsTrue_andPasses", test_notificationNameIsObserved_handlerReturnsTrue_andPasses),
+                   ("test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled", test_notificationNameIsObservedAfterTimeout_handlerIsNotCalled),
         ]
     }
 }
+// CHECK: Test Suite 'NotificationHandlerTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+
 
 XCTMain([testCase(NotificationHandlerTestCase.allTests)])
 
-// CHECK: Executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 2 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/ErrorHandling/main.swift b/Tests/Functional/ErrorHandling/main.swift
index 66c6bba..05129cb 100644
--- a/Tests/Functional/ErrorHandling/main.swift
+++ b/Tests/Functional/ErrorHandling/main.swift
@@ -8,6 +8,10 @@
     import SwiftXCTest
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'ErrorHandling' started at \d+:\d+:\d+\.\d+
 class ErrorHandling: XCTestCase {
     static var allTests: [(String, ErrorHandling -> () throws -> Void)] {
         return [
@@ -29,21 +33,21 @@
     }
     
     enum SomeError: ErrorProtocol {
-        case AnError(String)
+        case anError(String)
     }
     
     func functionThatDoesThrowError() throws {
-        throw SomeError.AnError("an error message")
+        throw SomeError.anError("an error message")
     }
 
-// CHECK: Test Case 'ErrorHandling.test_shouldButDoesNotThrowErrorInAssertion' started.
+// CHECK: Test Case 'ErrorHandling.test_shouldButDoesNotThrowErrorInAssertion' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/ErrorHandling/main.swift:\d+: error: ErrorHandling.test_shouldButDoesNotThrowErrorInAssertion : XCTAssertThrowsError failed: did not throw error -
 // CHECK: Test Case 'ErrorHandling.test_shouldButDoesNotThrowErrorInAssertion' failed \(\d+\.\d+ seconds\).
     func test_shouldButDoesNotThrowErrorInAssertion() {
         XCTAssertThrowsError(try functionThatDoesNotThrowError())
     }
     
-// CHECK: Test Case 'ErrorHandling.test_shouldThrowErrorInAssertion' started.
+// CHECK: Test Case 'ErrorHandling.test_shouldThrowErrorInAssertion' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'ErrorHandling.test_shouldThrowErrorInAssertion' passed \(\d+\.\d+ seconds\).
     func test_shouldThrowErrorInAssertion() {
         XCTAssertThrowsError(try functionThatDoesThrowError()) { error in
@@ -53,13 +57,13 @@
             }
             
             switch thrownError {
-            case .AnError(let message):
+            case .anError(let message):
                 XCTAssertEqual(message, "an error message")
             }
         }
     }
     
-// CHECK: Test Case 'ErrorHandling.test_throwsErrorInAssertionButFailsWhenCheckingError' started.
+// CHECK: Test Case 'ErrorHandling.test_throwsErrorInAssertionButFailsWhenCheckingError' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/ErrorHandling/main.swift:\d+: error: ErrorHandling.test_throwsErrorInAssertionButFailsWhenCheckingError : XCTAssertEqual failed: \("Optional\("an error message"\)"\) is not equal to \("Optional\(""\)"\) -
 // CHECK: Test Case 'ErrorHandling.test_throwsErrorInAssertionButFailsWhenCheckingError' failed \(\d+\.\d+ seconds\).
     func test_throwsErrorInAssertionButFailsWhenCheckingError() {
@@ -70,38 +74,42 @@
             }
             
             switch thrownError {
-            case .AnError(let message):
+            case .anError(let message):
                 XCTAssertEqual(message, "")
             }
         }
     }
-    
-// CHECK: Test Case 'ErrorHandling.test_canAndDoesThrowErrorFromTestMethod' started.
-// CHECK: \<EXPR\>:0: unexpected error: ErrorHandling.test_canAndDoesThrowErrorFromTestMethod : threw error "AnError\("an error message"\)" -
+
+// CHECK: Test Case 'ErrorHandling.test_canAndDoesThrowErrorFromTestMethod' started at \d+:\d+:\d+\.\d+
+// CHECK: \<EXPR\>:0: error: ErrorHandling.test_canAndDoesThrowErrorFromTestMethod : threw error "anError\("an error message"\)"
 // CHECK: Test Case 'ErrorHandling.test_canAndDoesThrowErrorFromTestMethod' failed \(\d+\.\d+ seconds\).
     func test_canAndDoesThrowErrorFromTestMethod() throws {
         try functionThatDoesThrowError()
     }
     
-// CHECK: Test Case 'ErrorHandling.test_canButDoesNotThrowErrorFromTestMethod' started.
+// CHECK: Test Case 'ErrorHandling.test_canButDoesNotThrowErrorFromTestMethod' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'ErrorHandling.test_canButDoesNotThrowErrorFromTestMethod' passed \(\d+\.\d+ seconds\).
     func test_canButDoesNotThrowErrorFromTestMethod() throws {
         try functionThatDoesNotThrowError()
     }
     
     func functionThatShouldReturnButThrows() throws -> Int {
-        throw SomeError.AnError("did not actually return")
+        throw SomeError.anError("did not actually return")
     }
-    
-// CHECK: Test Case 'ErrorHandling.test_assertionExpressionCanThrow' started.
-// CHECK: .*/ErrorHandling/main.swift:\d+: unexpected error: ErrorHandling.test_assertionExpressionCanThrow : XCTAssertEqual threw error "AnError\("did not actually return"\)" -
+
+// CHECK: Test Case 'ErrorHandling.test_assertionExpressionCanThrow' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/ErrorHandling/main.swift:\d+: error: ErrorHandling.test_assertionExpressionCanThrow : XCTAssertEqual threw error "anError\("did not actually return"\)" -
 // CHECK: Test Case 'ErrorHandling.test_assertionExpressionCanThrow' failed \(\d+\.\d+ seconds\).
     func test_assertionExpressionCanThrow() {
         XCTAssertEqual(try functionThatShouldReturnButThrows(), 1)
     }
 }
+// CHECK: Test Suite 'ErrorHandling' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 6 tests, with 4 failures \(2 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(ErrorHandling.allTests)])
 
-// CHECK: Executed 6 tests, with 4 failures \(2 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 6 tests, with 4 failures \(2 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 6 tests, with 4 failures \(2 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 6 tests, with 4 failures \(2 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
\ No newline at end of file
diff --git a/Tests/Functional/FailingTestSuite/main.swift b/Tests/Functional/FailingTestSuite/main.swift
index 518fdcd..16ba668 100644
--- a/Tests/Functional/FailingTestSuite/main.swift
+++ b/Tests/Functional/FailingTestSuite/main.swift
@@ -8,6 +8,10 @@
     import SwiftXCTest
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'PassingTestCase' started at \d+:\d+:\d+\.\d+
 class PassingTestCase: XCTestCase {
     static var allTests: [(String, PassingTestCase -> () throws -> Void)] {
         return [
@@ -15,15 +19,16 @@
         ]
     }
 
-// CHECK: Test Case 'PassingTestCase.test_passes' started.
+// CHECK: Test Case 'PassingTestCase.test_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'PassingTestCase.test_passes' passed \(\d+\.\d+ seconds\).
     func test_passes() {
         XCTAssert(true)
     }
 }
-// CHECK: Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'PassingTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
-
+// CHECK: Test Suite 'FailingTestCase' started at \d+:\d+:\d+\.\d+
 class FailingTestCase: XCTestCase {
     static var allTests: [(String, FailingTestCase -> () throws -> Void)] {
         return [
@@ -33,32 +38,35 @@
         ]
     }
 
-// CHECK: Test Case 'FailingTestCase.test_passes' started.
+// CHECK: Test Case 'FailingTestCase.test_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'FailingTestCase.test_passes' passed \(\d+\.\d+ seconds\).
     func test_passes() {
         XCTAssert(true)
     }
 
-// CHECK: Test Case 'FailingTestCase.test_fails' started.
+// CHECK: Test Case 'FailingTestCase.test_fails' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/FailingTestSuite/main.swift:\d+: error: FailingTestCase.test_fails : XCTAssertTrue failed - $
 // CHECK: Test Case 'FailingTestCase.test_fails' failed \(\d+\.\d+ seconds\).
     func test_fails() {
         XCTAssert(false)
     }
 
-// CHECK: Test Case 'FailingTestCase.test_fails_with_message' started.
+// CHECK: Test Case 'FailingTestCase.test_fails_with_message' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/FailingTestSuite/main.swift:\d+: error: FailingTestCase.test_fails_with_message : XCTAssertTrue failed - Foo bar.
 // CHECK: Test Case 'FailingTestCase.test_fails_with_message' failed \(\d+\.\d+ seconds\).
     func test_fails_with_message() {
         XCTAssert(false, "Foo bar.")
     }
 }
-// CHECK: Executed 3 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-
+// CHECK: Test Suite 'FailingTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([
     testCase(PassingTestCase.allTests),
     testCase(FailingTestCase.allTests),
 ])
 
-// CHECK: Total executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/FailureMessagesTestCase/main.swift b/Tests/Functional/FailureMessagesTestCase/main.swift
index 962814c..ed20a28 100644
--- a/Tests/Functional/FailureMessagesTestCase/main.swift
+++ b/Tests/Functional/FailureMessagesTestCase/main.swift
@@ -9,6 +9,11 @@
 #endif
 
 // Regression test for https://github.com/apple/swift-corelibs-xctest/pull/22
+
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'FailureMessagesTestCase' started at \d+:\d+:\d+\.\d+
 class FailureMessagesTestCase: XCTestCase {
     static var allTests: [(String, FailureMessagesTestCase -> () throws -> Void)] {
         return [
@@ -37,162 +42,166 @@
         ]
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssert' started.
-// CHECK: test.swift:44: error: FailureMessagesTestCase.testAssert : XCTAssertTrue failed - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssert' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:49: error: FailureMessagesTestCase.testAssert : XCTAssertTrue failed - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssert' failed \(\d+\.\d+ seconds\).
     func testAssert() {
         XCTAssert(false, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualOptionals' started.
-// CHECK: test.swift:51: error: FailureMessagesTestCase.testAssertEqualOptionals : XCTAssertEqual failed: \("Optional\(1\)"\) is not equal to \("Optional\(2\)"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualOptionals' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:56: error: FailureMessagesTestCase.testAssertEqualOptionals : XCTAssertEqual failed: \("Optional\(1\)"\) is not equal to \("Optional\(2\)"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualOptionals' failed \(\d+\.\d+ seconds\).
     func testAssertEqualOptionals() {
         XCTAssertEqual(1, 2, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArraySlices' started.
-// CHECK: test.swift:58: error: FailureMessagesTestCase.testAssertEqualArraySlices : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArraySlices' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:63: error: FailureMessagesTestCase.testAssertEqualArraySlices : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArraySlices' failed \(\d+\.\d+ seconds\).
     func testAssertEqualArraySlices() {
         XCTAssertEqual([1][0..<1], [2][0..<1], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualContiguousArrays' started.
-// CHECK: test.swift:65: error: FailureMessagesTestCase.testAssertEqualContiguousArrays : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualContiguousArrays' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:70: error: FailureMessagesTestCase.testAssertEqualContiguousArrays : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualContiguousArrays' failed \(\d+\.\d+ seconds\).
     func testAssertEqualContiguousArrays() {
         XCTAssertEqual(ContiguousArray(arrayLiteral: 1), ContiguousArray(arrayLiteral: 2), "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArrays' started.
-// CHECK: test.swift:72: error: FailureMessagesTestCase.testAssertEqualArrays : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArrays' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:77: error: FailureMessagesTestCase.testAssertEqualArrays : XCTAssertEqual failed: \("\[1\]"\) is not equal to \("\[2\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualArrays' failed \(\d+\.\d+ seconds\).
     func testAssertEqualArrays() {
         XCTAssertEqual([1], [2], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualDictionaries' started.
-// CHECK: test.swift:79: error: FailureMessagesTestCase.testAssertEqualDictionaries : XCTAssertEqual failed: \("\[1: 2\]"\) is not equal to \("\[3: 4\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualDictionaries' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:84: error: FailureMessagesTestCase.testAssertEqualDictionaries : XCTAssertEqual failed: \("\[1: 2\]"\) is not equal to \("\[3: 4\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualDictionaries' failed \(\d+\.\d+ seconds\).
     func testAssertEqualDictionaries() {
         XCTAssertEqual([1:2], [3:4], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualWithAccuracy' started.
-// CHECK: test.swift:86: error: FailureMessagesTestCase.testAssertEqualWithAccuracy : XCTAssertEqualWithAccuracy failed: \("1\.0"\) is not equal to \("2\.0"\) \+/- \("0\.1"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualWithAccuracy' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:91: error: FailureMessagesTestCase.testAssertEqualWithAccuracy : XCTAssertEqualWithAccuracy failed: \("1\.0"\) is not equal to \("2\.0"\) \+/- \("0\.1"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertEqualWithAccuracy' failed \(\d+\.\d+ seconds\).
     func testAssertEqualWithAccuracy() {
         XCTAssertEqualWithAccuracy(1, 2, accuracy: 0.1, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertFalse' started.
-// CHECK: test.swift:93: error: FailureMessagesTestCase.testAssertFalse : XCTAssertFalse failed - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertFalse' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:98: error: FailureMessagesTestCase.testAssertFalse : XCTAssertFalse failed - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertFalse' failed \(\d+\.\d+ seconds\).
     func testAssertFalse() {
         XCTAssertFalse(true, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThan' started.
-// CHECK: test.swift:100: error: FailureMessagesTestCase.testAssertGreaterThan : XCTAssertGreaterThan failed: \("0"\) is not greater than \("0"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThan' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:105: error: FailureMessagesTestCase.testAssertGreaterThan : XCTAssertGreaterThan failed: \("0"\) is not greater than \("0"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThan' failed \(\d+\.\d+ seconds\).
     func testAssertGreaterThan() {
         XCTAssertGreaterThan(0, 0, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThanOrEqual' started.
-// CHECK: test.swift:107: error: FailureMessagesTestCase.testAssertGreaterThanOrEqual : XCTAssertGreaterThanOrEqual failed: \("-1"\) is less than \("0"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThanOrEqual' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:112: error: FailureMessagesTestCase.testAssertGreaterThanOrEqual : XCTAssertGreaterThanOrEqual failed: \("-1"\) is less than \("0"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertGreaterThanOrEqual' failed \(\d+\.\d+ seconds\).
     func testAssertGreaterThanOrEqual() {
         XCTAssertGreaterThanOrEqual(-1, 0, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThan' started.
-// CHECK: test.swift:114: error: FailureMessagesTestCase.testAssertLessThan : XCTAssertLessThan failed: \("0"\) is not less than \("0"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThan' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:119: error: FailureMessagesTestCase.testAssertLessThan : XCTAssertLessThan failed: \("0"\) is not less than \("0"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThan' failed \(\d+\.\d+ seconds\).
     func testAssertLessThan() {
         XCTAssertLessThan(0, 0, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThanOrEqual' started.
-// CHECK: test.swift:121: error: FailureMessagesTestCase.testAssertLessThanOrEqual : XCTAssertLessThanOrEqual failed: \("1"\) is greater than \("0"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThanOrEqual' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:126: error: FailureMessagesTestCase.testAssertLessThanOrEqual : XCTAssertLessThanOrEqual failed: \("1"\) is greater than \("0"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertLessThanOrEqual' failed \(\d+\.\d+ seconds\).
     func testAssertLessThanOrEqual() {
         XCTAssertLessThanOrEqual(1, 0, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNil' started.
-// CHECK: test.swift:128: error: FailureMessagesTestCase.testAssertNil : XCTAssertNil failed: "helloworld" - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNil' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:133: error: FailureMessagesTestCase.testAssertNil : XCTAssertNil failed: "helloworld" - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNil' failed \(\d+\.\d+ seconds\).
     func testAssertNil() {
         XCTAssertNil("helloworld", "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualOptionals' started.
-// CHECK: test.swift:135: error: FailureMessagesTestCase.testAssertNotEqualOptionals : XCTAssertNotEqual failed: \("Optional\(1\)"\) is equal to \("Optional\(1\)"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualOptionals' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:140: error: FailureMessagesTestCase.testAssertNotEqualOptionals : XCTAssertNotEqual failed: \("Optional\(1\)"\) is equal to \("Optional\(1\)"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualOptionals' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualOptionals() {
         XCTAssertNotEqual(1, 1, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArraySlices' started.
-// CHECK: test.swift:142: error: FailureMessagesTestCase.testAssertNotEqualArraySlices : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArraySlices' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:147: error: FailureMessagesTestCase.testAssertNotEqualArraySlices : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArraySlices' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualArraySlices() {
         XCTAssertNotEqual([1][0..<1], [1][0..<1], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualContiguousArrays' started.
-// CHECK: test.swift:149: error: FailureMessagesTestCase.testAssertNotEqualContiguousArrays : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualContiguousArrays' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:154: error: FailureMessagesTestCase.testAssertNotEqualContiguousArrays : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualContiguousArrays' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualContiguousArrays() {
         XCTAssertNotEqual(ContiguousArray(arrayLiteral: 1), ContiguousArray(arrayLiteral: 1), "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArrays' started.
-// CHECK: test.swift:156: error: FailureMessagesTestCase.testAssertNotEqualArrays : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArrays' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:161: error: FailureMessagesTestCase.testAssertNotEqualArrays : XCTAssertNotEqual failed: \("\[1\]"\) is equal to \("\[1\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualArrays' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualArrays() {
         XCTAssertNotEqual([1], [1], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualDictionaries' started.
-// CHECK: test.swift:163: error: FailureMessagesTestCase.testAssertNotEqualDictionaries : XCTAssertNotEqual failed: \("\[1: 1\]"\) is equal to \("\[1: 1\]"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualDictionaries' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:168: error: FailureMessagesTestCase.testAssertNotEqualDictionaries : XCTAssertNotEqual failed: \("\[1: 1\]"\) is equal to \("\[1: 1\]"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualDictionaries' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualDictionaries() {
         XCTAssertNotEqual([1:1], [1:1], "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualWithAccuracy' started.
-// CHECK: test.swift:170: error: FailureMessagesTestCase.testAssertNotEqualWithAccuracy : XCTAssertNotEqualWithAccuracy failed: \("1\.0"\) is equal to \("1\.0"\) \+/- \("0\.1"\) - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualWithAccuracy' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:175: error: FailureMessagesTestCase.testAssertNotEqualWithAccuracy : XCTAssertNotEqualWithAccuracy failed: \("1\.0"\) is equal to \("1\.0"\) \+/- \("0\.1"\) - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotEqualWithAccuracy' failed \(\d+\.\d+ seconds\).
     func testAssertNotEqualWithAccuracy() {
         XCTAssertNotEqualWithAccuracy(1, 1, 0.1, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotNil' started.
-// CHECK: test.swift:177: error: FailureMessagesTestCase.testAssertNotNil : XCTAssertNotNil failed - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertNotNil' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:182: error: FailureMessagesTestCase.testAssertNotNil : XCTAssertNotNil failed - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertNotNil' failed \(\d+\.\d+ seconds\).
     func testAssertNotNil() {
         XCTAssertNotNil(nil, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testAssertTrue' started.
-// CHECK: test.swift:184: error: FailureMessagesTestCase.testAssertTrue : XCTAssertTrue failed - message
+// CHECK: Test Case 'FailureMessagesTestCase.testAssertTrue' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:189: error: FailureMessagesTestCase.testAssertTrue : XCTAssertTrue failed - message
 // CHECK: Test Case 'FailureMessagesTestCase.testAssertTrue' failed \(\d+\.\d+ seconds\).
     func testAssertTrue() {
         XCTAssertTrue(false, "message", file: "test.swift")
     }
 
-// CHECK: Test Case 'FailureMessagesTestCase.testFail' started.
-// CHECK: test.swift:191: error: FailureMessagesTestCase.testFail : failed - message
+// CHECK: Test Case 'FailureMessagesTestCase.testFail' started at \d+:\d+:\d+\.\d+
+// CHECK: test.swift:196: error: FailureMessagesTestCase.testFail : failed - message
 // CHECK: Test Case 'FailureMessagesTestCase.testFail' failed \(\d+\.\d+ seconds\).
     func testFail() {
         XCTFail("message", file: "test.swift")
     }
 }
+// CHECK: Test Suite 'FailureMessagesTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 22 tests, with 22 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(FailureMessagesTestCase.allTests)])
 
-// CHECK: Executed 22 tests, with 22 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 22 tests, with 22 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 22 tests, with 22 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 22 tests, with 22 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/NegativeAccuracyTestCase/main.swift b/Tests/Functional/NegativeAccuracyTestCase/main.swift
index 18c0a6f..79656c0 100644
--- a/Tests/Functional/NegativeAccuracyTestCase/main.swift
+++ b/Tests/Functional/NegativeAccuracyTestCase/main.swift
@@ -9,6 +9,11 @@
 #endif
 
 // Regression test for https://github.com/apple/swift-corelibs-xctest/pull/7
+
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'NegativeAccuracyTestCase' started at \d+:\d+:\d+\.\d+
 class NegativeAccuracyTestCase: XCTestCase {
     static var allTests: [(String, NegativeAccuracyTestCase -> () throws -> Void)] {
         return [
@@ -19,34 +24,38 @@
         ]
     }
 
-// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_passes' started.
+// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_passes' passed \(\d+\.\d+ seconds\).
     func test_equalWithAccuracy_passes() {
         XCTAssertEqualWithAccuracy(0, 0.1, accuracy: -0.1)
     }
 
-// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_fails' started.
+// CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_fails' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/NegativeAccuracyTestCase/main.swift:\d+: error: NegativeAccuracyTestCase.test_equalWithAccuracy_fails : XCTAssertEqualWithAccuracy failed: \(\"0\.0\"\) is not equal to \(\"0\.2\"\) \+\/- \(\"-0\.1\"\) - $
 // CHECK: Test Case 'NegativeAccuracyTestCase.test_equalWithAccuracy_fails' failed \(\d+\.\d+ seconds\).
     func test_equalWithAccuracy_fails() {
         XCTAssertEqualWithAccuracy(0, 0.2, accuracy: -0.1)
     }
 
-// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_passes' started.
+// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_passes' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_passes' passed \(\d+\.\d+ seconds\).
     func test_notEqualWithAccuracy_passes() {
         XCTAssertNotEqualWithAccuracy(1, 2, -0.5)
     }
 
-// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails' started.
+// CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails' started at \d+:\d+:\d+\.\d+
 // CHECK: .*/NegativeAccuracyTestCase/main.swift:\d+: error: NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails : XCTAssertNotEqualWithAccuracy failed: \("1\.0"\) is equal to \("2\.0"\) \+/- \("-1\.0"\) - $
 // CHECK: Test Case 'NegativeAccuracyTestCase.test_notEqualWithAccuracy_fails' failed \(\d+\.\d+ seconds\).
     func test_notEqualWithAccuracy_fails() {
         XCTAssertNotEqualWithAccuracy(1, 2, -1)
     }
 }
+// CHECK: Test Suite 'NegativeAccuracyTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(NegativeAccuracyTestCase.allTests)])
 
-// CHECK: Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 4 tests, with 2 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/Observation/All/main.swift b/Tests/Functional/Observation/All/main.swift
new file mode 100644
index 0000000..38a6df3
--- /dev/null
+++ b/Tests/Functional/Observation/All/main.swift
@@ -0,0 +1,127 @@
+// RUN: %{swiftc} %s -o %{built_tests_dir}/All
+// RUN: %{built_tests_dir}/All > %t || true
+// RUN: %{xctest_checker} %t %s
+
+#if os(Linux) || os(FreeBSD)
+    import XCTest
+    import Foundation
+#else
+    import SwiftXCTest
+    import SwiftFoundation
+#endif
+
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+class Observer: XCTestObservation {
+    var startedBundlePaths = [String]()
+    var startedTestSuites = [XCTestSuite]()
+    var startedTestCaseNames = [String]()
+    var failureDescriptions = [String]()
+    var finishedTestCaseNames = [String]()
+    var finishedTestSuites = [XCTestSuite]()
+    var finishedBundlePaths = [String]()
+
+    func testBundleWillStart(_ testBundle: NSBundle) {
+        startedBundlePaths.append(testBundle.bundlePath)
+    }
+
+    func testSuiteWillStart(_ testSuite: XCTestSuite) {
+        startedTestSuites.append(testSuite)
+    }
+
+    func testCaseWillStart(_ testCase: XCTestCase) {
+        startedTestCaseNames.append(testCase.name)
+    }
+
+    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
+        failureDescriptions.append(description)
+    }
+
+    func testCaseDidFinish(_ testCase: XCTestCase) {
+        finishedTestCaseNames.append(testCase.name)
+    }
+
+    func testSuiteDidFinish(_ testSuite: XCTestSuite) {
+        print("In \(#function): \(testSuite.name)")
+    }
+
+    func testBundleDidFinish(_ testBundle: NSBundle) {
+        print("In \(#function)")
+    }
+}
+
+let observer = Observer()
+XCTestObservationCenter.shared().addTestObserver(observer)
+
+// CHECK: Test Suite 'Observation' started at \d+:\d+:\d+\.\d+
+class Observation: XCTestCase {
+    static var allTests: [(String, Observation -> () throws -> Void)] {
+        return [
+            ("test_one", test_one),
+            ("test_two", test_two),
+            ("test_three", test_three),
+        ]
+    }
+
+// CHECK: Test Case 'Observation.test_one' started at \d+:\d+:\d+\.\d+
+// CHECK: .*/Observation/All/main.swift:\d+: error: Observation.test_one : failed - fail!
+// CHECK: Test Case 'Observation.test_one' failed \(\d+\.\d+ seconds\).
+    func test_one() {
+        XCTAssertEqual(observer.startedBundlePaths.count, 1)
+        XCTAssertEqual(
+            observer.startedTestSuites.count, 3,
+            "Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
+        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one"])
+        XCTAssertEqual(observer.failureDescriptions, [])
+        XCTAssertEqual(observer.finishedTestCaseNames, [])
+        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
+
+        XCTFail("fail!")
+        XCTAssertEqual(observer.failureDescriptions, ["failed - fail!"])
+    }
+
+// CHECK: Test Case 'Observation.test_two' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Case 'Observation.test_two' passed \(\d+\.\d+ seconds\).
+    func test_two() {
+        XCTAssertEqual(observer.startedBundlePaths.count, 1)
+        XCTAssertEqual(
+            observer.startedTestSuites.count, 3,
+            "Three test suites should have started: 'All tests', 'tmp.xctest', and 'Observation'.")
+        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
+        XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
+        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
+
+        XCTestObservationCenter.shared().removeTestObserver(observer)
+    }
+
+// CHECK: Test Case 'Observation.test_three' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Case 'Observation.test_three' passed \(\d+\.\d+ seconds\).
+    func test_three() {
+        XCTAssertEqual(observer.startedBundlePaths.count, 1)
+        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
+        XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
+        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
+
+        XCTestObservationCenter.shared().addTestObserver(observer)
+    }
+}
+
+// There's no guarantee as to the order in which these two observers will be
+// called, so we match any order here.
+
+// CHECK: (In testSuiteDidFinish: Observation)|(Test Suite 'Observation' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: Observation)|(Test Suite 'Observation' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: Observation)|(Test Suite 'Observation' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+
+XCTMain([testCase(Observation.allTests)])
+
+// CHECK: (In testSuiteDidFinish: .*\.xctest)|(Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: .*\.xctest)|(Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: .*\.xctest)|(Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+
+// CHECK: (In testSuiteDidFinish: All tests)|(Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: All tests)|(Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: All tests)|(Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+)|(\t Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+
+// CHECK: In testBundleDidFinish
diff --git a/Tests/Functional/Observation/Selected/main.swift b/Tests/Functional/Observation/Selected/main.swift
new file mode 100644
index 0000000..2b7c956
--- /dev/null
+++ b/Tests/Functional/Observation/Selected/main.swift
@@ -0,0 +1,86 @@
+// RUN: %{swiftc} %s -o %{built_tests_dir}/Selected
+// RUN: %{built_tests_dir}/Selected Selected.ExecutedTestCase/test_executed > %t || true
+// RUN: %{xctest_checker} %t %s
+
+#if os(Linux) || os(FreeBSD)
+    import XCTest
+    import Foundation
+#else
+    import SwiftXCTest
+    import SwiftFoundation
+#endif
+
+// CHECK: Test Suite 'Selected tests' started at \d+:\d+:\d+\.\d+
+
+class Observer: XCTestObservation {
+    var startedTestSuites = [XCTestSuite]()
+    var finishedTestSuites = [XCTestSuite]()
+
+    func testBundleWillStart(_ testBundle: NSBundle) {}
+
+    func testSuiteWillStart(_ testSuite: XCTestSuite) {
+        startedTestSuites.append(testSuite)
+    }
+
+    func testCaseWillStart(_ testCase: XCTestCase) {}
+    func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {}
+    func testCaseDidFinish(_ testCase: XCTestCase) {}
+
+    func testSuiteDidFinish(_ testSuite: XCTestSuite) {
+        print("In \(#function): \(testSuite.name)")
+    }
+
+    func testBundleDidFinish(_ testBundle: NSBundle) {}
+}
+
+let observer = Observer()
+XCTestObservationCenter.shared().addTestObserver(observer)
+
+class SkippedTestCase: XCTestCase {
+    static var allTests: [(String, SkippedTestCase -> () throws -> Void)] {
+        return [
+            ("test_skipped", test_skipped),
+        ]
+    }
+
+    func test_skipped() {
+        XCTFail("This test method should not be executed.")
+    }
+}
+
+// CHECK: Test Suite 'ExecutedTestCase' started at \d+:\d+:\d+\.\d+
+class ExecutedTestCase: XCTestCase {
+    static var allTests: [(String, ExecutedTestCase -> () throws -> Void)] {
+        return [
+            ("test_executed", test_executed),
+            ("test_skipped", test_skipped),
+        ]
+    }
+
+// CHECK: Test Case 'ExecutedTestCase.test_executed' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Case 'ExecutedTestCase.test_executed' passed \(\d+\.\d+ seconds\).
+    func test_executed() {
+        let suiteNames = observer.startedTestSuites.map { $0.name }
+        XCTAssertEqual(suiteNames, ["Selected tests", "ExecutedTestCase"])
+    }
+
+    func test_skipped() {
+        XCTFail("This test method should not be executed.")
+    }
+}
+
+// There's no guarantee as to the order in which these two observers will be
+// called, so we match any order here.
+
+// CHECK: (In testSuiteDidFinish: ExecutedTestCase)|(Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+|\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: ExecutedTestCase)|(Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+|\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: ExecutedTestCase)|(Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+|\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+
+XCTMain([
+    testCase(SkippedTestCase.allTests),
+    testCase(ExecutedTestCase.allTests),
+])
+
+// CHECK: (In testSuiteDidFinish: Selected tests|Test Suite 'Selected tests' passed at \d+:\d+:\d+\.\d+)|(\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: Selected tests|Test Suite 'Selected tests' passed at \d+:\d+:\d+\.\d+)|(\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
+// CHECK: (In testSuiteDidFinish: Selected tests|Test Suite 'Selected tests' passed at \d+:\d+:\d+\.\d+)|(\t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds)
diff --git a/Tests/Functional/Observation/main.swift b/Tests/Functional/Observation/main.swift
deleted file mode 100644
index 7861505..0000000
--- a/Tests/Functional/Observation/main.swift
+++ /dev/null
@@ -1,94 +0,0 @@
-// RUN: %{swiftc} %s -o %{built_tests_dir}/Observation
-// RUN: %{built_tests_dir}/Observation > %t || true
-// RUN: %{xctest_checker} %t %s
-
-#if os(Linux) || os(FreeBSD)
-    import XCTest
-    import Foundation
-#else
-    import SwiftXCTest
-    import SwiftFoundation
-#endif
-
-class Observer: XCTestObservation {
-    var startedBundlePaths = [String]()
-    var startedTestCaseNames = [String]()
-    var failureDescriptions = [String]()
-    var finishedTestCaseNames = [String]()
-    var finishedBundlePaths = [String]()
-
-    func testBundleWillStart(testBundle: NSBundle) {
-        startedBundlePaths.append(testBundle.bundlePath)
-    }
-
-    func testCaseWillStart(testCase: XCTestCase) {
-        startedTestCaseNames.append(testCase.name)
-    }
-
-    func testCase(testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
-        failureDescriptions.append(description)
-    }
-
-    func testCaseDidFinish(testCase: XCTestCase) {
-        finishedTestCaseNames.append(testCase.name)
-    }
-
-    func testBundleDidFinish(testBundle: NSBundle) {
-        print("In \(#function)")
-    }
-}
-
-let observer = Observer()
-XCTestObservationCenter.shared().addTestObserver(observer)
-
-class Observation: XCTestCase {
-    static var allTests: [(String, Observation -> () throws -> Void)] {
-        return [
-            ("test_one", test_one),
-            ("test_two", test_two),
-            ("test_three", test_three),
-        ]
-    }
-
-// CHECK: Test Case 'Observation.test_one' started.
-// CHECK: .*/Observation/main.swift:\d+: error: Observation.test_one : failed - fail!
-// CHECK: Test Case 'Observation.test_one' failed \(\d+\.\d+ seconds\).
-    func test_one() {
-        XCTAssertEqual(observer.startedBundlePaths.count, 1)
-        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one"])
-        XCTAssertEqual(observer.failureDescriptions, [])
-        XCTAssertEqual(observer.finishedTestCaseNames, [])
-        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
-
-        XCTFail("fail!")
-        XCTAssertEqual(observer.failureDescriptions, ["failed - fail!"])
-    }
-
-// CHECK: Test Case 'Observation.test_two' started.
-// CHECK: Test Case 'Observation.test_two' passed \(\d+\.\d+ seconds\).
-    func test_two() {
-        XCTAssertEqual(observer.startedBundlePaths.count, 1)
-        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
-        XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
-        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
-
-        XCTestObservationCenter.shared().removeTestObserver(observer)
-    }
-
-// CHECK: Test Case 'Observation.test_three' started.
-// CHECK: Test Case 'Observation.test_three' passed \(\d+\.\d+ seconds\).
-    func test_three() {
-        XCTAssertEqual(observer.startedBundlePaths.count, 1)
-        XCTAssertEqual(observer.startedTestCaseNames, ["Observation.test_one", "Observation.test_two"])
-        XCTAssertEqual(observer.finishedTestCaseNames,["Observation.test_one"])
-        XCTAssertEqual(observer.finishedBundlePaths.count, 0)
-
-        XCTestObservationCenter.shared().addTestObserver(observer)
-    }
-}
-
-XCTMain([testCase(Observation.allTests)])
-
-// CHECK: Executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 3 tests, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: In testBundleDidFinish
diff --git a/Tests/Functional/SelectedTest/main.swift b/Tests/Functional/SelectedTest/main.swift
index 7345378..a49f5d6 100644
--- a/Tests/Functional/SelectedTest/main.swift
+++ b/Tests/Functional/SelectedTest/main.swift
@@ -12,6 +12,11 @@
     import SwiftXCTest
 #endif
 
+// CHECK-METHOD: Test Suite 'Selected tests' started at \d+:\d+:\d+\.\d+
+// CHECK-TESTCASE: Test Suite 'Selected tests' started at \d+:\d+:\d+\.\d+
+// CHECK-ALL: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK-ALL: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
 class ExecutedTestCase: XCTestCase {
     static var allTests: [(String, ExecutedTestCase -> () throws -> Void)] {
         return [
@@ -20,41 +25,54 @@
         ]
     }
 
-// CHECK-METHOD:   Test Case 'ExecutedTestCase.test_foo' started.
+// CHECK-METHOD:   Test Suite 'ExecutedTestCase' started at \d+:\d+:\d+\.\d+
+// CHECK-METHOD:   Test Case 'ExecutedTestCase.test_foo' started at \d+:\d+:\d+\.\d+
 // CHECK-METHOD:   Test Case 'ExecutedTestCase.test_foo' passed \(\d+\.\d+ seconds\).
-// CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_bar' started.
+// CHECK-TESTCASE: Test Suite 'ExecutedTestCase' started at \d+:\d+:\d+\.\d+
+// CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_bar' started at \d+:\d+:\d+\.\d+
 // CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_bar' passed \(\d+\.\d+ seconds\).
-// CHECK-ALL:      Test Case 'ExecutedTestCase.test_bar' started.
+// CHECK-ALL:      Test Suite 'ExecutedTestCase' started at \d+:\d+:\d+\.\d+
+// CHECK-ALL:      Test Case 'ExecutedTestCase.test_bar' started at \d+:\d+:\d+\.\d+
 // CHECK-ALL:      Test Case 'ExecutedTestCase.test_bar' passed \(\d+\.\d+ seconds\).
     func test_bar() {}
 
-// CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_foo' started.
+// CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_foo' started at \d+:\d+:\d+\.\d+
 // CHECK-TESTCASE: Test Case 'ExecutedTestCase.test_foo' passed \(\d+\.\d+ seconds\).
-// CHECK-ALL:      Test Case 'ExecutedTestCase.test_foo' started.
+// CHECK-ALL:      Test Case 'ExecutedTestCase.test_foo' started at \d+:\d+:\d+\.\d+
 // CHECK-ALL:      Test Case 'ExecutedTestCase.test_foo' passed \(\d+\.\d+ seconds\).
     func test_foo() {}
 }
-// CHECK-METHOD:   Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK-TESTCASE: Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK-ALL:      Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-METHOD:   Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK-METHOD:   \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-TESTCASE: Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK-TESTCASE: \t Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-ALL:      Test Suite 'ExecutedTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK-ALL:      \t Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 
+// CHECK-ALL: Test Suite 'SkippedTestCase' started at \d+:\d+:\d+\.\d+
 class SkippedTestCase: XCTestCase {
     static var allTests: [(String, SkippedTestCase -> () throws -> Void)] {
         return [("test_baz", test_baz)]
     }
 
-// CHECK-ALL: Test Case 'SkippedTestCase.test_baz' started.
+// CHECK-ALL: Test Case 'SkippedTestCase.test_baz' started at \d+:\d+:\d+\.\d+
 // CHECK-ALL: Test Case 'SkippedTestCase.test_baz' passed \(\d+\.\d+ seconds\).
     func test_baz() {}
 }
-// CHECK-ALL: Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-ALL: Test Suite 'SkippedTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK-ALL: \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([
     testCase(ExecutedTestCase.allTests),
     testCase(SkippedTestCase.allTests),
 ])
 
-// CHECK-METHOD:   Total executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK-TESTCASE: Total executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK-ALL:      Total executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-METHOD:   Test Suite 'Selected tests' passed at \d+:\d+:\d+\.\d+
+// CHECK-METHOD:   \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-TESTCASE: Test Suite 'Selected tests' passed at \d+:\d+:\d+\.\d+
+// CHECK-TESTCASE: \t Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-ALL:      Test Suite '.*\.xctest' passed at \d+:\d+:\d+\.\d+
+// CHECK-ALL:      \t Executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK-ALL:      Test Suite 'All tests' passed at \d+:\d+:\d+\.\d+
+// CHECK-ALL:      \t Executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/SingleFailingTestCase/main.swift b/Tests/Functional/SingleFailingTestCase/main.swift
index ac75eaf..315cc69 100644
--- a/Tests/Functional/SingleFailingTestCase/main.swift
+++ b/Tests/Functional/SingleFailingTestCase/main.swift
@@ -8,6 +8,10 @@
     import SwiftXCTest
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'SingleFailingTestCase' started at \d+:\d+:\d+\.\d+
 class SingleFailingTestCase: XCTestCase {
     static var allTests: [(String, SingleFailingTestCase -> () throws -> Void)] {
         return [
@@ -15,15 +19,19 @@
         ]
     }
 
-// CHECK: Test Case 'SingleFailingTestCase.test_fails' started.
-// CHECK: .*/SingleFailingTestCase/main.swift:22: error: SingleFailingTestCase.test_fails : XCTAssertTrue failed -
-// CHECK: Test Case 'SingleFailingTestCase.test_fails' failed \(\d+\.\d+ seconds\).
+    // CHECK: Test Case 'SingleFailingTestCase.test_fails' started at \d+:\d+:\d+\.\d+
+    // CHECK: .*/SingleFailingTestCase/main.swift:26: error: SingleFailingTestCase.test_fails : XCTAssertTrue failed -
+    // CHECK: Test Case 'SingleFailingTestCase.test_fails' failed \(\d+\.\d+ seconds\).
     func test_fails() {
         XCTAssert(false)
     }
 }
+// CHECK: Test Suite 'SingleFailingTestCase' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 1 test, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 XCTMain([testCase(SingleFailingTestCase.allTests)])
 
-// CHECK: Executed 1 test, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
-// CHECK: Total executed 1 test, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 1 test, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' failed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 1 test, with 1 failure \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/TestCaseLifecycle/main.swift b/Tests/Functional/TestCaseLifecycle/main.swift
index e2e5d40..84929d0 100644
--- a/Tests/Functional/TestCaseLifecycle/main.swift
+++ b/Tests/Functional/TestCaseLifecycle/main.swift
@@ -8,6 +8,10 @@
     import SwiftXCTest
 #endif
 
+// CHECK: Test Suite 'All tests' started at \d+:\d+:\d+\.\d+
+// CHECK: Test Suite '.*\.xctest' started at \d+:\d+:\d+\.\d+
+
+// CHECK: Test Suite 'SetUpTearDownTestCase' started at \d+:\d+:\d+\.\d+
 class SetUpTearDownTestCase: XCTestCase {
     static var allTests: [(String, SetUpTearDownTestCase -> () throws -> Void)] {
         return [
@@ -28,7 +32,7 @@
         print("In \(#function)")
     }
 
-// CHECK: Test Case 'SetUpTearDownTestCase.test_hasValueFromSetUp' started.
+// CHECK: Test Case 'SetUpTearDownTestCase.test_hasValueFromSetUp' started at \d+:\d+:\d+\.\d+
 // CHECK: In setUp\(\)
 // CHECK: In test_hasValueFromSetUp\(\)
 // CHECK: In tearDown\(\)
@@ -38,9 +42,11 @@
         XCTAssertEqual(value, 42)
     }
 }
-// CHECK: Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'SetUpTearDownTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 
+// CHECK: Test Suite 'NewInstanceForEachTestTestCase' started at \d+:\d+:\d+\.\d+
 class NewInstanceForEachTestTestCase: XCTestCase {
     static var allTests: [(String, NewInstanceForEachTestTestCase -> () throws -> Void)] {
         return [
@@ -51,20 +57,21 @@
 
     var value = 1
 
-// CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValue' started.
+// CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValue' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValue' passed \(\d+\.\d+ seconds\).
     func test_hasInitializedValue() {
         XCTAssertEqual(value, 1)
         value += 1
     }
 
-// CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValueInAnotherTest' started.
+// CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValueInAnotherTest' started at \d+:\d+:\d+\.\d+
 // CHECK: Test Case 'NewInstanceForEachTestTestCase.test_hasInitializedValueInAnotherTest' passed \(\d+\.\d+ seconds\).
     func test_hasInitializedValueInAnotherTest() {
         XCTAssertEqual(value, 1)
     }
 }
-// CHECK: Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'NewInstanceForEachTestTestCase' passed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 2 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
 
 
 XCTMain([
@@ -72,4 +79,7 @@
     testCase(NewInstanceForEachTestTestCase.allTests)
 ])
 
-// CHECK: Total executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite '.*\.xctest' passed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
+// CHECK: Test Suite 'All tests' passed at \d+:\d+:\d+\.\d+
+// CHECK: \t Executed 3 tests, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds
diff --git a/Tests/Functional/xctest_checker/tests/test_compare.py b/Tests/Functional/xctest_checker/tests/test_compare.py
index e64836e..3d33c44 100644
--- a/Tests/Functional/xctest_checker/tests/test_compare.py
+++ b/Tests/Functional/xctest_checker/tests/test_compare.py
@@ -12,6 +12,7 @@
 import unittest
 
 from xctest_checker import compare
+from xctest_checker.error import XCTestCheckerError
 
 
 def _tmpfile(content):
@@ -26,30 +27,52 @@
     def test_no_match_raises(self):
         actual = _tmpfile('foo\nbar\nbaz\n')
         expected = _tmpfile('c: foo\nc: baz\nc: bar\n')
-        with self.assertRaises(AssertionError):
+        with self.assertRaises(XCTestCheckerError):
             compare.compare(actual, expected, check_prefix='c: ')
 
-    def test_too_few_expected_raises(self):
+    def test_too_few_expected_raises_and_first_line_in_error(self):
         actual = _tmpfile('foo\nbar\nbaz\n')
         expected = _tmpfile('c: foo\nc: bar\n')
-        with self.assertRaises(AssertionError):
+        with self.assertRaises(XCTestCheckerError) as cm:
             compare.compare(actual, expected, check_prefix='c: ')
 
-    def test_too_many_expected_raises(self):
+        self.assertIn('{}:{}'.format(expected, 1), cm.exception.message)
+
+    def test_too_many_expected_raises_and_excess_check_line_in_error(self):
         actual = _tmpfile('foo\nbar\n')
         expected = _tmpfile('c: foo\nc: bar\nc: baz\n')
-        with self.assertRaises(AssertionError):
+        with self.assertRaises(XCTestCheckerError) as cm:
             compare.compare(actual, expected, check_prefix='c: ')
 
+        self.assertIn('{}:{}'.format(expected, 3), cm.exception.message)
+
     def test_match_does_not_raise(self):
         actual = _tmpfile('foo\nbar\nbaz\n')
         expected = _tmpfile('c: foo\nc: bar\nc: baz\n')
         compare.compare(actual, expected, check_prefix='c: ')
 
+    def test_match_with_inline_check_does_not_raise(self):
+        actual = _tmpfile('bling\nblong\n')
+        expected = _tmpfile('meep meep // c: bling\nmeep\n// c: blong\n')
+        compare.compare(actual, expected, check_prefix='// c: ')
+
+    def test_check_prefix_twice_in_the_same_line_raises_with_line(self):
+        actual = _tmpfile('blorp\nbleep\n')
+        expected = _tmpfile('c: blorp\nc: bleep c: blammo\n')
+        with self.assertRaises(XCTestCheckerError) as cm:
+            compare.compare(actual, expected, check_prefix='c: ')
+
+        self.assertIn('{}:{}'.format(expected, 2), cm.exception.message)
+
+    def test_check_prefix_in_run_line_ignored(self):
+        actual = _tmpfile('flim\n')
+        expected = _tmpfile('// RUN: xctest_checker --prefix "c: "\nc: flim\n')
+        compare.compare(actual, expected, check_prefix='c: ')
+
     def test_includes_file_name_and_line_of_expected_in_error(self):
         actual = _tmpfile('foo\nbar\nbaz\n')
         expected = _tmpfile('c: foo\nc: baz\nc: bar\n')
-        with self.assertRaises(AssertionError) as cm:
+        with self.assertRaises(XCTestCheckerError) as cm:
             compare.compare(actual, expected, check_prefix='c: ')
 
         self.assertIn("{}:{}:".format(expected, 2), cm.exception.message)
diff --git a/Tests/Functional/xctest_checker/xctest_checker/compare.py b/Tests/Functional/xctest_checker/xctest_checker/compare.py
index cc9e4f4..a77da7b 100644
--- a/Tests/Functional/xctest_checker/xctest_checker/compare.py
+++ b/Tests/Functional/xctest_checker/xctest_checker/compare.py
@@ -10,6 +10,8 @@
 
 import re
 
+from .error import XCTestCheckerError
+
 
 def _actual_lines(path):
     """
@@ -26,13 +28,33 @@
     that begins with the given prefix.
     """
     with open(path) as f:
-        for line_number, line in enumerate(f):
-            if line.startswith(check_prefix):
-                yield line[len(check_prefix):].strip(), line_number+1
+        for index, line in enumerate(f):
+            if 'RUN:' in line:
+                # Ignore lit directives, which may include a call to
+                # xctest_checker that specifies a check prefix.
+                continue
+
+            # Note that line numbers are not zero-indexed; we must add one to
+            # the loop index.
+            line_number = index + 1
+
+            components = line.split(check_prefix)
+            if len(components) == 2:
+                yield components[1].strip(), line_number
+            elif len(components) > 2:
+                # Include a newline, then the file name and line number in the
+                # exception in order to have it appear as an inline failure in
+                # Xcode.
+                raise XCTestCheckerError(
+                    path, line_number,
+                    'Usage violation: prefix "{}" appears twice in the same '
+                    'line.'.format(check_prefix))
+
 
 def _add_whitespace_leniency(original_regex):
     return "^ *" + original_regex + " *$"
 
+
 def compare(actual, expected, check_prefix):
     """
     Compares each line in the two given files.
@@ -40,23 +62,30 @@
     file, raises an AssertionError. Also raises an AssertionError if the number
     of lines in the two files differ.
     """
-    for actual_line, expected_line_and_line_number in map(
+    for actual_line, expected_line_and_number in map(
             None,
             _actual_lines(actual),
             _expected_lines_and_line_numbers(expected, check_prefix)):
 
-        if actual_line is None:
-            raise AssertionError('There were more lines expected to appear '
-                                 'than there were lines in the actual input.')
-        if expected_line_and_line_number is None:
-            raise AssertionError('There were more lines than expected to '
-                                 'appear.')
+        if expected_line_and_number is None:
+            raise XCTestCheckerError(
+                expected, 1,
+                'The actual output contained more lines of text than the '
+                'expected output. First unexpected line: {}'.format(
+                    repr(actual_line)))
 
-        (expected_line, expectation_source_line_number) = expected_line_and_line_number
+        (expected_line, expectation_line_number) = expected_line_and_number
+
+        if actual_line is None:
+            raise XCTestCheckerError(
+                expected, expectation_line_number,
+                'There were more lines expected to appear than there were '
+                'lines in the actual input. Unmet expectation: {}'.format(
+                    repr(expected_line)))
 
         if not re.match(_add_whitespace_leniency(expected_line), actual_line):
-            raise AssertionError('Actual line did not match the expected '
-                                 'regular expression.\n'
-                                 '{}:{}: Actual: {}\n'
-                                 'Expected: {}\n'.format(
-                                     expected, expectation_source_line_number, repr(actual_line), repr(expected_line)))
+            raise XCTestCheckerError(
+                expected, expectation_line_number,
+                'Actual line did not match the expected regular expression.\n'
+                'Actual: {}\nExpected: {}'.format(
+                    repr(actual_line), repr(expected_line)))
diff --git a/Tests/Functional/xctest_checker/xctest_checker/error.py b/Tests/Functional/xctest_checker/xctest_checker/error.py
new file mode 100644
index 0000000..68c4414
--- /dev/null
+++ b/Tests/Functional/xctest_checker/xctest_checker/error.py
@@ -0,0 +1,19 @@
+# xctest_checker/error.py - Errors that display nicely in Xcode -*- python -*-
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+# Licensed under Apache License v2.0 with Runtime Library Exception
+#
+# See http://swift.org/LICENSE.txt for license information
+# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+
+class XCTestCheckerError(Exception):
+    """
+    An exception that indicates an xctest_checker-based functional test should
+    fail. Formats exception messages such that they render inline in Xcode.
+    """
+    def __init__(self, path, line_number, message):
+        super(XCTestCheckerError, self).__init__(
+            '\n{}:{}: {}'.format(path, line_number, message))
diff --git a/XCTest.xcodeproj/project.pbxproj b/XCTest.xcodeproj/project.pbxproj
index bda83c9..93f6e92 100644
--- a/XCTest.xcodeproj/project.pbxproj
+++ b/XCTest.xcodeproj/project.pbxproj
@@ -13,11 +13,17 @@
 		AE7DD60C1C8F0513006FC722 /* XCTestObservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE7DD60B1C8F0513006FC722 /* XCTestObservation.swift */; };
 		AE9596DF1C96911F001A9EF0 /* ObjectWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE9596DE1C96911F001A9EF0 /* ObjectWrapper.swift */; };
 		AE9596E11C9692B8001A9EF0 /* XCTestObservationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE9596E01C9692B8001A9EF0 /* XCTestObservationCenter.swift */; };
+		AED59FF61CB5394800F49260 /* XCTestErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED59FF51CB5394800F49260 /* XCTestErrors.swift */; };
 		C265F66F1C3AEB6A00520CF9 /* XCTAssert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C265F6691C3AEB6A00520CF9 /* XCTAssert.swift */; };
 		C265F6701C3AEB6A00520CF9 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C265F66A1C3AEB6A00520CF9 /* XCTestCase.swift */; };
 		C265F6721C3AEB6A00520CF9 /* XCTestMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = C265F66C1C3AEB6A00520CF9 /* XCTestMain.swift */; };
-		C265F6731C3AEB6A00520CF9 /* XCTimeUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C265F66D1C3AEB6A00520CF9 /* XCTimeUtilities.swift */; };
+		DA7714F91CA87DEF001EA745 /* XCTestSuiteRun.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7714F81CA87DEF001EA745 /* XCTestSuiteRun.swift */; };
+		DA7714FB1CA87DFB001EA745 /* XCTestCaseRun.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7714FA1CA87DFB001EA745 /* XCTestCaseRun.swift */; };
+		DA7714FD1CA8D057001EA745 /* PrintObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7714FC1CA8D057001EA745 /* PrintObserver.swift */; };
+		DA7732481CA87278007E31FD /* XCTestRun.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7732471CA87278007E31FD /* XCTestRun.swift */; };
 		DA7805FA1C6704A2003C6636 /* SwiftFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7805F91C6704A2003C6636 /* SwiftFoundation.framework */; };
+		DA7FB3431CA4EA4000F024F9 /* XCTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7FB3421CA4EA4000F024F9 /* XCTestSuite.swift */; };
+		DA7FB38F1CA4EE3800F024F9 /* XCAbstractTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7FB38E1CA4EE3800F024F9 /* XCAbstractTest.swift */; };
 		DACC94421C8B87B900EC85F5 /* XCWaitCompletionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACC94411C8B87B900EC85F5 /* XCWaitCompletionHandler.swift */; };
 		DADB979C1C51BDA2005E68B6 /* XCTestExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = DADB979B1C51BDA2005E68B6 /* XCTestExpectation.swift */; };
 /* End PBXBuildFile section */
@@ -41,14 +47,20 @@
 		AE7DD60B1C8F0513006FC722 /* XCTestObservation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestObservation.swift; sourceTree = "<group>"; };
 		AE9596DE1C96911F001A9EF0 /* ObjectWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectWrapper.swift; sourceTree = "<group>"; };
 		AE9596E01C9692B8001A9EF0 /* XCTestObservationCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestObservationCenter.swift; sourceTree = "<group>"; };
+		AED59FF51CB5394800F49260 /* XCTestErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestErrors.swift; sourceTree = "<group>"; };
 		B1384A411C1B3E8700EDF031 /* CONTRIBUTING.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTING.md; sourceTree = "<group>"; };
 		B1384A421C1B3E8700EDF031 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
 		B1384A431C1B3E8700EDF031 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
 		C265F6691C3AEB6A00520CF9 /* XCTAssert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTAssert.swift; sourceTree = "<group>"; };
 		C265F66A1C3AEB6A00520CF9 /* XCTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestCase.swift; sourceTree = "<group>"; };
 		C265F66C1C3AEB6A00520CF9 /* XCTestMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestMain.swift; sourceTree = "<group>"; };
-		C265F66D1C3AEB6A00520CF9 /* XCTimeUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTimeUtilities.swift; sourceTree = "<group>"; };
+		DA7714F81CA87DEF001EA745 /* XCTestSuiteRun.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestSuiteRun.swift; sourceTree = "<group>"; };
+		DA7714FA1CA87DFB001EA745 /* XCTestCaseRun.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestCaseRun.swift; sourceTree = "<group>"; };
+		DA7714FC1CA8D057001EA745 /* PrintObserver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrintObserver.swift; sourceTree = "<group>"; };
+		DA7732471CA87278007E31FD /* XCTestRun.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestRun.swift; sourceTree = "<group>"; };
 		DA7805F91C6704A2003C6636 /* SwiftFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftFoundation.framework; path = "../swift-corelibs-foundation/build/Debug/SwiftFoundation.framework"; sourceTree = "<group>"; };
+		DA7FB3421CA4EA4000F024F9 /* XCTestSuite.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestSuite.swift; sourceTree = "<group>"; };
+		DA7FB38E1CA4EE3800F024F9 /* XCAbstractTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCAbstractTest.swift; sourceTree = "<group>"; };
 		DACC94411C8B87B900EC85F5 /* XCWaitCompletionHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCWaitCompletionHandler.swift; sourceTree = "<group>"; };
 		DADB979B1C51BDA2005E68B6 /* XCTestExpectation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestExpectation.swift; sourceTree = "<group>"; };
 		EA3E74BB1BF2B6D500635A73 /* build_script.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = build_script.py; sourceTree = "<group>"; };
@@ -112,13 +124,19 @@
 				AE7DD6071C8E81A0006FC722 /* ArgumentParser.swift */,
 				AE9596DE1C96911F001A9EF0 /* ObjectWrapper.swift */,
 				AE7DD6081C8E81A0006FC722 /* TestFiltering.swift */,
+				DA7714FC1CA8D057001EA745 /* PrintObserver.swift */,
 				C265F6691C3AEB6A00520CF9 /* XCTAssert.swift */,
+				DA7FB38E1CA4EE3800F024F9 /* XCAbstractTest.swift */,
+				DA7FB3421CA4EA4000F024F9 /* XCTestSuite.swift */,
+				DA7732471CA87278007E31FD /* XCTestRun.swift */,
 				C265F66A1C3AEB6A00520CF9 /* XCTestCase.swift */,
+				DA7714F81CA87DEF001EA745 /* XCTestSuiteRun.swift */,
+				DA7714FA1CA87DFB001EA745 /* XCTestCaseRun.swift */,
+				AED59FF51CB5394800F49260 /* XCTestErrors.swift */,
 				DADB979B1C51BDA2005E68B6 /* XCTestExpectation.swift */,
 				C265F66C1C3AEB6A00520CF9 /* XCTestMain.swift */,
 				AE7DD60B1C8F0513006FC722 /* XCTestObservation.swift */,
 				AE9596E01C9692B8001A9EF0 /* XCTestObservationCenter.swift */,
-				C265F66D1C3AEB6A00520CF9 /* XCTimeUtilities.swift */,
 				DACC94411C8B87B900EC85F5 /* XCWaitCompletionHandler.swift */,
 				510957A81CA878410091D1A1 /* XCNotificationExpectationHandler.swift */,
 			);
@@ -253,15 +271,21 @@
 			files = (
 				DACC94421C8B87B900EC85F5 /* XCWaitCompletionHandler.swift in Sources */,
 				510957A91CA878410091D1A1 /* XCNotificationExpectationHandler.swift in Sources */,
-				C265F6731C3AEB6A00520CF9 /* XCTimeUtilities.swift in Sources */,
 				AE7DD60C1C8F0513006FC722 /* XCTestObservation.swift in Sources */,
+				DA7FB38F1CA4EE3800F024F9 /* XCAbstractTest.swift in Sources */,
 				C265F6701C3AEB6A00520CF9 /* XCTestCase.swift in Sources */,
 				DADB979C1C51BDA2005E68B6 /* XCTestExpectation.swift in Sources */,
+				DA7714FD1CA8D057001EA745 /* PrintObserver.swift in Sources */,
 				AE7DD60A1C8E81A0006FC722 /* TestFiltering.swift in Sources */,
 				AE7DD6091C8E81A0006FC722 /* ArgumentParser.swift in Sources */,
+				DA7732481CA87278007E31FD /* XCTestRun.swift in Sources */,
 				AE9596E11C9692B8001A9EF0 /* XCTestObservationCenter.swift in Sources */,
+				DA7714FB1CA87DFB001EA745 /* XCTestCaseRun.swift in Sources */,
 				C265F66F1C3AEB6A00520CF9 /* XCTAssert.swift in Sources */,
+				DA7FB3431CA4EA4000F024F9 /* XCTestSuite.swift in Sources */,
+				DA7714F91CA87DEF001EA745 /* XCTestSuiteRun.swift in Sources */,
 				AE9596DF1C96911F001A9EF0 /* ObjectWrapper.swift in Sources */,
+				AED59FF61CB5394800F49260 /* XCTestErrors.swift in Sources */,
 				C265F6721C3AEB6A00520CF9 /* XCTestMain.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;