Open7

React Nativeのテストコードを書くときのTips集

使っているテストフレームワーク

  • jest
    • jest-expo
    • ts-jest
    • babel-jest
    • @types/jest
    • @testing-library/jest-native
  • @testing-library/react-native

前提

  • expoを使っている(eject予定なので、そのときの移行Tipsもまとめられたらと思う)

jest.config.js

module.exports = {
  preset: 'jest-expo',
  setupFilesAfterEnv: ['@testing-library/jest-native/extend-expect'],
  moduleFileExtensions: ['ts', 'tsx', 'js'],
  transform: {
    '^.+\\.(js)$': '<rootDir>/node_modules/babel-jest',
    '\\.(ts)$': 'ts-jest',
    '^.+\\.tsx?$': 'babel-jest',
  },
  testRegex: '(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$',
  testPathIgnorePatterns: ['\\.snap$', '<rootDir>/node_modules/'],
  cacheDirectory: '.jest/cache',
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.json',
    },
  },
  transformIgnorePatterns: [
    'node_modules/(?!((jest-)?react-native|react-router-native|react-clone-referenced-element|expo(nent)?|@expo(nent)?/.*|react-navigation|以下略))',
  ],
};

ポイントはtransformIgnorePatterns
ここに地道に設定を足していく

あとは設定のなかでいくつかDeprecatedになるものがあり、そのへんのネット文献だと警告が出るものは修正している

各jest系パッケージのバージョン

メジャーバージョンを合わせておくほうがよさげ。

テストファイルの拡張子

基礎的なところだが、テストファイルの拡張子は.test.tsxのようにtsxとする

コンポーネントの表示テスト

以下が例。

      const component = render(<ChatMessage message={createMockMessage()} />);
      expect(component.queryByText('text')).toBeTruthy();
      expect(component.queryByText(LABELS.READ)).toBeNull();
      expect(component.queryByA11yLabel(LABELS.DELETE_BUTTON)).toBeNull();

render

TSXコンポーネントを渡す。

queryByText

実際に表示されているテキストを検索してくれる。厳密にテストしたければもう少し工夫の余地がありそう。

ちなみにgetByTextというのもありこちらを利用しても同様の結果は得られる。しかし「表示されていないこと」をテストしたいときgetXXXを使うとそこで落ちてしまうため、現状queryをベースにテストを書いていくことが好み。

queryByA11yLabel

画像など、表示されている内容がテキストではない場合にとりあえず使っている。
元コンポーネントの方でアクセシビリティラベルを設定するとよい。

          <Image
            accessibilityLabel="送信された画像"
            source={{ uri: props.uri }}
          />

存在しない場合はNULLが返ってくるためそれをアサートする

@testing-library/react-native 注意点

cleanup

以下を書く

afterEach(cleanup);

render

renderメソッドはitメソッド内で実行する必要がありそう。describeで実行するとUnable to find node on an unmounted component.というエラーになった

Alertのモック

アラートが表示されることをモックでアサートしたい

spyOnでモック関数をImplementationOnceして入れ込めばいい。引数はそのまま流す

import { Alert } from 'react-native';
const mockAlert = jest.fn();
jest.spyOn(Alert, 'alert').mockImplementationOnce((...arg) => mockAlert(...arg));

そしてテストは普通にモック関数のテストを書けばいい。以下は若干好奇心もあり書きすぎたがだいたいこんな感じで書ける

    fireEvent(component.queryByA11yLabel('削除ボタン'), 'click');
    expect(Alert.alert).toHaveBeenCalledTimes(1);
    expect(mockAlert.mock.calls.length).toBe(1);
    expect(mockAlert.mock.calls[0][0]).toBe('本当に削除しますか?');
    expect(mockAlert.mock.calls[0][1]).toBe('この操作は取り消すことができません');
    expect(mockAlert.mock.calls[0][2][0].text).toBe('いいえ');
    expect(mockAlert.mock.calls[0][2][1].text).toBe('はい');
ログインするとコメントできます