Idea of UI tests
Many companies around the world employ manual testing for applications and they have their reasons. The advantages are multiplicitous, including a personal contact, understanding of the priorities, and inquisitiveness.
What’s more, UI tests in a long-term project may improve some aspects of QA which testers are struggling with.
I have listed some more or less common problems with manual testing:
- Doing it repetitively is tedious and boring
- Vulnerable to human’s misunderstanding and oversight
- Test cases are not portable
- It isn’t documenting itself
- Requires many different devices with many different OS versions
Manual testing is great, especially when you want to publish your digital product quickly. After that, most crucial screens of your app should be tested from code in order to avoid regression and omission.
Possibilities on Android platform
Nowadays, Android is a mature platform with many developed solutions. There are a lot of tools for UI testing, too: Espresso, ActivityScenario, Kakao, Kaspresso, Robolectric, Barista, Spoon, Robotium, Firebase Test Lab. But which should I choose?
The right library should allow us to write tests that are:
- Understandable for both developers and testers
- Following step by step principle
- Focused to check only important parts
It turns out that Kaspresso takes advantage of Kotlin and fulfills our requirements with some extra features. Let’s find out what it really can do for us!
Kaspresso is a Kaspersky’s library built on top of the Kakao. Thanks to its Kotlin DSL nature and Page Object Pattern, code has context and is pretty readable.
Official repository is stored at Github.
Code that tells the truth
In a sample app I have created a simple test case in which clicking on the button changes the text on the screen. Pretty basic example, but it will show how clean is the syntax of Kaspresso.
And the test code is as simple as the action. No more verbose code that could be unobvious for most of the testers. Now, once written code is a documentation of the screen for every person in the project.
This is especially useful when the screen has many hidden actions and testers are not always able to reproduce all the test paths.
Step by step
Sometimes there is a situation when the final result depends on the actions being taken before.
Given that case, it would be awesome to describe larger tests in self-explanatory blocks. Of course, Kaspresso has a great step() function for that.
Moreover, this library simplifies the configuration before and after the given test. It is also worth mentioning that created steps will be logically printed in the console which increases the control over running tasks.
Additionally, you can exclude any repetitive fragment of test in the simple scenario. This is accomplished by overriding the Scenario abstract class. In the example above I have extracted buttons visibility checking.
Work with Custom View
Next big advantage is that you can easily create your own view assertions, for example your custom view with an uncommon result.
This screen shows its own implementation of a rotating image view. Unfortunately Espresso is a base for the Kakao and therefore Kaspresso doesn’t have an assertion for a rotated view. A workaround for that is to extend BaseAssertion interface.
Creating assertions vastly improves the readability of the tests and allows encapsulating more complicated checks into the dedicated interfaces. Afterwards it can be almost self-describing.
Under the hood
In the code samples I have used a Screen object. This object is the lowest layer of Kaspresso abstraction. In the end we need to use Espresso to point out which view should be referenced to.
In the code above only withId() is the Espresso view’s pointer. This pattern is really handy as it just describes the screen. No Activity, no Fragment, no Dialog, it is not important for a test and a tester what type of class a developer has used.
As the Screen object doesn’t have to correspond to a single physical window, you can encapsulate any parts of your view into single files. Creating logical configurations may be also quite helpful, for example HomeScreenWithPremium or HomeScreenBasic.
Having a strong code base of UI tests is a big advantage. You can upload your scenarios into the Firebase Test Cloud or run them on the physical machine any time. This may happen when your testers are busy or you want to restrain regression.
You can achieve most of the syntax just with the Kakao library, but I had a reason to present Kaspresso. It does many other things that I didn’t mention:
- Advanced interception of test actions
- Clean and readable logging
- Ability to call ADB commands
- Perfect integration with Kautomator
With tools like that, writing UI tests is so clean that I believe it’s an added value for both developers and testers.
If you are looking for full code, check our repository with usage of ActivityScenario, Kakao and Kaspresso.