UITests failing when run in group but succeed when run independently

Refresh

April 2019

Views

124 time

1

I'm currently working on a project with many asynchronous code and I'm writing the UITests for this project. During the development I run them one by one but never in a group. So I thought the tests are succeeding. But when testing them all together most of them are failing. I implemented the setup and teardown properly. I researched the reasons for this behaviour but I couldn't find any good answer to this problem. It's like the wait for expectations are not working properly...

Here is the method that makes most of the problems. I'm calling this one every time when I want to wait for an element to appear.

/*
* This method will wait for an element (10 seconds default) afterwards it will assert it existence
*
* - parameter toAppear:The condition we are waiting for.
* - parameter element: The element to be expected
* - parameter timeout: The MAX time that the function will wait for the element, 10 seconds if none is given
* - parameter file:    The file where the error will be displayed, the current file will be used in case none is provided
* - parameter line:    The code line where the error will be displayed, the current line will be used in case none is provided
*/
static func assertForElement(toAppear: Bool, _ element: XCUIElement?, timeout: TimeInterval = 10, file: String = #file, line: Int = #line) {

    guard let currentTestCase = BaseXCTestCase.CurrentTestCase else {
        return
    }

    guard let element = element else {
        let message = "Element cannot be empty"

        currentTestCase.recordFailure(withDescription: message, inFile: file, atLine: line, expected: true)

        return
    }

    let existsPredicate = NSPredicate(format: "exists == \(toAppear)")

    currentTestCase.expectation(for: existsPredicate, evaluatedWith: element, handler: nil)
    currentTestCase.waitForExpectations(timeout: timeout) { [weak currentTestCase] (error: Error?) in

        if (error != nil) {
            let appearMessage = "Failed to find \(String(describing: element)) after \(timeout) seconds."
            let disappearMessage = "Failed to see \(String(describing: element)) disappear after \(timeout) seconds."

            currentTestCase?.recordFailure(withDescription: ((toAppear == false) ? disappearMessage : appearMessage), inFile: file, atLine: line, expected: true)
        }
    }
}

Does anyone have a good method to UITest async code?

Thank you very much in advance!

UPDATE

Here are the error warnings I get.

most of the time I just get: Asynchronous wait failed: Exceeded timeout of 10 seconds, with unfulfilled expectations: "Expect predicateexists == 1for object but the element is visible and clickable in the simulator. On the other hand I get: caught "NSInternalInconsistencyException", "API violation - creating expectations while already in waiting mode."...

1 answers

3

Your error message implies that you are creating additional expectations after you've called waitForExpectations.

Create all of your expectations first and then call waitForExpectations as the final line of code in your test.