0

I have UI XCTestCases (XCUITests) that perform some gestures. Our performance tests need to be able to call startMeasuring and stopMeasuring depending on the state of the app.

We have methods in our app code that return a BOOL value depending on whether it has completed rendering everything and I need to read that value.

How can I call those methods in our app?

Teresa Peters
  • 229
  • 3
  • 14

1 Answers1

1

Short version: You shouldn't, but I guess you could try signal passing.

Longer version: A major (though perhaps philosophical) point of UI Tests is that they only evaluate that which is passed to the user, or at least to the user-visible View / Accessibility Hierarchies. Using signal passing or some other method to side-channel information is not supported and is against the aesthetic of the test framework.

Instead, you could evaluate whether or not everything has finished rendering by waiting for a .Hittable predicate on the particular UI elements; or if you have elements that only become interactable once the page has finished loading (a common pattern) you could wait for those to change state.

There are a number of different ways to go about this, but the "right" answer is to find some way that's user-visible that you can evaluate.

... alternatively, have a non-visible UI element in the View Hierarchy that changes state based on the Boolean in question, if you want something that just works and don't care about philosophy.

Aaron Sofaer
  • 706
  • 4
  • 19
  • Ah, I knew I should've left more context. I do know the right way is to wait for some elements and the states exposed by XCUIElement. If I had a simple app, I totally would. However, let's pretend I have an app that displays dynamic content such as a variable amount of newspaper stories from a service, and those stories are stored in a collection. That collection doesn't know when its stories have finished loading, because it doesn't care. – Teresa Peters Sep 26 '16 at 19:56
  • For our UI Automation with Calabash (3rd party automation solution), we exposed a method on our view's controller which we can call by asking the view for its delegate and then from there we can call any public method on that class. So, I'm basically trying to do something similar with XCTest. – Teresa Peters Sep 26 '16 at 19:56
  • Now, for message passing, I did try performSelector, but did not get anywhere with that. Do you have an example of that working? To further complicate things, I've written the UI Tests in Swift but our app code is in Objective C, so maybe I just missed something in the chaos. – Teresa Peters Sep 26 '16 at 19:57
  • One more thing to note, the team defines "finished loading" as more than just hittable. It's also that each image has loaded, html content, etc. – Teresa Peters Sep 26 '16 at 20:02
  • I got signal passing working once about a year ago, haven't touched it since, don't remember the details. WRT the thrust of your question: are there any placeholder UI elements or "this is still loading" communications to the user? If so, voila, you have the element on whose basis you can make your queries. I use things like the disappearance of a progress indicator or the hittability of a button that's not hittable until everything is done loading. – Aaron Sofaer Sep 26 '16 at 20:43
  • No, there aren't unfortunately. I'm not able to make functionality changes to our code. I just have limitations to work around. – Teresa Peters Sep 26 '16 at 20:49
  • That sounds like an unfortunate dysfunction within your workplace, if you can't even express the state of the boolean through an accessibilityIdentifier changing. Maybe if you include the app as a target, you can figure out a way to access its internals... – Aaron Sofaer Sep 26 '16 at 21:08
  • I've been trying various things since I posted this without much progress. Is there any chance you can take another look at that signal passing code? I've tried adding UI tests to the Unit Test target using the environment variables mentioned here: https://twitter.com/punksomething/status/609505357132500993. No luck. I've also tried adding references to our app code's .h files in the test code bridging header. – Teresa Peters Oct 18 '16 at 06:28
  • The best I can offer is that my notes say that "I built a signal passing solution off of this link: http://stackoverflow.com/questions/39763687/passing-custom-objects-between-two-ios-apps but it would have required more work on the app code" (the next clause is "so I used a sleep instead", I still feel bad about that sleep). A different note says there were three ways I looked at; write data to shared storage, push notifications, and URL query strings. My apologies for my general unhelpfulness; I abandoned this line of investigation rapidly, long ago. – Aaron Sofaer Oct 18 '16 at 22:17