End-to-End React Native Testing
By Mohit Joshi, Community Contributor - February 3, 2023
Mobile apps have become an integral part of our daily life. Globally, apps influence the fate of several businesses. With the help of React Native, it has also become easier to create Android and iOS apps. The React Native testing framework allows you to build web, Android, and iOS apps with the same codebase using ReactJs. Testing is a process for identifying the bugs in the UI of an application after it has undergone development. This article helps you understand how to perform end-to-end testing of React Native apps.
End-to-End Testing with React Native
When the react-native apps reach the testing stage, it becomes essential to check everything thoroughly to solve any problem before launching it out to users. End-to-end testing is done to test all system components under real user conditions readily. There are two types of end-to-end testing – vertical and horizontal.
In vertical testing, tests are performed in sequential order and used in testing complex computing systems. However, in horizontal testing, testing is done from the user’s perspective, assuring the user can easily navigate the system.
Every single component, whether big or small, is brought together to build an application. Therefore it becomes necessary to understand the composition of React Native apps and how testing can be performed on different layers of an application. Here are the types of testing that you can perform on React Native apps.
- Unit Testing for React Native Apps: Unit testing allows you to test individual parts of your code, like functions, classes, elements, or objects. Unit tests are quick to write and can be executed handily. The frameworks equipped for performing unit tests generally are Jasmine, Enzyme, Jest, and Mocha.
- Integration Testing for React Native apps: Integration testing checks if the elements work as planned with the other elements. It checks the cooperation among individual units within our application.
- Component Testing for React Native apps: In component testing, you test whether the app interacts with the users as planned. For example, when a button is clicked, does it perform the required action? Also, it assures whether a component is rightly placed in UI and has an appearance as specified by the developer. If either of the cases is not working, you will deliver a broken UI to the users.
Performing E2E testing of React Native apps using Detox
Prerequisites
- Install the latest version of Node.js in your system because you will install several packages throughout the tutorial.
- Install any IDE of your choice.
- Create an emulator to run your applications.
- Install the latest version of homebrew and Xcode on your system if you are using macOS.
- Install the latest version of Java and also set up environment variables.
- To test React Native Android applications, you should also install Android SDK and Android studio.
Step 1: Setting up Project and configuring it for iOS and Android
For iOS
It is important to note that you need to have macOS to perform testing of iOS applications.
- Initialize a React Native application with the help of the following command.
npx react-native init MyApp
- Install the latest version of Homebrew.
xcode-select -install
- Install detox dependency and applesimutills with the help of the following command.
brew tap wix/brew; brew install applesimutils;
- Install Detox command line interface tool globally on your system.
npm install -g detox-cli
- Navigate to your application’s folder. Here, install Detox by following the below command.
yarn add detox -D
- Also, install Mocha to use it as a test runner.
npm install --save-dev mocha
- After installing Mocha.js, follow the below command to create the necessary files in your project folder.
detox init -r mocha
It will create a new folder “e2e” in your project containing some configuration files and an example test file.
For Android
Setting up iOS takes only a few steps; however, configuring for Android is a bit complex.
- Set up Java on your machine. To check for your Java Version.
java --version
- Next, you have to install Android SDK on your machine; however, if you have Android Studio installed on your machine, Android SDK is installed automatically, whereas you can also install SDK alone. Also, set up SDK’s root directory path into environment variables ANDROID_SDK_ROOT and ANDROID_HOME.
set ANDROID_HOME
Or
echo $ANDROID_HOME
- Now create an Android Emulator with the help of Android Studio’s SDK manager and also install the system image for the same. Open Virtual Device manager in Android Studio to list all your installed emulators. Launch the emulator with the following command.
Run emulator -list-avds to get the name of your emulator
emulator -avd @name-of-your-emulator
- To use detox for React Native Android application, you must have a minimum minSdkVersion of 18. Update minSdkVersion follow this command.
minSdkVersion = 18
Now, open android/build.gradle file. In this file, add the following script inside repositories.
maven { url "$rootDir/../node_modules/detox/Detox-android" }
On the same file, add the support for Kotlin as follows.
buildscript { // ... ext.kotlinVersion = '1.7.10' // (check what the latest version is!) dependencies { // ... classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } }
- Navigate into android/app/build.gradle file, add the following configuration inside the dependencies.
dependencies { androidTestImplementation('com.wix:detox:+') }
In the same file and add the following configuration inside android.defaultConfig
android { defaultConfig { testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' } }
- The next step is to create a new file DetoxTest.java in the path android/app/src/androidTest/java/com/myapp/.
Once the file is created add the following script to the file. It would be best if you replaced “com.myapp” with your app’s package name.
package s import com.wix.detox.Detox; import com.wix.detox.config.DetoxConfig; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.LargeTest; import androidx.test.rule.ActivityTestRule; @RunWith(AndroidJUnit4.class) @LargeTest public class DetoxTest { @Rule public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false); @Test public void runDetoxTests() { // TestButlerProbe.assertReadyIfInstalled(); DetoxConfig detoxConfig = new DetoxConfig(); detoxConfig.idlePolicyConfig.masterTimeoutSec = 90; detoxConfig.idlePolicyConfig.idleResourceTimeoutSec = 60; detoxConfig.rnContextLoadTimeoutSec = (com.myapp.BuildConfig.DEBUG ? 180 : 60); Detox.runTests(mActivityRule, detoxConfig); } }
Step 2: Setup .detoxrc.json file
This is the required .detoxrc.json file for the entire setup. However, it also contains information about the simulators that I am using, which will vary according to your own simulators
import React, {useState} from 'react'; import {Button, TextInput, View, Text, SafeAreaView, Alert} from 'react-native'; const App = () => { const [input, setInput] = useState(''); return ( <SafeAreaView style={{flex: 1}}> <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text testID="title" style={{fontSize: 22, textAlign: 'center'}}> BrowserStack Demo </Text> <TextInput testID="input" placeholder="Write Anything here" value={input} onChangeText={setInput} style={{padding: 25}} /> <Button testID="button" title="Enter" onPress={() => Alert.alert(input)} /> </View> </SafeAreaView> ); }; export default App;
Step 4: Creating Test Script
Navigate to the e2e folder and open the firstTest.spec.js file.
describe('Example', () => { before(async () => { await device.launchApp(); }); beforeEach(async () => { await device.reloadReactNative(); }); it('Should have BrowserStack Demo written', async () => { await expect(element(by.id('title'))).toBeVisible(); }); const typedText = 'Browserstack'; it('Should type Browserstack', async () => { const input = element(by.id('input')); await input.typeText(typedText); }); it('Should press on the submit button', async () => { await element(by.id('button')).tap(); }); it('should have a alert', async () => { await expect(element(by.text(typedText)).atIndex(0)).toBeVisible(); await element(by.text('OK')).tap(); }); });
Step 5: Executing Test Script
Start the emulator for Android and iOS and then execute the tests.
- For Android:
Build the Android app following the command.
detox build -c android
Start the test
detox test -c android
- For iOS:
Build the iOS app following the command.
detox build -c ios
Start the test
detox test -c ios
Emulators or simulators are better suited to test the React Native apps in the initial phases of development. That said, they are not reliable when it comes to checking for accuracy and compatibility. Adopting a real device cloud like BrowserStack for app testing is a feasible method that eliminates the burden of setting up test infrastructure for teams. It eliminates the overhead of maintaining the device labs. This way team can focus purely on testing and delivery of robust apps.