Categories:
Loading... Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?
React Native testing with Appium. Learn about Appium mobile testing

Appium mobile testing – test React Native apps

Mar 7, 2021

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.

React Native Testing with Appium and Detox
React Native Testing with Appium and Detox

For testing your mobile apps on real devices you can use AWS Device Farm, Firebase Test Lab, BrowserStack and Sauce Labs.


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).

How did you like this article?

Oops, your feedback wasn't sent

Latest articles

Show more posts