1. ホーム
  2. React
  3. Jestでテストをはじめよう!【作りながら覚えるReact】

Jestでテストをはじめよう!【作りながら覚えるReact】

目次

  1. はじめに
  2. インストールする
  3. テストを書く
  4. まとめ

はじめに

Reactによるスマートスピーカー発音サービスを作りながら学んでいくこのシリーズ。
前回はCreate React Appを使ったアプリケーションをGitHub Pagesにデプロイする方法をご紹介しました。

GitHub PagesでReactアプリケーションを公開!【作りながら覚えるReact】

今回はFacebook公式のテストフレームワークであるJestを使用し、単体テストを行っていきます。

導入する

では、早速JestをこのSmart Speakers Commands Speaker(SSCS)に導入していきます。

といっても実はCreate React Appで作られたReactアプリケーションはすでにJestが含まれています。
その証拠にコマンドライン上で yarn start を実行するとJestが実行されます。対話型になっているので、選択して進めていきます。

No tests found related to files changed since last commit.
Press `a` to run all tests, or run Jest with `--watchAll`.
Watch Usage
› Press a to run all tests.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press q to quit watch mode.
› Press Enter to trigger a test run.

Usageの通り、コマンドを選択するとテストが実行されます。
ここでは a を押してすべてのテストを実行します。

実行結果がこちらです。

 PASS  src/App.test.js
✓ renders without crashing (76ms)
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.193s
Ran all test suites.
Watch Usage: Press w to show more.

今回はsrc/App.test.jsというファイルが実行されました。
これはもともとCreate React Appで自動的に作成されたテストファイルです。

POINT!!

今回、「すべてのテストを実行」を選択した際に自動的にApp.test.jsが選択されてテストが実行されました。
実はJestでは~.test.jsファイルはテストファイルとみなされ、自動的にテストの対象となります。
また他にも~.spec.js__tests__ディレクトリ内の.jsファイルもテスト対象となります。

テストファイルを見る

では、実行されたApp.test.jsがどういったものか見ていきましょう。

src/App.test.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});

import部分は必要なファイルを読み込んでいるだけなので、itから始まる部分がテストの部分です。
it()ブロックの中がテストで実行されます。
ブロック内のrenders without crashingは、「これからこの振る舞いをテストするよ」という宣言です。
その後のアロー関数内でテストを書きます。

アロー関数の詳細はこちらの記事をご覧ください。

今回のサンプルは特に明示的にテストコードを書くということはされておらず、div要素の中にAppコンポーネントをレンダーし、最後にdivをアンマウント(DOMから削除)するという流れが実行されているだけです。
それでも、この流れの中で正しくReactが動作されているかテストすることができています。

テストに失敗してみる

ではこのテストを実際にRed(テストが失敗する)パターンにしていきましょう。
yarn test を実行したそのままの状態で、src/components/speaker_button.js をちょっと触ってみましょう。

import React, { Component } from 'react';
import {Alexa} from '../const/alexa';
import {Google} from '../const/google';

このimport部分について、3行目のGoogleを削除してみます。
当然importしたGoogleについては内部で使われており、これが無いとGoogle Home用のスピーカーボタンを正しく表示することができません。

更新してみるとテストが自動的に実行されます。

 FAIL  src/App.test.js
● renders without crashing
ReferenceError: Google is not defined

このようにyarn test実行中は変更を自動検知し、エラー内容を表示してくれます!

テストを書く

では、実際に簡単なテストを書いていきます。

今回はexpecttoEqualを使用します。
expect関数内では、振る舞いが正しいか確認するマッチャ(Matcher)を使うことができます。
toEqual は値がexpect内のものと一致しているか確認することができます。
例えば expect(sum(2, 2)).toEqual(4); の場合には2+2をtoEqualマッチャで4と等しいか確認しています。

では、今回はどのようなテストを書くか考えていきます。
 2018-07-03 3.55.25.png (98.5 kB)
こちらのキャプチャの通り、各コマンドのカードは8個あります。
ここで「コマンドのカード数が8個か」というテストを書くこともできますが、コマンドは恐らく増えていくことが想定されますし、「それが8個で無かったときに問題なのか?」と考えていくと、そうではない気がします。

ですが、ここの個数が中途半端な7個とか9個とか奇数の場合にはかっこわるいですし、スタイルも崩れるかもしれません。
今回はコマンドの個数がAlexa側、Google Home側でそれぞれ偶数であるというテストを作ってみます。
テストについては、このように「このテストに失敗するケースの場合にサービスに問題が発生する」といったものを書くようにすると良いでしょう。

テストを書く

では、今回はsrc/const/alexa.js をテストします。
testディレクトリにテストファイルを格納していきます。

src/__test__/const/alexa.js

import React from 'react';
import ReactDOM from 'react-dom';
import {Alexa} from '../../const/alexa';
it('alexa commands length is even', () => {
expect(Alexa.commands.length % 2).toEqual(0);
});

expect(Alexa.commands.length % 2).toEqual(0);
ここでは、コマンドの個数をlengthメソッドで呼び出し、 2で割ったあまりが0かどうか(偶数かどうか)をテストしています。

実行結果を見ていきましょう。

 PASS  src/__tests__/const/alexa.js
PASS  src/App.test.js
Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.362s, estimated 1s
Ran all test suites.
Watch Usage: Press w to show more.

src/__tests__/const/alexa.js のテストが実行され、問題なく通っている(Green)であることが確認できますね!
この調子でGoogle Home側もぜひテストしてみてください。

まとめ

今回はJestでのテスト方法をご紹介しました。
他のマッチャやスナップショットテストなどのテストパターンもあり、今後ご紹介していきます。

Author Profile

eishis
eishis
SIerやスタートアップ、フリーランスを経て2016年11月にeishis, Inc.を設立。
マーケター・ディレクター・エンジニアなど何でも屋。
COBOLからReactまで色んなことやります。

この記事は
参考になりましたか?

PAGE TOP