3

I noticed that all my UI tests fail when the network is slow. For instance a user would try to login and then the next screen wouldn't load fast enough in order for another UIElement to be on screen.

How can I handle a slow network connection without using a delay() ?

Display Name
  • 4,502
  • 2
  • 47
  • 63
codeRefiner
  • 513
  • 4
  • 6

3 Answers3

0

You should definitely take a look at multi-threading. When handling network connections, you should make all this processing in a secondary thread. If not, the main thread will be blocked and the app will become unresponsive to the user.

Multi-threading is a very big subject. I recommend you to start looking at Apple's reference for this. You can also refer to a great course on iTunes U (lecture 11).

If you just want to give it a shot, here's the actual code (similar) that you will need:

dispatch_queue_t newQueue = dispatch_queue_create("networkQueue", NULL);

dispatch_async(newQueue, ^{

// here you need to call the networking processes

   dispatch_async(dispatch_get_main_queue(), ^{

     // if you need to update your UI, you need to get back to the main queue.
     // This block will be executed in your main queue.

    });
});
tomidelucca
  • 2,543
  • 1
  • 26
  • 26
  • 1
    Yeah I am fairly well versed with GCD and we do implement all network calls in background threads, however, the issue is that my automation code is seeking a UIElement on screen and it is not currently visible yet. To give you an example, say your about to load a screen full of text but you have a spinner going until the text loads. I want my automation code to be able to wait for the text to load but I don't want to use a target.delay() – codeRefiner Mar 12 '13 at 20:45
  • What can be used instead of target.delay()? It seems to be blocking the app's main thread. – martn_st Jan 08 '15 at 19:34
  • @maremmle I know it's been a while but I just posted a new answer explaining how we wait for networking / other background tasks in UIAutomation tests just in case. – lekksi Oct 08 '15 at 19:08
0

The only way I know of is using a delay. I usually have a activity indicator when loading stuff from the internet. So I add a delay while the activity indicator is displaying

while (activityIndicator.isVisible())
{
    UIALogger.logMessage("Loading");
    UIATarget.localTarget().delay(1);
} 
Johan de Klerk
  • 2,515
  • 3
  • 25
  • 35
0

Check out pushTimeout and popTimeout methods in the UIATarget. You can find the docs here.

Here is one code example from our iOS app UIAutomation tests:

// Tap "Post" button, which starts a network request
mainWindow.buttons()["post.button.post"].tap();
    
// Wait for maximum of 30 seconds to "OKAY" button to be valid
target.pushTimeout(30);

// Tap the button which is shown from the network request success callback
mainWindow.buttons()["dialog.button.okay"].tap();

// End the wait scope
target.popTimeout();
lekksi
  • 4,868
  • 1
  • 16
  • 13