The Path from Appium to Kaspresso
Hi everyone!
My name is Sergei Dudarev. In this article, I would like to tell you about my journey from Appium to Kaspresso: where it all began, which discoveries I made along the way, how my stereotypes were shattered, and what conclusions I eventually reached.
How I came to choose Appium
When I switched to mobile testing, I was faced with the decision of which automation tool I should use. I had to choose between native tools (Espresso, Kaspresso) and Appium.
There was very little available information about Kaspresso at that time. Even in the vast expanses of the internet, there was just a README.md on GitHub and a few articles that failed to provide enough information to understand all of its capabilities.
I was left with a choice between Espresso and Appium.
The latter was more popular among my colleagues from adjacent teams.
After talking with my colleagues about why they specifically chose this tool, and after reading a few articles that compared Appium and Espresso, I picked out the following advantages of Appium:
- Appium has a smoother learning curve compared to other native tools. This appears to be a pretty good advantage in that manual testers without experience writing code will have an easier time writing their first test, which will immediately bring results and consequently more interest in automation. I’ve met more than a few manual testers who lost interest in automation because they were unable to get their bearings in a complex project and write their first test. I also met some testers who began to write automated tests in projects with a well-planned architecture. They wrote their first tests as a sort of designer kit consisting of ready-made steps, after which their interest grew and they delved deeper and deeper into automation, eventually even working with a test automator. Therefore, the smoother the learning curve, the better.
- Appium lets us interact with third-party applications.
Espresso does not have this capability. Although Android does have a separate tool called UiAutomator for this purpose, it would be better to have a similar API for working with your own application as well as with third-party apps.
Therefore, this advantage was crucial for me because the specific characteristics of my project entail a multitude of interactions with third-party apps as well as with the Android system. - In contrast to native tools, Appium lets you write a single test for two different platforms (Android and iOS). Another solid argument in favor of Appium is that it seems to help us handle two tasks with a single tool.
After carefully weighing all of the pros and cons, I chose a stack of python + pytest + appium.
Experimentation period
For a period of approximately six months, I used this stack to automate tests and everything went fairly well. However, I started getting more and more interested in Kaspresso.
This interest was sparked by more and more new information about Kaspresso, positive feedback, and a new tutorial that provided a step-by-step explanation of the capabilities of the framework.
At that time, I still had no idea just how much it would suit me and fit the specific attributes of my project.
I decided to write a few tests in Kaspresso as a sort of optional variant without negatively affecting the automation of my project.
How my former stereotypes were shattered
After I grabbed a link to the Kaspresso tutorial from my colleagues, I became familiar with it while actually implementing Kaspresso in my own project.
As it turned out, this was not difficult at all. All I had to do was add a few dependencies and create a package with the tests. This is described in detail in the integration section.
It was also fairly easy to write the first test thanks to the intuitive and concise Kotlin DSL. If we look at the code of the test, we can immediately see that it clicks the Continue button on the WizardAgreements screen, and then we make sure that the Continue button is visible on the permissions prompt screen:
While I was writing my first test, it was at this moment that my first stereotype regarding the learning curve was shattered. I had been certain that I could only write a native test after immersing myself in Kotlin (which I practically knew nothing about) and doing a deep dive into the structure of the app being tested. This all turned out to be untrue. In reality, it is no more difficult to begin writing autotests in Kaspresso than it is in Appium. In fact, it turned out to be even simpler for me. You can see this for yourself by completing the lessons in the Kaspresso tutorial.
When it came to interaction with third-party applications, my second stereotype was shattered.
I had thought that native tools were not appropriate for these tasks. As it turned out, this was only true for Espresso. If you want to run tests using Espresso, it is recommended to use another tool called UiAutomator for interaction with other apps. However, Kaspresso was actually created based on these two tools, and provides convenient and highly functional wrappers over them. This means that you do not need to use anything else, because this framework covers all of your needs. As a bonus, it also provides us with a unified style in our tests, whether interacting with our own app or with third-party apps.
Strictly speaking, Appium also uses UiAutomator as one of its options for interacting with apps.
I would also like to briefly discuss the capabilities for writing a single test for iOS and Android using Appium. On one hand, under certain conditions you can actually write a single test in one language that will run on the two platforms. On the other hand, in real life the two apps often have different UX and UI (due not only to the inconsistency in their design but also due to the OS differences) and different element locators. As a result, instead of unified code for the two platforms, we end up with many ifs in the test code to distinguish the logic for the different platforms and therefore the test becomes cumbersome and inconvenient to debug. In my opinion, it’s not a good idea to limit ourselves to one programming language to accomplish different tasks. Instead, we should use the particular language that is suitable for the specific task instead of the language that we know better. Of course, there may be exceptions to this bold statement of mine. For example, some experiments need to be conducted quickly. However, I think the gist here is clear.
It gets even better
The deeper I delved into studying the capabilities of Kaspresso, the more I appreciated it.
The first thing I’d like to mention is its well-thought-out test architecture, which is based on the page object pattern. When writing tests, you do not need to meticulously think through the architectural framework for tests. Instead, you just follow the concept inherent in Kaspresso.
As for the next advantage, out-of-the-box Kaspresso provides what I previously had to think through and implement myself in my project when using Appium.
For example:
- adb.
To interact with the adb server in my project when using Appium, I had to write my own implementation that executed adb commands through the Python subprocess library.
In Kaspresso, all you have to do is query the adbServer interface, call the performShell method that executes shell commands in adb (you do not need to write the full command; all you have to do is write everything that comes after shell), and pass the command that you want to execute to the method:
As a response, we receive the execution result of this command.
In addition, adbServer has the performAdb method that executes adb commands (we pass everything that comes after adb in the command to this method), and performCmd, which executes command-line commands on the host from which the tests are run.
By the way, Espresso doesn’t even have the capability to interact with adb.
2. Adb command wrappers.
Ready-to-use adb command wrappers save time that would otherwise be spent searching for info on how the commands are formulated, and they save you from having to implement the methods that execute these adb commands in your own project.
For example, to disable the internet on a device, all you have to do is call
There is no need to learn and individually execute the “adb shell svc wifi disable” and “adb shell svc data disable” commands.
Aside from that, the Devices class has a large set of methods for interaction with the Android OS. For example, you can emulate incoming calls and text messages, install and remove apps, and change the language. To learn about all the capabilities of the Devices class, click here.
3. Autoscroll.
Kaspresso lets you scroll to an element that you plan to interact with. This mechanism saves you from worrying about how the element may fail to display properly on some screens. If necessary, Kaspresso will scroll to the element on its own.
This adds stability to tests and lets you write them faster because in this case there is no need to implement a scroll method in your own project and then figure out where to add its call before you click on it, for example.
4. Working with permissions.
There are a few options for granting permissions supported by Kaspresso. The first option is to grant them automatically during app installation. The second option is to employ a user scenario via the UI. Here I would like to emphasize the second option. When using Appium, if we are tasked with testing a request and applying a permission, we need to find an appropriate locator for it and write the method that will search for it on the page and accept it.
When using Kaspresso, all we need to do is call the already existing method that checks for the dialog window and the example permission if available
5. Screenshots.
Our app must support a multitude of localizations, therefore we must view how the app screen appears in different languages. To help us accomplish this task and also conduct a design review, Kaspresso provides the latest ready-to-use solution out of the box.
Just look at how little code you have to write to capture screenshots from the app screen in 12 languages and save them in the folder sdcard/Documents/screenshots/
There are two options for capturing screenshots. The first option is to go through the entire user scenario until you reach the necessary screen. The second option lets you avoid running the entire app and instead run only individual fragments, thereby providing a more stable and quicker way to capture screenshots. For more details, click here.
In addition to the screenshots, the XML files will be saved with all strings on the screen and their IDs.
6. Working with logcat.
There are some tests in which there is insufficient interaction with the UI, or part of the logic may be hidden from the user. In that case, we need to work with logs via logcat to make sure that our app is handling things like we expect.
Once again, Kaspresso also provides us with a ready-to-use solution for this purpose. To find a relevant string in a log, all you need is the following:
7. Steps
Kaspresso provides a mechanism that lets you make autotests more readable thanks to the capability to allocate chunks of code into separate blocks that correspond to individual test cases, and adds logging and screenshots to tests. For more details about the steps, click here.
8. Protection against flakiness
Although I already mentioned autoscroll earlier, this is not the only thing that Kaspresso offers to improve the stability of tests. For example, Kaspresso can also close system windows and wait for asynchronous elements to load, and you can easily and flexibly configure all this on your own.
This all helps save many hours that you would otherwise spend searching for and implementing the necessary functionality. I used to have to repeatedly re-invent a new wheel to do all this before, when I could’ve instead spent all that time writing new autotests.
I would also like to briefly mention a possibly not-so-obvious advantage of native tools, which is that the tests are located in the same project as the app being tested. This expands our capabilities by letting us conduct white box testing of our app, thereby adding stability to tests and extending our possibilities.
Conclusion
To sum up my own personal conclusions, I think Kaspresso is a framework that can be used by anyone to begin writing autotests for Android apps because its learning curve is fairly smooth. My stereotypes regarding native automation tools were shattered because most of them only pertained to Espresso. Kaspresso can cover all your needs for testing Android apps.
If we compare Kaspresso with Appium, the capabilities of Kaspresso are not just on par with Appium but in many ways are even superior to Appium.
If you found this article useful, or if you’re planning to use Kaspresso in your projects, please consider supporting us by starring our Github project and joining our community on Telegram. We hope to see you among our contributors!
Furthermore, we welcome you to read our previous publications about autotests on Android:
Native, simple and fast screenshot tests with Kaspresso
UI tests on Android. How do we test an app that requires permissions?