2018年7月3日

プログラミング

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でのテスト方法をご紹介しました。
他のマッチャやスナップショットテストなどのテストパターンもあり、今後ご紹介していきます。

Reactのお仕事に関するご相談

Bageleeの運営会社、palanではReactに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。

無料相談フォームへ

0

0

AUTHOR

eishis

Eishi Saito 総務

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

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

簡単に自分で作れるWebAR

「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。

palanARへ
palanar

palanはWebARの開発を
行っています

弊社では企画からサービスの公開終了まで一緒に関わらせていただきます。 企画からシステム開発、3DCG、デザインまで一貫して承ります。

webar_waterpark

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

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

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

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

kobori

こぼり ともろう エンジニア

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

sasai

ささい エンジニア

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

damien

Damien

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

ゲスト bagelee

ゲスト bagelee

かっきー

かっきー

まりな

まりな

suzuki

suzuki

miyagi

ogawa

ogawa

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

いわもと

いわもと

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

kobari

taishi kobari

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

shogokubota

kubota shogo

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

nishi tomoya

aihara

aihara

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

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

kainuma

Kainuma

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

sugimoto

sugimoto

asama

ando

iwasawa ayane

oshimo

oshimo

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

CONTACT PAGE TOP