Write tests. Not too many. Mostly integration.
— Guillermo ▲ (@rauchg) December 10, 2016
Whatever your approach to tests is - testing pyramid1 or testing trophy2 - you know that you need to write integration tests. In this post I’m going to show how to setup integration tests for React Native project.
Step 1 - install react-component-driver
This library simplifies your test by offering functions for commonly used functionality. It uses react-test-renderer which allows to run your app code on Node.js. It is possible to write tests using just react-test-renderer, however creating a driver for each screen makes your test code more readable and requires less changes when product changes.
Step 2 - configure jest
React Native components sometimes require platform-specific counterparts to function correctly. Since our tests run in Node, instantiating those is tricky. The solution is to replace these components in tests with ones that feature just enough behavior to allow testing. For our example test we’ll need to mock TouchableOpacity and Switch components. We need to tell jest where to look for mocks setup file. This way mocked versions of components are available in each test suite.
|
|
This setup file just sets up mocks for the components that are used in example app. It’s a good place to also setup async-storage mocking and other mocks you might commonly need for tests.
|
|
Step 3 - write a test case
Let’s create a simple app screen for us to test.
|
|
Now we’ll instantiate this component in our test using a component driver and write a test to toggle a checkbox and to press a submit button.
|
|
Notice how using the driver allows us to focus on what actions are being performed, while the details of how they are performed are delegated to the driver.
Finally, two more tips for writing better integration tests:
Use mocking sparingly. Our team at Wix Mobile App had some test cases where Redux selectors were being mocked - when the state shape changed, tests for that screen were still “green”, while the app was crashing when opened on device. It’s good to use test doubles for network, disk, etc. Avoid using mocks for code that’s a part of your project.
Avoid component snapshot testing. Comparing snapshots can be useful when writing unit tests, but in integration tests they will be a source of flakiness. Simply check for presence/absence of components with specific testIDs and whether correct API calls were made. This will give you the freedom to refactor with confidence.
The source code for this article is available here.
Thanks to Morad Stern, Roman Kolgushev, Guy Manzuruola, and Ran Greenberg for reviews and suggestions.
- Good arguments for testing pyramid approach [return]
- Good arguments for testing trophy approach [return]