Test Automation

Your app is looking great! Let’s add some test cases with Jest and Appium.

How do you make sure that future development doesn’t break something that’s working today? By integrating automated tests with tools like Jest and Appium. Jest is a JavaScript testing framework that is often used to do snapshot testing of React Native apps, whereas the Appium framework is used for the integration testing of React Native apps.

Jest

Let’s update your app to incorporate snapshot testing for the button component.

The output of youi-tv init includes the basic setup your application needs to work with Jest.

Add a Jest Test

Each test is defined in a JavaScript file located in your project’s __tests__ folder. Copy and paste the following test file into a new file called button-test.js in MyApp/__tests__.

import Button from "./../button.js";
import React from "react";
import renderer from "react-test-renderer";

test("renders correctly", () => {
  const tree = renderer.create(<Button />).toJSON();
  expect(tree).toMatchSnapshot();
});

Run the Jest Test

From your app’s top-level project folder (MyApp) run Jest with the command below.

yarn test

The terminal shows the progress of the test command:

yarn run v1.22.10
$ jest
PASS  __tests__/button-test.js (5.021s)
✓ renders correctly (3068ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        6.627s
Ran all test suites.
✨ Done in 12.66s.

Since this is the first time you’re running it, the test generated and saved a snapshot for your button test. You can find that file in __tests__/__snapshots__/button-test.js.snap. The next time you run Jest, a new snapshot will be generated and compared with the saved one.

By running this snapshot test between iterations of development, you can ensure that the structure of your Button component doesn’t change. To learn more, see Jest Snapshot Testing.

Great Job! Keep it Up With More Tests

For more information on adding Jest tests to your app, see Testing React Native Apps in the Jest docs.

Appium

You.i Platform has an Appium Driver that you can use with both simulators and real devices. Even if you’re not familiar with Appium, it’s easy to get going. Follow this section of the tutorial to try it out.

Install

The output of youi-tv init includes the basics your application needs to work with Appium, but you need to install the Appium framework. Start by installing Appium using the method of your choice from their installation guide.

Set Up Dependencies

Use node --version to verify that your installed Node.js version is supported. You.i Platform release 6.13 supports Node versions 12.10 to 12.x. For information on other third party tools, verify our complete list for your development platform.

With a valid Node version installed, use brew and node to install the required dependencies for the Appium project within your app.

cd MyApp/__tests__/appium
brew bundle
yarn

If the brew bundle command gives you errors, run brew upgrade to upgrade problem packages and clean up dependencies, and then repeat the commands above.

Configure

Customize the default value in the Appium configuration file with your application’s name and path. With your favorite editor, open MyApp/__tests__/appium/wdio.yimac.conf.js and change app: to point to your application.

Change the app line in this section:

// change the "app:" value below from this
exports.config = merge(wdioConf.config, {
   capabilities: [{
      app: '../../../../../allinone/osx/react/samples/ReactTemplateProject/youi/Release/MyApp',

To this:

// to this (which points to your app)
exports.config = merge(wdioConf.config, {
   capabilities: [{
      app: '../../youi/build/osx/Debug/MyApp',

Run the Default Tests

Now you’re ready to run the default Appium tests.

Open a new terminal window and start the Metro bundler for your application. Due to the changes we made earlier, we add an extra yarn step before yarn start to be sure yarn has everything it needs.

# in a new terminal window
cd MyApp
yarn
yarn start

Go to your original terminal window, and from the MyApp/__tests__/appium folder, execute the tests.

yarn yimac

The app opens! All by itself.

The tests run, then it closes again.

Review the Test Results

Look at the terminal you used to launch the Appium tests to see the results.

Screen capture of Appium tests running with a You.i React Native application

This default test confirmed that when your application runs, the You.i TV logo is present. It’s pretty boring as far as tests go, right? But if someone accidentally removed the logo section in index.youi.js, the tests would fail. Go ahead and try it!

Create New Test Cases

Based on the work we did in the Components section of this quick start guide, your app switches between light and dark modes when you click a button.

Let’s see how to exercise that button using Appium.

Since the button text changes depending on the value of this.state.lightTheme, we can create the following two test cases:

  • Test Case 1 - Before clicking the button, ensure that the button’s text says “Switch to the dark theme”.

  • Test Case 2 - After clicking the button, ensure that the button’s text says “Switch to the light theme”.

Understand the Existing Test

Before we get started with new tests, let’s take a look at the test we already ran. Open MyApp/__tests__/appium/test/specs/app.test.js in your favorite text editor. Notice the following:

context('when in App', () => {
  it('displays logo image', function() {
    // Wait until the screen is loaded and displayed.
    expect(AppScreen.react_image_node.getAttribute("isdisplayed")).to.be.true;
});

This is the default test case we ran above. Can you guess:

  • The pass/fail condition?
  • Which element is under test?

The pass/fail condition is that a particular element is displayed:

  • It uses the keywords expect and to.be.true,
  • the attribute checked is isdisplayed.

The element under test is the AppScreen.react_image_node. But what is that?

AppScreen.react_image_node is a user-defined method that returns the name of a scene tree element to test. In this case, it returns a value corresponding to the ImageView with the logo image.

In the next steps, you’ll see where to find those values and configure your tests to use them.

Install and Set Up Appium Desktop

For our two new proposed test cases, we need to verify the button text and click the button. But how do we know the name of the scene tree element that identifies the button we want to test? With Appium Desktop!

Start by downloading and installing Appium Desktop version 1.21, following the instructions on their website.

Once it’s installed, launch it and click Start Server to start the Appium server with the default settings (host 0.0.0.0 and port 4723).

Screen capture of Appium Desktop

Click the magnifying glass at the top-right corner of the window to start an Inspector session. Notice the area highlighted in red below (JSON Representation).

Screen capture of Appium Desktop in inspection mode

We need to provide a JSON schema for our app. The JSON schema is found in MyApp/__tests__/appium/wdio.yimac.conf.js. Open this file and copy the contents of the capabilities section into the JSON Representation in Appium Desktop.

capabilities: [{
  app: '../../youi/build/osx/Debug/MyApp',
  automationName: 'YouiEngine',
  deviceName: 'Mac',
  platformName: 'yimac',
  youiEngineAppAddress: 'localhost'
}],

The format of the JSON schema is a bit different in Appium Desktop, so a few small changes are needed. In Appium Inspector, click the Pencil icon in the JSON Representation area to begin editing.

  • Paste the copied capabilities into the editor, between the curly braces.
  • If you copied the top and bottom lines from the sample above, remove them.
  • If you had been using a relative path to your app (with ../.. in the path), change it to the absolute path.
  • Surround each key and each value with double quotes ", as shown below (change single quotes ' to double ", and add double quotes to the keys).

Screen capture of Appium Desktop, JSON Representation section

Click the Save icon (floppy disk) in Appium Inspector to save the JSON Representation. The Inspector is updated with your app’s capabilities listed on the left side.

Screen capture of Appium Desktop in inspection mode, with JSON Representation added

Run an Inspector Session

It’s time to run an Inspector session. If your Metro Bundler isn’t running, open a terminal window and start it.

# in a new terminal window
cd MyApp
yarn start

From the Appium Inspector, click Start Session at the bottom-right corner. Your app launches, as well as the screen shown below. If your app hides the Inspector screen, switch back to Appium to see the Inspector screen.

Screen capture of Appium Desktop inspecting your You.i Engine One application

From here we can see the entire scene tree of the app in the “App Source” column. Play with it a bit to see the information it gives you. Click the drop-down toggle for each section, then click the drop-down item again to see its nested elements.

Find the Right Element Names

Move the cursor over your app on the left side of the Inspector page. As you move your cursor over areas of the screen, sections are highlighted. These are elements in the scene tree. For our test, we want to find the name of the element containing the button text. So highlight the button element’s text (not just the button) and click it. Information about this element is shown in the Selected Element column on the right:

Screen capture of Appium Desktop showing the details of Button Text in your You.i Engine One application

Look at the Attribute > Name row, highlighted above. The name of our selected element is React:RCTText:9. Note that the name of the selected element in your running session may not be React:RCTText:9.

Close the interactive session and quit Appium Desktop. Leaving it running can interfere with the tests below.

Create the New Tests

Now that we know the name of the element we want to test, we can use it as an identifier in our test script. We can check that the text rendered on the button is correct, and we can even instruct Appium to click it for us!

Remember the AppScreen.react_image_node method from the default test we ran earlier? We need to define a similar abstraction function that returns React:RCTText:9 for our new tests.

Open MyApp/__tests__/appium/test/pageobjects/app.page.js. Here you’ll see the definition for react_image_node.

get react_image_node()  { return $("~React:RCTImageView:3"); }

Following the lead of the default test case, add a new function get react_button_node() to app.page.js. Have your new function return the attribute name of the button text element:

get react_image_node()  { return $("~React:RCTImageView:3"); }
get react_button_node() { return $("~React:RCTText:9"); }

Save and close the file.

Open MyApp/__tests__/appium/test/specs/app.test.js to add the two test cases.

Test Case 1 - For this case, we want to check the button text before we click the button. We can get the button’s text with AppScreen.react_button_node.getText(). Then we can use expect and to.equal to test that the text matches our expected value.

context('before clicking the button', () => {
  it('displays text to switch to the dark theme', () => {
    // Wait until the screen is loaded and displayed.
    expect(AppScreen.react_button_node.getText()).to.equal(
      'Switch to the dark theme'
    );
  });
});

Test Case 2 - We want to have Appium click the button, then verify the new button text. As above, we use AppScreen.react_button_node to find the button, then .click() to click it. In this case, we add a bit more logic to give the button a few seconds to change before we check the text again.

context('after clicking the button', () => {
  it('displays text to switch back to the light theme', () => {
    // Once the screen is loaded, click the theme change button
    AppScreen.react_button_node.click();
    // Give the screen 5 seconds to update
    browser.waitUntil(
      () => {
        return (
          AppScreen.react_button_node.getText() === 'Switch to the light theme'
        );
      },
      5000,
      'expected text to be different after 5s'
    );
    // Check that the text is changed
    expect(AppScreen.react_button_node.getText()).to.equal(
      'Switch to the light theme'
    );
  });
});

Run Your New Tests

It’s time to see it all in action!

From the MyApp/__tests__/appium folder, run the following command to launch your tests.

yarn yimac

If your tests fail with an Appium error, make sure you’ve closed Appium Desktop and try again.

Watch as your app launches and the theme button is clicked. The app closes again.

If your app fails to close automatically (there’s a known Appium issue that can cause this to happen), close it manually before proceeding.

Your shell window shows the success (or failure) of your tests. If your tests failed, check all your spelling carefully, including the actual button text in index.youi.js.

Screen capture of Appium Desktop showing the details of Button Text in your You.i Engine One application

You now know how to automate test cases using Appium. If you’d like more practice automating test cases using Appium with Your First App, here are some things you can test for when the button is clicked:

  • Test that the logo changes successfully.
  • Test that the background color changes successfully.
  • Test that the text color changes successfully.

These are left as exercises for you to try.

Next Steps

Now you have a working app that you can run automated tests against with Jest and Appium.

Next, you’ll learn how to extend your app’s functionality through a native module.