React Native 테스트 전략: Jest와 Detox 활용법

작성일 :

React Native 테스트 전략: Jest와 Detox 활용법

React Native로 애플리케이션을 개발하다 보면 품질 관리를 위해 테스트가 필수적입니다. 다양한 종류의 테스트가 있으며, 이에 따라 테스트 도구도 다양합니다. 이 글에서는 대표적인 테스트 도구인 Jest와 Detox를 사용한 테스트 전략을 살펴보겠습니다.

유닛 테스트 (Unit Test)

유닛 테스트는 애플리케이션의 가장 작은 단위를 테스트하는 것으로, 일반적으로 함수 하나 또는 컴포넌트 하나를 테스트합니다. React Native에서 유닛 테스트를 할 때 가장 많이 사용하는 도구는 Jest입니다.

Jest 설정하기

먼저 Jest를 설치해야 합니다.

bash
npm install --save-dev jest

그 다음 package.json 파일에 다음과 같은 설정을 추가합니다.

json
{
  "scripts": {
    "test": "jest"
  }
}

기본 설정이 완료되면 테스트 파일을 작성할 수 있습니다. 예를 들어, sum.js 파일이 있다고 가정합시다.

javascript
// sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

이 함수에 대한 유닛 테스트를 작성해보겠습니다.

javascript
// sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

이제 터미널에서 npm test를 실행하면 유닛 테스트가 실행됩니다.

통합 테스트 (Integration Test)

통합 테스트는 여러 유닛들이 모여서 제대로 작동하는지 확인하는 테스트입니다. 보통 여러 컴포넌트 또는 모듈이 올바르게 연동되는지 확인합니다.

통합 테스트도 Jest를 사용할 수 있으며, 추가로 React Testing Library를 사용하여 컴포넌트를 렌더링하고 상호작용할 수 있습니다.

React Testing Library 설정하기

먼저 React Testing Library를 설치합니다.

bash
npm install --save-dev @testing-library/react-native

다음으로, 간단한 버튼 컴포넌트를 테스트해보겠습니다.

javascript
// Button.js
import React from 'react';
import { Button, Text, View } from 'react-native';

const MyButton = ({ onPress, title }) => (
  <View>
    <Button onPress={onPress} title={title} />
  </View>
);

export default MyButton;

이 컴포넌트에 대한 통합 테스트를 작성합시다.

javascript
// Button.test.js
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import MyButton from './Button';

test('button click updates text', () => {
  const handlePress = jest.fn();
  const { getByText } = render(<MyButton onPress={handlePress} title="Press me" />);

  fireEvent.press(getByText('Press me'));
  expect(handlePress).toHaveBeenCalledTimes(1);
});

End-to-End 테스트 (E2E Test)

End-to-End 테스트는 애플리케이션의 전체 흐름을 테스트하는 것으로, 실제 사용자 관점에서 테스트를 수행합니다. 이 때는 주로 Detox를 사용합니다.

Detox 설정하기

Detox를 설치하고 설정하는 과정은 조금 복잡할 수 있습니다. 먼저 Detox와 필요한 의존성을 설치합니다.

bash
npm install --save-dev detox
npm install --save-dev jest-circus

다음으로 Detox 설정 파일을 생성해야 합니다. e2e/config.json 파일을 생성하고 다음과 같이 작성합니다.

json
{
  "testRunner": "jest",
  "runnerConfig": "e2e/config.js",
  "configurations": {
    "ios.sim.debug": {
      "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/YourApp.app",
      "build": "xcodebuild -workspace ios/YourApp.xcworkspace -scheme YourApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
      "type": "ios.simulator",
      "name": "iPhone 12"
    }
  }
}

다음으로, e2e/config.js 파일을 생성하고 다음과 같이 작성합니다.

javascript
const { init, device, expect, element, by } = require('detox');
const { detox: { configurations } } = require('../package.json');

describe('Example', () => {
  beforeAll(async () => {
    await init(configurations);
  });

  beforeEach(async () => {
    await device.reloadReactNative();
  });

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

  it('should show hello screen after tap', async () => {
    await element(by.id('welcome_button')).tap();
    await expect(element(by.id('hello'))).toBeVisible();
  });
});

이제 npm run build 명령어로 애플리케이션을 빌드하고, detox test 명령어로 테스트를 실행하면 됩니다.

결론

React Native 애플리케이션의 테스트는 초기 설정에 다소 시간이 걸리지만, Jest와 Detox를 활용하면 유닛 테스트, 통합 테스트 및 End-to-End 테스트를 효과적으로 수행할 수 있습니다. 이러한 테스트들은 애플리케이션의 품질을 보장하고, 버그를 사전에 발견하여 유지 보수 비용을 절감하는데 큰 도움을 줍니다.