我正在尝试使用 XCTest 框架测试我的应用程序。
如果某些逻辑条件成立(使用断言),我希望我的单个测试用例失败。我不希望测试用例中的其余代码运行,因为这可能会导致问题(例如访问空指针)我还希望测试用例的其余部分正常运行,而只是失败的测试被标记为失败。
我注意到 XCTestCase 有一个名为 continueAfterFailure 的属性。但是,将其设置为 YES 会导致失败的测试在断言之后继续执行行,并将其设置为 NO 会导致其余测试根本不运行。
这个问题有解决方案吗?
帕斯卡的回答给了我正确实现这一目标的想法。现在,当断言失败时,XCTool 的行为类似于 OCUnit:测试用例的执行立即中止,调用 tearDown 并运行下一个测试用例。
只需覆盖invokeTest
基类中的方法(从 XCTestCase 类继承的方法):
- (void)invokeTest
{
self.continueAfterFailure = NO;
@try
{
[super invokeTest];
}
@finally
{
self.continueAfterFailure = YES;
}
}
而已!
最简单的方法是添加:
continueAfterFailure = false
进入 setUp() 方法。所以它看起来像这样:
迅速
override func setUp() {
super.setUp()
continueAfterFailure = false
}
Objective-C
- (void)setUp {
[super setUp];
[self setContinueAfterFailure:NO];
}
一种选择是正常检查条件,如果为假则失败并从测试中返回。
像这样的东西:
if (!condition) {
XCFail(@"o noes");
return;
}
您可以将其包装在辅助宏中以保持可读性。
像Kiwi这样的BDD 测试库对于这类事情来说更加优雅,因为它们可以更轻松地在许多测试之间共享设置,从而减少每个测试的断言。
我可以continueAfterFailure
使用此模式并让其他测试运行:
self.continueAfterFailure = NO;
@try
{
// Perform test code here
}
@finally
{
self.continueAfterFailure = YES;
}
在 Swift 项目中,我使用了一个辅助函数(在我的所有测试的共享超类中定义,它本身 extends XCTestCase
):
/// Like `XCTFail(...)` but aborts the test.
func XCTAbortTest(_ message: String,
file: StaticString = #file, line: UInt = #line
) -> Never {
self.continueAfterFailure = false
XCTFail(message, file: file, line: line)
fatalError("never reached")
}
正如评论所暗示的那样,调用fatalError
从未真正执行过;XCTFail
以有序的方式中止测试(tearDown
被调用,下一个测试运行等)。该调用只是为了欺骗编译器接受Never
作为返回类型,因为XCTFail
返回Void
(它确实返回 if continueAfterFailure == true
)。
请注意,每个测试方法都会self.continueAfterFailure
重置为默认值。true
您也可以在setUp()
.