React Native provides a cross-platform mobile app development experience without sacrificing the user experience or perceived performance. Developers love to build apps with a single codebase and methodology. Appium is an open-source testing automation framework for cross-platform applications and mobile applications. When it comes to UI testing, Appium is a great option for testing React Native apps. React Native apps are testable out of the box with Appium – perfect for mobile testing.
Let’s learn how Appium can be used for React Native testing.
Written by Sneh Pandya
Set up a new project
To begin, create a new project for React Native using the command below:
react-native init ReactNativeAppiumTest
Now, install Appium through npm or as a standalone app.
npm install -g appium
The standalone version can be downloaded from here.
Next, create a separate directory to write test cases. Ideally, it should be inside the project’s root folder to keep everything in place. Inside the tests
folder, create a package.json
file.
WebdriverIO is an open-source testing utility for NodeJS
that supports Appium.
To install WebdriverIO, run the command below:
npm install --save webdriverio @wdio/cli
Next, install ChaiJS as shown below to include support for assertion statements while writing test cases:
npm install --save chai
Configure WebdriverIO
The web driver config file needs to be generated to apply the configuration while testing. Run the command below inside the project:
npx wdio config
In return, the command prompt will ask a series of questions and install the required dependencies based on the input selections.
Note: You need to select both the Mocha and Appium services when configuring via the command line.
Once this is done, the wdio.conf
file will be generated inside the tests
directory.
Perform the following changes to configure WebdriverIO to work with Appium and run tests on Android Emulator:
exports.config = {
services: ['appium'],
port: 4723,
runner: 'local',
specs: [
'./tests/specs/**/*.js'
],
capabilities: [{
maxInstances: 1,
browserName: '',
appiumVersion: '1.13.0',
platformName: 'Android',
platformVersion: '<emulator platform version>',
deviceName: '<emulator name>',
app: '<path to APK>',
automationName: 'UiAutomator2'
}],
logLevel: 'trace',
bail: 0,
waitforTimeout: 10000,
connectionRetryTimeout: 90000,
connectionRetryCount: 3,
framework: 'mocha',
reporters: ['spec'],
mochaOpts: {
ui: 'bdd'
timeout: 60000
}
}
In this file, Appium is added to the service list, and the default port for communication is also set. Declare the APK path, Android emulator name and version to complete the configuration. Also, maxInstances
is set to 1 to avoid running multiple tests in parallel.
Preparing demo application
Let’s prepare a simple application for the purpose of React Native testing using Appium. In our case, we will add a simple login page to run tests using Appium. Inside the App.js
file, add the code below:
import React, { Component } from 'react';
import { TouchableHighlight, StyleSheet, Text, TextInput, View } from 'react-native';
export default class App extends Component {
constructor() {
super()
this.state = {
username: '',
password: '',
isLogined: false
}
}
inputChangeHandler = (value, name) => {
this.setState({
[name]: value
})
}
login = () => {
if ((this.state.username == 'codemagic') && (this.state.password == 'nevercode')) {
this.setState({ isLogined: true });
}
else {
this.setState({ isLogined: false });
}
}
render() {
return (
<View style={LOCAL_STYLES.wrapper} testID="app-root" accessibilityLabel="app-root">
<View style={LOCAL_STYLES.inputContainer}>
<TextInput name="username" accessibilityLabel="username" style={LOCAL_STYLES.input} onChangeText={(text) => this.inputChangeHandler(text, "username")} />
</View>
<View style={LOCAL_STYLES.inputContainer}>
<TextInput name="password" accessibilityLabel="password" secureTextEntry={true} style={LOCAL_STYLES.input} onChangeText={(text) => this.inputChangeHandler(text, "password")} />
</View>
<Text accessibilityLabel="loginstatus">{this.state.isLogined ? "success" : "fail"}</Text>
<TouchableHighlight style={LOCAL_STYLES.buttonContainer} accessibilityLabel="login" onPress={this.login}>
<Text style={{ color: 'white' }}>Login</Text>
</TouchableHighlight>
</View>
);
}
}
const LOCAL_STYLES = StyleSheet.create({
wrapper: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
inputContainer: {
borderBottomColor: '#AFAFAF',
backgroundColor: '#FFFFFF',
borderRadius: 10,
borderBottomWidth: 1,
marginBottom: 16,
flexDirection: 'row',
alignItems: 'center',
width: '80%',
borderColor: 'blue',
borderWidth: 1
},
buttonContainer: {
height: 45,
width: 250,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 20,
borderRadius: 20,
backgroundColor: "#00b5ec"
}
});
To make the components testable, add a property to the relevant components. For Android, add accessibilityLabel
, and for iOS, add testID
, as shown in the code above.
Now run the app and check the screen. A simple login screen should open up. Next, let’s write test cases using Appium to verify our login functionality.
Preparing the test case
Inside the tests
directory, create a new file named App.test.js
, and add the code below:
var expect = require('chai').expect;
describe('Simple App testing', () => {
beforeEach(() => {
$("~app-root").waitForDisplayed(10000, false)
});
it('Login test: valid case', async => {
$('~username').setValue("codemagic");
$('~password').setValue("nevercode");
$("~login").click();
$("~loginstatus").waitForDisplayed(11000);
const status = $("~loginstatus").getText();
expect(status).to.equal('success');
});
it('Login test: invalid case', async => {
$('~username').setValue("nevercode");
$('~password').setValue("codemagic");
$("~login").click();
$("~loginstatus").waitForDisplayed(11000);
const status = $("~loginstatus").getText();
expect(status).to.equal('fail');
});
});
The above test case will verify the login functionality and check whether the test passes or fails based on the input credentials. beforeEach
is added to make sure the app is load prior to the test being run.
Execute tests
To execute the test case written above, let’s launch an emulator with the command below:
react-native run-android
Now, let’s start the Appium server in a separate command prompt to set up communication:
appium
In a new command prompt, run the webdriver test suite using the command below:
npx wdio ./wdio.conf.js
Once set up, the test execution will start, and the command prompt will show the logs of the executed steps in parallel when the emulator shows the test running.
Once the automation process is complete, you will see the test results as follows:
App testing
✓ Login test: valid case
✓ Login test: invalid case
2 tests passing (10.1s)
Conclusion
It is popular in the developer ecosystem to use Appium to test React Native apps. Appium makes it seamless to write test cases for both Android and iOS platforms while working with React Native. Selenium, the underlying web driver, works as a bridge between Appium and mobile platforms to deploy and execute tests.
Assure the quality of your app with automated tests for React Native
Codemagic mobile CI/CD makes it easy to automate the testing of your React Native apps. You can choose to run tests on the emulator or simulator or on real devices. Set up automatic build triggering to test every new commit.
Assure the quality of your React Native apps with automated tests. Run unit tests with Jest or test the full app on the simulator/emulator or real devices with Appium or Detox.
For testing your mobile apps on real devices you can use AWS Device Farm, Firebase Test Lab, BrowserStack and Sauce Labs.
Was this article useful? 🤔 Let us know HERE.
Useful links and resources
Here’s an article on why Android developers should pay attention to React Native in 2021.
Here’s an article on running React Native Detox tests on Codemagic.
Here’s an article on React Native testing with Jest and Codemagic.
Here’s an article on choosing the right database for your React Native app.
Here’s an article on how to improve the performance of a React Native app.
Learn about the options how to use CI/CD tool for testing mobile apps
Here’s a practical guide on Continuous Integration and Delivery for React Native apps.
For discussions, learning and support, join the Codemagic Slack community.
Sneh is a Senior Product Manager based in Baroda. He is a community organizer at Google Developers Group and co-host of NinjaTalks podcast. His passion for building meaningful products inspires him to write blogs, speak at conferences and mentor different talents. You can reach out to him over Twitter (@SnehPandya18) or via email (sneh.pandya1@gmail.com).