iosswiftunit-testingswift-testing

How to verify assertionFailure() in unit tests using Swift Testing framework?


I use the Swift Testing framework to implement unit tests in my iOS project. In one of my tests, I need to verify that assertionFailure() is triggered under certain conditions.

Here’s an example code snippet:

func foo(bar: Bool) -> String {
    if bar {
        return "foobar"
    } else {
        assertionFailure("expected true but was false")
        return nil
    }
}

In this example, I want to test that assertionFailure() is called when bar is false. Is it possible to capture and verify this behavior using the Swift Testing framework? If so, how can I do it?

Any insights or suggestions would be appreciated!


Solution

  • Your foo demo method will not even compile because assertionFailure only affects debug builds and would therefore not guarantee that your method always returns a value.

    Writing a unit test for methods using assertionFailure generally makes little sense, because debug builds would behave differently compared to release builds.

    If you actually meant preconditionFailure instead, which works for debug and release builds alike, then testing this method is currently not supported by Swift Testing.

    preconditionFailure / assertionFailure cause a Mach EXC_BAD_INSTRUCTION exception which can only be caught by a corresponding Mach exception handler.

    Beyond Swift Testing, you could use Nimble, for example, to test preconditionFailure calls. Nimble does support assertion tests by using CwlPreconditionTesting. Of course, you could also use CwlPreconditionTesting directly in combination with Swift Testing instead of Nimble.

    However, I would like to point out that you should be very careful when using preconditionFailure calls and it is almost always better to use Swift's normal error handling.