It is possible to do exactly what you want, I just managed to do it, like this:
Use recordFailure
You can achieve what you want just by calling recordFailure, in any test (inheriting from standard XCTestCase).
Shorter syntax
Either extend XCTestCase
If you want to simplify the call to this function you either write an extension function wrapping it.
or subclass
You can also subclass XCTestCase (which can be a good idea if you want to share some setup, being called in setup, then you only need to do it in this new superclass to your test classes).
class TestCase: XCTestCase {
func forwardFailure(
withDescription description: String = "Something went wrong",
inFile filePath: String = #file,
atLine line: Int = #line,
expected: Bool = false
) {
self.recordFailure(
withDescription: description,
inFile: filePath,
atLine: line,
expected: expected
)
}
}
I'm not sure how to use expected: Bool, it is a required argument for the recordFailure method (source), but looks like Apple mostly sets it to false.
Custom assert methods
Now you can declare your custom assert methods, like this (or as an extension on just XCTestCase, depending on your choice):
extension TestCase {
/// Since `Foobar.Type` does not conform to `Equatable`, even if `Foobar` conforms to `Equatable`, we are unable to write `XCTAssertEquals(type(of: foo), Foobar.self)`, this assert method fixes that.
func XCTAssertType<Actual, Expected>(
of actual: Actual,
is expectedType: Expected.Type,
_ filePath: String = #file,
_ line: Int = #line
) {
if let _ = actual as? Expected { return /* success */ }
let actualType = Mirror(reflecting: actual).subjectType
forwardFailure(
withDescription: "Expected '\(actual)' to be of type '\(expectedType)', but was: '\(actualType)'",
inFile: filePath,
atLine: line
)
}
}
And now it reports the error, not inside the custom assert, but at call site .
Using standard assert methods + forward location in file
You can also just forward the line of, and pass to standards asserts, if you look at e.g. XCTAssertTrue, it accepts a line argument, and a file argument.