Skip to content

Commit fe31f89

Browse files
committed
Add class-level setUp and tearDown methods on XCTestCase
1 parent 0610ec3 commit fe31f89

File tree

4 files changed

+53
-8
lines changed

4 files changed

+53
-8
lines changed

Sources/XCTest/XCTestCase.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,14 @@ public class XCTestCase: XCTest {
129129
fatalError("Terminating execution due to test failure")
130130
}
131131
}
132+
133+
/// Setup method called before the invocation of any test method in the
134+
/// class.
135+
public class func setUp() {}
136+
137+
/// Teardown method called after the invocation of every test method in the
138+
/// class.
139+
public class func tearDown() {}
132140
}
133141

134142
/// Wrapper function allowing an array of static test case methods to fit

Sources/XCTest/XCTestMain.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,9 @@
7575
}
7676

7777
let filter = TestFiltering(selectedTestName: selectedTestName)
78-
for (testCaseClass, testCaseMethods) in TestFiltering.filterTests(testCases, filter: filter.selectedTestFilter) {
79-
let testCaseSuite = XCTestSuite(name: "\(testCaseClass)")
80-
for (testName, testClosure) in testCaseMethods {
81-
let testCase = testCaseClass.init(name: testName, testClosure: testClosure)
82-
testCaseSuite.addTest(testCase)
83-
}
84-
currentTestSuite.addTest(testCaseSuite)
85-
}
78+
TestFiltering.filterTests(testCases, filter: filter.selectedTestFilter)
79+
.map(XCTestCaseSuite.init)
80+
.forEach(currentTestSuite.addTest)
8681

8782
rootTestSuite.run()
8883

Sources/XCTest/XCTestSuite.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,33 @@ public class XCTestSuite: XCTest {
6868
tests.append(test)
6969
}
7070
}
71+
72+
/// A test suite which is associated with a particular test case class. It will
73+
/// call `setUp` and `tearDown` on the class itself before and after invoking
74+
/// all of the test cases making up the class.
75+
internal class XCTestCaseSuite: XCTestSuite {
76+
private let testCaseClass: XCTestCase.Type?
77+
78+
init(testCaseEntry: XCTestCaseEntry) {
79+
let testCaseClass = testCaseEntry.0
80+
self.testCaseClass = testCaseClass
81+
super.init(name: String(testCaseClass))
82+
83+
for (testName, testClosure) in testCaseEntry.1 {
84+
let testCase = testCaseClass.init(name: testName, testClosure: testClosure)
85+
addTest(testCase)
86+
}
87+
}
88+
89+
override func setUp() {
90+
if let testCaseClass = testCaseClass {
91+
testCaseClass.setUp()
92+
}
93+
}
94+
95+
override func tearDown() {
96+
if let testCaseClass = testCaseClass {
97+
testCaseClass.tearDown()
98+
}
99+
}
100+
}

Tests/Functional/TestCaseLifecycle/main.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ class SetUpTearDownTestCase: XCTestCase {
2121

2222
var value = 0
2323

24+
// CHECK: In class setUp\(\)
25+
override class func setUp() {
26+
super.setUp()
27+
print("In class \(#function)")
28+
}
29+
2430
override func setUp() {
2531
super.setUp()
2632
print("In \(#function)")
@@ -41,6 +47,12 @@ class SetUpTearDownTestCase: XCTestCase {
4147
print("In \(#function)")
4248
XCTAssertEqual(value, 42)
4349
}
50+
51+
// CHECK: In class tearDown\(\)
52+
override class func tearDown() {
53+
super.tearDown()
54+
print("In class \(#function)")
55+
}
4456
}
4557
// CHECK: Test Suite 'SetUpTearDownTestCase' passed at \d+:\d+:\d+\.\d+
4658
// CHECK: \t Executed 1 test, with 0 failures \(0 unexpected\) in \d+\.\d+ \(\d+\.\d+\) seconds

0 commit comments

Comments
 (0)