Why We Chose to Use Native UI Tests with a React Native App

I’ve been working on a React Native app for a few months now. The project is a particularly interesting one: take an existing web app and turn it into a mobile app. Given the nature of the project, there have been many decisions to make. One choice I didn’t expect to be hotly debated was which UI testing framework to use.

Originally, we decided to use Appium tests. Our app consisted mainly of a web view to display the web app, and Appium provided tools to interact with the web view context. We discovered pretty quickly that writing Appium tests for our specific test cases was time consuming and difficult. After many iterations of different ways to approach and work with Appium, we couldn’t take it anymore. That’s when we made the big switch to write native UI tests.

Writing native tests left us with fewer choices: simply use XCTest for iOS and Espresso for Android. Below are some considerations we took into account when making this decision.

Pro: Faster Test Writing

This was the biggest deciding factor for our UI testing. We had spent far too much time trying to get Appium tests to work, attempting to mold the tests to fit our very specific use case.

Since making the switch to native UI tests, our team has remarked many times how quickly we were able to crush through UI test writing.

Pro: Environments and Tools

One of the other issues we had with Appium tests was getting the right environment set up to run them. In our app’s case, this meant more than just pulling down the newest tests to run. We eventually had environment variables to set for whether or not we were running an Appium test, as well as specific behavior that only the tests would see. This included things like opening an OS-level alert instead of navigating to the browser when tapping an external link.

Not only did these environments have to be correct to successfully run the tests, but we ran into flakiness with our tests. This was especially true when running the tests on CircleCI. Because we couldn’t produce some of the failures locally, we had trouble determining the root of the problems.

Pro: Documentation

Because XCTest and Espresso are supported by Apple and Google respectively, there is much more documentation available.

Con: Writing Tests Twice

In order to fully UI test a React Native app, we need to be able to run tests on both iOS and Android. If we’re choosing to write native UI tests, this means that we need tests for both iOS and Android. Fortunately, the test cases should be shared between platforms. We would simply need to write the steps for reproducing them in the framework and language of choice.

However, if writing only one cross-platform test is taking longer than writing two native UI tests, this is no longer a drawback.

Con: Language Barriers

Many web developers have made the transition into mobile app development through React Native. Choosing to test with native frameworks means that if a developer is used to working strictly in JavaScript or TypeScript, bridging into Swift or Kotlin or Java can cause some pain points.

While the process of writing native UI tests for a React Native app may seem counterproductive, it made our team more effective in our testing. Is your team writing your own native UI tests? Let me know your process in the comments below!