# Testing

## Unit Testing

The first and the most popular option is unit-testing of your JavaScript modules. React Native Starter comes with ready-to-use Jest integration, which you can use to test components, classes and functions.

Let's talk about testing each of them.

### Testing Views

The best way to test if your views are rendered correctly is to create a view snapshot and compare the new snapshots each time. This way you can see when your views are changing or not.

Let's pretend you have a button component that can take a string or an image as a children component and calls onPress handler when TouchableOpacity inside this component is clicked. So your button component looks something like this:

{% code title="components/Button.js" %}

```javascript
export const Button = ({ children, onPress }) => (
  <View style={styles.container}>
    <TouchableOpacity onPress={onPress}>
      {children}
    </TouchableOpacity>
  </View>
);
```

{% endcode %}

And what you want to test here are that:

1. Button renders correctly with image and with a text.
2. `onPress`handler is fired when TouchableOpacity has been pressed.

Let's create a test file called `Button.spec.js`. By default, jest looks for all the files named as `*.spec.js`, `*.test.js` and for files placed under the `__tests__` folder.

{% code title="components/Button.spec.js" %}

```javascript
import React from 'react';
// Import enzyme's shallow renderer
import { shallow } from 'enzyme';

// Describes a test group
describe('Button', () => {
  it('renders correctly with a text', () => {
    // Render our button with a text inside
    const wrapper = shallow(<Button>test</Button>);

    // Check that the rendered button matches
    // previously saved snapshot
    expect(wrapper).toMatchSnapshot();
  });

  it('renders correctly with an image', () => {
    // Render our button with an image inside
    const wrapper = shallow(
      <Button>
        <Image src={require('something')} />
      </Button>,
    );

    // Check that the rendered button matches
    // previously saved snapshot
    expect(wrapper).toMatchSnapshot();
  });

  it('handles onPress', () => {
    // Create a mock function to pass as a handler
    const onPress = jest.fn();

    // Render our button with an image inside
    const wrapper = shallow(<Button onPress={onPress}>test</Button>);

    // Find a TouchableOpacity and press it
    wrapper
      .find('TouchableOpacity')
      .first()
      .props()
      .onPress();

    // Check that our handler have been called 1 time
    expect(onPress).toHaveBeenCalledTimes(1);
  });
});

```

{% endcode %}

Learn more about Unit-testing here: <https://jestjs.io/docs/en/tutorial-react-native>

## End to end testing

We integrated **Detox** framework for running end2end tests for your app. We also integrated it with jest, so you can write your tests in the familiar environment.

High velocity native mobile development requires us to adopt continuous integration workflows, which means our reliance on manual QA has to drop significantly. Detox tests your mobile app while it's running in a real device/simulator, interacting with it just like a real user.

The most difficult part of automated testing on mobile is the tip of the testing pyramid - E2E. The core problem with E2E tests is flakiness - tests are usually not deterministic. We believe the only way to tackle flakiness head on is by moving from black box testing to gray box testing. That's where Detox comes into play.

* **Cross Platform:** Write cross-platform tests in JavaScript. Currently supports iOS, Android is nearly complete. View the [Android status page](https://github.com/wix/Detox/blob/master/docs/More.AndroidSupportStatus.md).
* **Runs on Devices** (not yet supported on iOS): Gain confidence to ship by testing your app on a device/simulator just like a real user.
* **Automatically Synchronized:** Stops flakiness at the core by monitoring asynchronous operations in your app.
* **Made For CI:** Execute your E2E tests on CI platforms like Travis without grief.
* **Test Runner Independent:** Use Mocha, AVA, or any other JavaScript test runner you like.
* **Debuggable:** Modern async-await API allows breakpoints in asynchronous tests to work as expected.

Let's pretend you want to test your that your login flow works and verify it with Detox.

First, create a file called `login.spec.js` under the `e2e` folder and add the following code there:

{% code title="e2e/login.spec.js" %}

```javascript
describe('Login flow', () => {
  it('should login successfully', async () => {
    await device.reloadReactNative();
    await expect(element(by.id('email'))).toBeVisible();
      
    await element(by.id('email')).typeText('john@example.com');
    await element(by.id('password')).typeText('123456');
    await element(by.text('Login')).tap();
      
    await expect(element(by.text('Welcome'))).toBeVisible();
    await expect(element(by.id('email'))).toNotExist();
  });
});

```

{% endcode %}

&#x20;Then, simply open your console and type

```bash
e2e:build && e2e:test
```

That's it! You should see the iOS simulator opened and your app tested.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.reactnativestarter.com/testing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
