File: XCTestRun.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (186 lines) | stat: -rw-r--r-- 6,766 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// 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.
//

/// 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".
open 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.
    open private(set) var startDate: Date?

    /// The time at which the test run was stopped, or nil.
    open private(set) var stopDate: Date?

    /// The number of seconds that elapsed between when the run was started and
    /// when it was stopped.
    open var totalDuration: TimeInterval {
        if let stop = stopDate, let start = startDate {
            return stop.timeIntervalSince(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.
    open var testDuration: TimeInterval {
        return totalDuration
    }

    /// The number of tests in the run.
    open var testCaseCount: Int {
        return test.testCaseCount
    }

    /// The number of test executions recorded during the run.
    open private(set) var executionCount: Int = 0

    /// The number of test skips recorded during the run.
    open var skipCount: Int {
        hasBeenSkipped ? 1 : 0
    }

    /// The number of test failures recorded during the run.
    open private(set) var failureCount: Int = 0

    /// The number of uncaught exceptions recorded during the run.
    open private(set) var unexpectedExceptionCount: Int = 0

    /// The total number of test failures and uncaught exceptions recorded
    /// during the run.
    open var totalFailureCount: Int {
        return failureCount + unexpectedExceptionCount
    }

    /// `true` if all tests in the run completed their execution without
    /// recording any failures, otherwise `false`.
    open var hasSucceeded: Bool {
        guard isStopped else {
            return false
        }
        return totalFailureCount == 0
    }

    /// `true` if the test was skipped, otherwise `false`.
    open private(set) var hasBeenSkipped = false

    /// 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.
    open 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 = Date()
    }

    /// Stop a test run. Must not be called unless the run has been started.
    /// Must not be called more than once.
    open 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 = Date()
    }

    /// 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: Int, expected: Bool) {
        func failureLocation() -> String {
            if let filePath = filePath {
                return "\(test.name) (\(filePath):\(lineNumber))"
            } else {
                return "\(test.name)"
            }
        }

        guard isStarted else {
            fatalError("Invalid attempt to record a failure for a test run " +
                       "that has not yet been started: \(failureLocation())")
        }
        guard !isStopped else {
            fatalError("Invalid attempt to record a failure for a test run " +
                       "that has already been stopped: \(failureLocation())")
        }

        if expected {
            failureCount += 1
        } else {
            unexpectedExceptionCount += 1
        }
    }

    func recordSkip(description: String, sourceLocation: SourceLocation?) {
        func failureLocation() -> String {
            if let sourceLocation = sourceLocation {
                return "\(test.name) (\(sourceLocation.file):\(sourceLocation.line))"
            } else {
                return "\(test.name)"
            }
        }

        guard isStarted else {
            fatalError("Invalid attempt to record a skip for a test run " +
                       "that has not yet been started: \(failureLocation())")
        }
        guard !hasBeenSkipped else {
            fatalError("Invalid attempt to record a skip for a test run " +
                       "that has already been skipped: \(failureLocation())")
        }
        guard !isStopped else {
            fatalError("Invalid attempt to record a skip for a test run " +
                       "has already been stopped: \(failureLocation())")
        }

        hasBeenSkipped = true
    }

    private var isStarted: Bool {
        return startDate != nil
    }

    private var isStopped: Bool {
        return isStarted && stopDate != nil
    }
}