XCTestCase: Wait for app to idle
Asked Answered
D

3

17

My UI-test fails because the test waits endless until the app idles. I can not see that there is anything happening in the background, like a loading spinner.

It just occurs on one tab. All others tabs are tapable but the test fails on Screen 3. I I click on another tab after the test is caught on Screen 3 the test resumes and finishes successfully.

Any ideas?

- (void)testExample
{

    XCUIElementQuery* tabBarsQuery = self.app.tabBars;

    [tabBarsQuery.buttons[@"Screen2"] tap];
    [tabBarsQuery.buttons[@"Screen3"] tap];
    [tabBarsQuery.buttons[@"Screen1"] tap];
    [tabBarsQuery.buttons[@"Screen4"] tap];

}
Dee answered 10/11, 2015 at 7:12 Comment(0)
C
10

Perhaps you have some animation or some other background (or foreground) activity that updates your UI on the main thread frequently. This causes the app to never be "quiesce" - at least on this tab. In our application we had UIView animation with option Repeat. CPU usage was fine and it wasn't a battery drain, but it made the test fail every time. Disabling the animation fixed the issue. I couldn't find a way to force the test not to wait to be idle, so we ended up disabling the animation using #ifdef for the UI test target using runtime arguments as described here: https://mcmap.net/q/176630/-accessing-the-host-app-code-from-the-xcode-7-ui-test-target

Cilla answered 6/6, 2016 at 9:50 Comment(2)
Weird. There must be a way to force the testing process to ignore animations... animations are kind of normal in apps aren't they? The animations should not have any meaning to the test flow. Just because something is moving does not mean another button cannot be tapped, in a UI.Aboveboard
Maybe it was simply a bug of XCTest in some earlier version. I'm not 100% sure but I think this is working fine now i.e. there is a repeating animation but it does not fail the test.Cilla
S
2
let tabBarsQuery = self.app.tabBars
let button = tabBarsQuery.buttons[@"Screen2"]

while writing UI test cases, system taking time to make it hittable so we are creating a predicate for it and waiting for the button.

let predicate = NSPredicate(format: "isHittable == 1") expectation(for: 
predicate, evaluatedWith: button, handler: nil)
waitForExpectations(timeout:10, handler: nil)
button.tap()
Shotwell answered 21/5, 2019 at 13:37 Comment(1)
While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply.Elaterin
N
0

I had a similar case in SwiftUI UI testing.
The UI test was supposed to swipe a list cell using cell.swipeLeft(), which is waiting for the swipe animation to be finished.
However, the swipe was not executed because the view was re-drawn before the swipe animation could be started.
Thus, the UI test waited for the app to idle arbitrarily long.

Nakitanalani answered 16/3, 2023 at 9:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.