I believe the below behaviour is due to how XCTest
works, but wanted to verify my idea is impossible (currently) with Xcode and XCTest
. I want to create table tests in Swift that would automatically run a particular test and flag the failing ones at the line of creation. In code:
struct TestCase<SUT> {
let value: SUT
let expectation: AnyHashable
let file: StaticString
let line: UInt
let evaluate: (SUT) -> AnyHashable
init<T: Hashable>(
_ value: SUT,
is expectation: T,
on keyPath: KeyPath<SUT, T>,
file: StaticString = #file,
line: UInt = #line
) {
self.value = value
self.expectation = .init(expectation)
self.file = file
self.line = line
self.evaluate = { $0[keyPath: keyPath] }
}
}
open class TableTestCase<SUT>: XCTestCase {
var testCases: [String: TestCase<SUT>] { [:] }
func testAll() {
testCases.forEach { name, test in
XCTAssertEqual(
test.expectation,
test.evaluate(test.value),
"Test \(name) failed",
file: test.file,
line: test.line
)
}
}
}
Then, some subclass would look like the following block of code:
struct User {
let id: Int
}
final class UserTests: TableTestCase<User> {
override var testCases: [String: TestCase<User>] {
[
// This test case should fail
"1": TestCase(User(id: 1), is: 2, on: \.id)
]
}
}
However, when running tests with Command + U
yields successful tests. (On some (recent) version of Xcode, I get the run test UI element in the gutter and the tests fail, but not on beta 11.4.)
Note: If I switch from using generics to a protocol with an associated type and a protocol extension for testAll
, then the same (undesirable) behaviour occurs.
This article by @ole suggests that automatic test discovery is possible for Swift in Linux. Is there some compiler flag that exists for Xcode to do something similar for this use case?