XCTFail immediately aborts the test in Xcode 26 — no retry on failure

Hi,

I’m seeing an unexpected change in how XCTFail behaves in UI tests after updating Xcode.

I use the following helper method:

`func waitForExistance(file: StaticString, line: UInt) -> Self {
    if !(element.exists || element.waitForExistence(timeout: Configuration.current.predicateTimeout)) {
        XCTFail("couldn't find element: \(element) after \(Configuration.current.predicateTimeout) seconds",
                file: file,
                line: line)
        return self
    } else {
        return self
    }
}`

In Xcode 16.4, this worked as expected: – when an element wasn’t found, XCTFail was triggered, but the test continued running, allowing my retry logic to execute.

After updating to Xcode 26.1 / 26.2 - the test now immediately aborts after XCTFail, without executing the next retry.

The logs show:

`t =   113.22s Tear Down
t =   113.22s     Terminate com.viessmann.care:81789
*** Assertion failure in -[UITests.Tests _caughtUnhandledDeveloperExceptionPermittingControlFlowInterruptions:caughtInterruptionException:whileExecutingBlock:], XCTestCase+IssueHandling.m:273
Test Case '-[UITests.Tests test_case]' failed (114.323 seconds).
Flushing outgoing messages to the IDE with timeout 600.00s
Received confirmation that IDE processed remaining outgoing messages`

It looks like XCTFail in Xcode 26 is now treated as an unhandled developer exception, which stops the test execution immediately, even when it’s called inside a helper method. This was not the case in earlier versions.

My questions:

Is this a regression in XCTest?

Or an intentional change in how XCTFail behaves in newer Xcode versions?

Should failures now be reported differently (e.g., using record(.init(type: .assertionFailure, …))) if I want to continue the test instead of aborting it?

I would like to restore the previous behavior where the failure is logged without terminating the entire test, so my retry mechanism can still run.

Has anyone else run into this after upgrading?

Thanks in advance!

If you’d like, I can also add recommended workarounds that actually work with Xcode 16.4 (e.g., replacing XCTFail with a non-terminating issue record).

I’m seeing the same behaviour and it’s causing my test repetition mode to not fire and thus it doesn’t re-run tests

So after some investigation. I found having the async setup() function caused this behaviour to prevent retries. When moving to the synchronous setup function I no longer get issue. The problem being I need to do async code in my setup...

If I move my code to the following, test repetitions now work and I see no such errors

override func setUp() {
        super.setUp()
        continueAfterFailure = false
        // setup async seems to prevent test repetitions from working      
        let exp = expectation(description: "setup")
        Task {
            try await setupWebApp(router: router)
            exp.fulfill()
        }
        wait(for: [exp], timeout: 10)
    }
XCTFail immediately aborts the test in Xcode 26 — no retry on failure
 
 
Q