运行某些单元测试时,此错误不一致:
2018-12-20 09:11:34.892 MyApp [4530:106103] * void _XCTFailureHandler中的断言失败(XCTestCase * __强_Nonnull,BOOL,const char * _Nonnull,NSUInteger,NSString * __ strong _Nonnull,NSString * __ strong _Nullable,... )(),/ Library / People / com.apple.xbs / Sources / XCTest_Sim / XCTest-14460.20 / Sources / XCTestFramework / Core / XCTestAssertionsImpl.m:41 2018-12-20 09:11:34.929 MyApp [4530:106103] *由于未捕获的异常'NSInternalInconsistencyException'终止应用程序,原因:'参数'测试“不能为零。”
似乎有些断言是失败的,因为参数是nil
,但我很难搞清楚哪一个。
环境:Xcode 10.1 iOS应用程序
在测试“完成”之后评估的XCTest
断言将在断言失败时抛出此异常:
由于未捕获的异常'NSInternalInconsistencyException'终止应用程序,原因:'参数'测试“不能为零。”
证明这一点的基本例子是以下测试:
func testRaceCondition() {
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 3) // Assertion fails and 'nil' exception is thrown 💥
}
}
断言是异步运行的,但测试不会等待异步块完成。因此,在评估断言时,测试已经完成并且测试用例已经被释放(因此是nil
)。
如果断言要通过,上面的代码不会抛出任何错误。以下代码似乎通过了测试,但从某种意义上说,如果失败会引发上述异常,而不是正确地使测试失败,那么它就是危险的:
func testRaceCondition() {
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 2) // Assertion passes 😱
}
}
为防止出现此问题,所有评估异步执行的块中的断言的测试都应使用期望并等待它们完成:
func testRaceCondition() {
let asyncExpectation = expectation(description: "Async block executed")
DispatchQueue.main.async {
XCTAssertEqual(1 + 1, 3)
asyncExpectation.fulfill()
}
waitForExpectations(timeout: 1, handler: nil)
}
通过使用期望,我们将获得正确的失败测试错误,而不是上面发布的难以调试的异常:
XCTAssertEqual失败:(“2”)不等于(“3”)