In the following article, I would like to share everything I learned about the tool. In particular, I will focus on describing how detox works, how to configure it, how to write tests and how to make them easily readable and maintainable.
Detox is a gray-box end-to-end testing and automation library for mobile apps (specifically dedicated for apps written in React Native). It’s important to underline and highlight that detox is a gray-box, not black-box, which means:
Detox uses native gray-box drivers developed by Google — EarlGrey for iOS and Espresso for Android. These frameworks synchronize with the application and interact with the application only when it’s idle.
It appears to be quite easy to start writing tests in Detox. Nevertheless, you need to make sure you have all required dependencies installed:
After that, you can install detox using npm. In the next step, in a package.json file, you need to add configurations you are going to run your tests on. In my case, there are two configurations: dev (called ios.sim.dev) and test (ios.sim.test), which represent the environment the app is launched on. We use 3 different environments in the project, 2 of which are used in the development:
You can open a terminal now, go to the folder with project repository cloned and type ‘detox init -r mocha’ (if you prefer mocha) or ‘detox init -r jest’ (if you prefer jest). It automatically creates:
If you have followed the above suggestions, it seems you are ready to write tests for your application. However, I would recommend you to spend some time beforehand in order to identify test cases you would like to be automated (it is good to verify the ones which will not be automated, as well as keep them documented). It will assure you that all the critical paths of the application are covered and finally your tests bring the biggest value. Writing tests flow is very simple. Once you have scenarios to be implemented, you can identify elements (in React Native components are usually elements that are used) which will be used in your test. Use a proper matcher to match the element, perform an action on that element or on a group of elements and set expectation — the expected result of your test.
Detox gives us a lot of options to interact with the elements specific for a mobile application, like multi-touch, swipe and others. It also gives us an opportunity to interact with the device by using a device object. Thanks to that, we can, for example, launch the app with certain parameters (e.g. grant access to the camera), reload the app, terminate the app, etc.
During work on my test project, I was writing tests keeping in mind the following rules:
As mentioned above, I recommend keeping all locators in one place. It is easier to maintain the code and to write the tests when you group locators for particular screens. Being inspired by Page Object Pattern from web applications testing, I implemented some kind of Screen Object Pattern and stored all locators in one file. For each screen, I created a separate dictionary with the same name as the screen.
It not only helped me to write the tests but also helped other people to understand what is being actually tested.
Tests can be run locally or on the CI server. Before executing the tests you need to build the application using ‘detox build’ method or just use binary already built in the build process on the CI server. After that, you can run all the tests using ‘detox test’ method with parameters. There you can specify what configuration tests should be run on.
Even if tests written in detox are stable and reliable, some of them may fail without obvious reason. Detox and React Native give us a few options to narrow down the problem and to fix failing tests quickly and easily:
Detox has started a new era in testing mobile applications — the era of gray-box testing. The one where we do not need to worry about delays, freezes or any other unexpected behaviours occurring quite often when using mobile apps. Thanks to that, we can avoid tests flakiness and make our test more reliable, stable and trustworthy. Configuration is less complex than in case of any other mobile TA framework, thus it makes automated testing a lot of easier and, what is very important, it leverages cooperation between testers and developers.