Detox, Enzyme, Jest Setup in React Native

Cing Sian Dal
2 min readDec 27, 2020

Installation

Install something required by detox:

$ xcode-select --install
$ brew tap wix/brew
$ brew install applesimutils

Install detox command line.

$ npm install -g detox-cli

Install detox.

npm install detox --save-dev --no-package-lock

Option with Jest: Install Jest.

npm install jest jest-circus --save-dev --no-package-lock

Initialise configuration script for Detox with Jest.

detox init -r jest

Configuration

(For simulator release) In your .detoxrc.json file:

{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"configurations": {
"ios.sim.release": {
"type": "ios.simulator",
"binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app",
"build": "...",
"device": {
"type": "iPhone 11 Pro"
}
}
}
}

(For simulator debugging) In your .detoxrc.json file:

{
"testRunner": "jest",
"runnerConfig": "e2e/config.json",
"configurations": {
"ios.sim.debug": {
"type": "ios.simulator",
"binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app",
"build": "...",
"device": {
"type": "iPhone 11 Pro"
}
}
}
}

Build your app.

detox build

Test your app.

detox test

API

Refresh the app. Hot reload.

describe('Example', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
});

Visible or not. Get document by id and value.

A sample component.

<Text testID={'textID'}>Hello World</Text>

By id:

it('should have welcome screen', async () => {
await expect(element(by.id('textID'))).toBeVisible();
});

By value:

it('should have welcome screen', async () => {
await expect(element(by.text('Hello World'))).toBeVisible();
});

Read to test more at https://jestjs.io/docs/en/getting-started

Event Handlers

onTap:

await element(by.id('hello_button')).tap();

Read more at https://github.com/wix/Detox/tree/master/docs

Enzyme

Used for shallow, full and static component rendering.

Install enzyme.

npm i --save-dev enzyme enzyme-adapter-react-16

Setup default props for a component.

import React from 'react';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import LocalComponent from './LocalComponent';
configure({ adapter: new Adapter() });const defaultProps = { itemObjects: [{ title: "something", item: [1, 2, 3] }, { title: "something", item: [1, 2, 3] }] };const setup = (props = {}) => {
const setupProps = { ...defaultProps, ...props };
return shallow(<LocalComponent {...setupProps} />)
}
const findByTestIDAttribute = (wrapper, val) => {
return wrapper.find(`[testID="${val}"]`);
}
describe('Component testing', () => {
it('renders with default props', () => {
const wrapper = setup();
const component = findByTestIDAttribute(wrapper, 'component-nothing-title');
expect(component.exists()).toBe(false);
});
});

Setup redux default state/props:

Let’s say this is TestUtil.js:

import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers';
import { middlewares } from '../configureStore';
export const storeFactory = (initialState) => { const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore);

return createStoreWithMiddleware(rootReducer, initialState);
}

Let’s say this is configureStore.js :

import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import rootReducer from './reducers';
export const middlewares = [ReduxThunk];const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore); export default createStoreWithMiddleware(rootReducer);

Read more enzyme at https://enzymejs.github.io/enzyme/docs/api/

--

--

Cing Sian Dal

Don’t follow me. I wrote junks here. Follow me on Twitter instead.