2018年7月3日
プログラミング
Jestでテストをはじめよう!【作りながら覚えるReact】


はじめに
Reactによるスマートスピーカー発音サービスを作りながら学んでいくこのシリーズ。
前回はCreate React Appを使ったアプリケーションをGitHub Pagesにデプロイする方法をご紹介しました。
今回は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
実行中は変更を自動検知し、エラー内容を表示してくれます!
テストを書く
では、実際に簡単なテストを書いていきます。
今回はexpect
とtoEqual
を使用します。
expect関数内では、振る舞いが正しいか確認するマッチャ(Matcher)を使うことができます。
toEqual
は値がexpect内のものと一致しているか確認することができます。
例えば expect(sum(2, 2)).toEqual(4);
の場合には2+2をtoEqualマッチャで4と等しいか確認しています。
では、今回はどのようなテストを書くか考えていきます。
こちらのキャプチャの通り、各コマンドのカードは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でのテスト方法をご紹介しました。
他のマッチャやスナップショットテストなどのテストパターンもあり、今後ご紹介していきます。
Reactのお仕事に関するご相談
Bageleeの運営会社、palanではReactに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
0
0
関連記事

2022年5月13日
Reactでオセロゲームを作る

2021年4月9日
Slack OAuth x React で Slack ユーザー認証を作ってみた!

2021年3月1日
Reactで使えるバリデーションライブラリを紹介!

2021年2月22日
Hasura Cloud × Auth0 × React でお手軽にTodoアプリを作ってみた!

2020年12月12日
Blitz.jsとTailwind CSSでメモ帳アプリの作成【第2弾】

2020年12月8日
コンポーネントを実装するときに意識すること
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへ
palanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー

Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

かっきー

まりな

suzuki
miyagi

ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと
デザイナーをしています。 好きな食べ物はラーメンです。

taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。

kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya

aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto
asama
ando
iwasawa ayane

oshimo
異業界からやってきたデザイナー。 palanARのUIをメインに担当してます。 これからたくさん吸収していきます!