Xcode UI Testing Tip

February 03, 2016

You’re using Xcode’s UI Testing framework, right? It’s a fantastic way to prevent bugs and know when refactoring you’re not breaking some dark corner of your app. It’s not always easy though! UI testing is still an early technology in Xcode 7. There are bugs, and asynchronous network calls can lead to frustrating false positives.

Here’s an incredibly easy tip to improve your tests: run them on a device with Network Link Conditioner set to “Very Bad Network.”

Things will time out. Your tests will fail. But that’s okay. You’ll quickly see places where it’s the test that’s at fault, and something timed out before a network operation completed. Some of these you can fix that with this snippet:

func waitUntilVisible(element: XCUIElement, file: String = __FILE__, line: UInt = __LINE__) {
    expectationForPredicate(NSPredicate(format: "exists == 1"), evaluatedWithObject: element, handler: nil)
    waitForExpectationsWithTimeout(30) { (error) in
        guard error != nil else { return }
        let message = "Failed to find \(element) after 30 seconds."
        self.recordFailureWithDescription(message, inFile: file, atLine: line, expected: true)
    }
}

What’s more interesting are the places where it’s not the test. I’ll bet you find some interesting race conditions you wouldn’t normally see, even when using Network Link Conditioner during your own debugging. Enjoy this, it’s not always this easy to find these types of bugs!

Marc Charbonneau is a mobile software engineer in Portland, OR. Want to reply to this article? Get in touch on Twitter @mbcharbonneau.