Testing. Testing. One. Two.
Oct 12, 2018
You want to test do UI testing but you also want your code to be clean and human readable. I wanted to see how using protocols would help with this. With the release of iOS7 Apple introduces UITesting as a native part of the test suite. UITesting allows for interaction with the app in an automated way by leveraging the app’s accessibility features. You could record interactions and have them translated to code and have them repeat consistently. The downside to this is that the code becomes multi line references through the app’s UI that may not be clear for humans, may not be reusable, and there is little documentation of the API. There are third-party libraries that can be used like KIF, but that expands what you have to keep track of significantly. You could roll your own, but that could be a significant level of work. In iOS8, Apple introduced the Swift programming language and the concept of Protocol Oriented Programming. Protocol Oriented Programming is intended to give the developer a strongly-typed way to manage API contracts. Polymorphism without all of the weight of the super class. I am a fan of testing and of swift and wanted to see how PoP could help me with UITesting.
I wanted two major outcomes.
Describe the steps as actions done by the user. Describe state of the app separate from the user. The user behavior is composed of smaller steps. The steps are separated by the user waiting for state. This allows me to fine tune the testing behavior. I found that combining too many actions at once, I got inconsistent behavior from my UITests. Giving myself at least 5 seconds to wait for an app UI element to exist seemed appropriate.
Created two main protocols, user and app Create a protocol that exposes XCUIElement to the testing process as State predicate Convert XCUIElement paths to protocol variables. Expose only the elements necessary that aligns with the user actions to be executed. Create a wait function on the user so that it waits for state in the app. Work is naturally split between behavior and waiting for state. Assertions are tied to what the user is waiting on, existence of state. User behavior protocol
User behavior protocol implementation
The intent is to wrap the XCUIElement details into chunks of code that execute in-between waiting for app state. The person writing tests only worries about user behavior and app state.
Application protocol implementation
The application interface is excellent in that, I am exposing UI elements in a way that abstracts all the XCUIElement work away. The elements exposed are reusable across the test code. I am ultimately waiting for state on UI elements. Which, essentially is a predicate.
The intent here is that the user is only concerned about the existence of an element or elements. Searching and finding the element is abstracted away within the method body. Working the problem this way, I can share the protocol with the rest of the testing team for use and I can evolve the protocol based on additional user behaviors and UI elements. I found doing this helped guide my UITesting process. Find it useful? Let me know!