failing a XCTestCase with assert without the test continuing to run but without stopping other tests

我怕爱的太早我们不能终老 提交于 2019-12-02 22:32:23

Pascal's answer gave me the idea to achieve this properly. XCTool now behaves like OCUnit when an assertion fails: the execution of the test case is aborted immediately, tearDown invoked and the next test case is run.

Simply override the method invokeTest in your base class (the one that inherits from the XCTestCase class):

- (void)invokeTest
{
    self.continueAfterFailure = NO;

    @try
    {
        [super invokeTest];
    }
    @finally
    {
        self.continueAfterFailure = YES;
    }
}

That's it!

The easiest way is to add:

continueAfterFailure = false

into setUp() method. So it will look like this:

Swift

override func setUp() {
    super.setUp()

    continueAfterFailure = false
}

Objective-C

 - (void)setUp {
    [super setUp];

    [self setContinueAfterFailure:NO];
}

One option would be to check the condition normally, then fail and return from the test if it is false.

Something like this:

if (!condition) {
  XCFail(@"o noes");
  return;
}

You could wrap this up in a helper macro to preserve readability.

BDD test libraries like Kiwi are more elegant for this sort of thing, as they make it easier to share setup between many tests which leads to fewer assertions per test.

I am able to use continueAfterFailure and let the other tests run by using this pattern:

self.continueAfterFailure = NO;
@try
{
    // Perform test code here
}
@finally
{
    self.continueAfterFailure = YES;
}

In Swift projects, I use a helper function (defined in a shared superclass of all my tests which itself 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")
}

As the comment suggests, the call to fatalError is never actually executed; XCTFail aborts the test in an orderly fashion (tearDown is called, next test runs, etc.). The call is only there to trick the compiler into accepting Never as return type since XCTFail returns Void (it does return if continueAfterFailure == true).

Note that self.continueAfterFailure is reset to the default true for every test method. You can also make that explicit in setUp().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!