SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

基礎からはじめるReact入門

Reduxで作成したロジックをJestでテストする

基礎からはじめるReact入門 第11回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Jestの基本

 create-react-appでJestを用いたテストコードを作成する場合は、次の2つのルールのどちらかを守る必要があります。

  • src/__tests__ フォルダの中にテストコードを配置する(ファイル名は何でもよい)
  • ファイル名の末尾を .test.js にする( src 内ならどこに置いてもよい)

 今回は後者のルールを中心にファイルを作成していきます。まずは、Jestの使い方の基本を見ていきましょう。

最小の例

 前述のsum.jsのテストコードとして、sum.test.jsを作成してみましょう(リスト2)。

[リスト2]src/sum.test.js
import { sum } from "./sum"; // (1)

test("1足す1は2になる", () => { // (2)
  // 条件
  const a = 1;
  const b = 1;
  // テスト対象の処理を実行する
  const actual = sum(a, b); // (3)
  // 処理結果が期待したものになっているかを検証する
  expect(actual).toBe(2); // (4)
});

 まずは通常のコードから利用する時と同様に、テスト対象の処理をimportします(1)。次に、グローバルスコープに定義されているtest関数を使って、テストの名前とテスト内容の関数を定義します(2)。なお、test関数により定義された、試行1回分のテストを「テストケース」と呼びます。テストケースの中では、テスト対象の処理を任意のパラメータで実行します(3)。最後に、グローバルスコープに定義されているexpect関数を使って、処理結果が期待通りかを検証します。これらのグローバル関数は、テストの実行時にJestが提供しているものです。

 テストコードを作成したら、ターミナルでリスト3のコマンドを実行します。

[リスト3]テストを実行する
$ npm run test

 実行するとターミナルが図1のような状態になります。

ターミナル
図1:ターミナルがテスト結果を表示している様子

 テストケースの名前である「1足す1は2になる」が表示されて、テストが成功したことが示されています。これがJestを用いたテストの最小の形です。

 create-react-appでは監視モードでJestが起動されるので、テストファイルを更新するたびに、テストが再実行されます。テストを終了したい場合はキーボードで「q」を押してください。テストファイルがたくさんある場合には、直近で編集したファイルのみがテスト対象になりますが、「a」を押すことでsrcフォルダ内のすべてのテストファイルを実行できます。監視モードで実行したくない場合にはCI=true npm run testのように先頭にCI=trueを付けることで、一通りのテストが終わったら終了する形式で実行できます。

 また、テストファイルの中にテストケースを複数記述することで、さまざまなパターンのテストを行うこともできます(リスト4)。

[リスト4]複数のテストケースを定義する例
import { sum } from "./sum";

test("1足す1は2になる", () => { ... });
test("1足す2は3になる", () => { ... });
test("4足す5は9になる", () => { ... });
test("1足す-1は0になる", () => { ... });

 この仕組みを用いることで、大量のテスト≒動作確認を高速に実施することができます。テスト対象のコードの種類によっては、先にテストケースを用意して動作確認を済ませてから、アプリに組み込んだほうが楽に開発を進められる場合もあります。

複数の関数のテストを分かりやすく管理する

 ファイル名の命名の特性上、JSファイル(XXX.js)1つに対して同名のテストファイル(XXX.test.js)を1つ作成する場合が多くなりますが、1つのJSファイルには複数の関数が含まれていることもしばしばあります。テストケースに「○○関数にaとbを渡したときにcになること」や「△△関数にxとyを渡したときにzになること」などの名前を付けながら管理することも可能ですが、少し冗長ですね。

 Jestでは、テストケースをグループ分けして管理するための仕組みが用意されています。足し算だけではなく、引き算(sub)も扱えるcalc.jsを作成して、そのテストファイルがどうなるのかを見てみましょう(リスト5)。

[リスト5]テストケースをグループ分けして管理する例
// src/calc.test.js
import { sum, sub } from "./calc";

describe("sum(a, b)", () => { // (1)
  test("1足す1は2になる", () => {
    const actual = sum(1, 1);
    expect(actual).toBe(2);
  });
  test("2足す2は4になる", () => {
    const actual = sum(2, 2);
    expect(actual).toBe(4);
  });
});
describe("sub(a, b)", () => {
  test("1引く1は0になる", () => {
    const actual = sub(1, 1);
    expect(actual).toBe(0);
  });
  test("5引く2は3になる", () => {
    const actual = sub(5, 2);
    expect(actual).toBe(3);
  });
});

 グループ分けして管理する場合、グローバルスコープに定義されているdescribe関数を使用します。使い方はtest関数とほとんど同じ(1)ですが、describe関数の中には複数のテストケースを定義する点が異なります。describe関数を用いて記述したテストファイルを実行すると、テスト結果が図2のような見た目に変わります。

describeを使用した場合のテスト結果の表示
図2:describeを使用した場合のテスト結果の表示

 何の関数をテストした結果なのか一目で分かりますね。本来はdescribe関数の第一引数に付ける名前は何でも構いませんが、筆者は好んで関数の名前を付けています。他にも管理しやすい命名のし方があると思うので、工夫してみてください。

expectのよく使う機能

 Jestでは、実行結果を検証するためにexpect関数を用います。これまでの例ではtoBe関数をつなげて使用することで値を評価していましたが、他にも多くの評価用関数が用意されています。全体としてはこちらのドキュメントで紹介されています。

 本記事では、頻繁に使うもののみをリスト6に挙げます。

[リスト6]実行結果を検証するための方法
// 基本型の値の同一性を評価するtoBe
expect(123).toBe(123);
// オブジェクトの値の同一性を再帰的に評価するtoEqual
expect({ a: 1, b: 2 }).toEqual({ a: 1, b: 2 });
// 条件に一致しないことを確認するnot
expect(123).not.toBe(0);
expect({ a: 1, b: 2 }).not.toEqual({ c: 1 });
// エラーが発生することを確認するtoThrow
expect(() => {
  sum("one", "two"); // 数値ではないのでエラーが出る
}).toThrow();

 これらの組み合わせで多くのテストは実施できますが、さらにかゆいところに手が届く便利な機能も用意されているので、困った時にはドキュメントを眺めてみてください。

次のページ
Reduxと自動テスト

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
基礎からはじめるReact入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10996 2018/08/21 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング