Jest

2021-01-21 hit count image

create-react-appでテストでよく使ってるJestについて説明します。

create-react-appシリーズ

このブログポストはシリーズで作成しております。次はcreate-react-appのシリーズのリストです。

概要

テストはサービスを開発してメインテナンスするに必須な条件の一つです。テストは全ての機能を確認する時間を減らしてくれるし、バグ発生を予防、同じバグが再び発生しないようにしてくれます。または、コードを修正する時、修正したコードのサイドエフェクトを探してくれるし、予想できなかった動作を見つけてくれます。

このようにテストコードはソフトウェア開発に大事な役割をやっております。そして、大体の言語にはその言語に合うテストフレームワークが存在してます。JavaScriptにもMocha, Jasmine, Karmaなどたくさんのフレームワークが存在して、JestもJavaScriptのテストフレームワーク中で一つになります。

create-react-appは基本的Jestを使ってます。このブログポストではJestの特徴と使い方に関して調べてみます。

Jestの特徴

JestはReactと同じようにFacebookが開発して管理してるJavaScriptテストフレームワークです。JavaScriptテストフレームワークなのでReact意外にもTypescrpt、ノード、Angular、Vueなどのテストもできます。

Jestはシンプルに集中して誰でも簡単にテストができるようにすることを目指しております。Jestはシンプル以外にも下記のような特徴を持っています。

ゼロ設定

テストを始めるためにたくさんのテストフレームワークは色んな設定をしなければならないです。しかし、Jestはこのような設定のせいで簡単にテストができないことを解決するためゼロ設定で提供してます。

スナップショット

JavaScriptで値を一々確認することができないぐらい大きなオブジェクトがある時があります。この場合をテストするためJestはスナップショット機能を提供してます。スナップショットは大きなオブジェクトを保存した後、コードの変更などでオブジェクトの値が変わると、エラーを表示してテストをする機能です。Reactではこのスナップショットの機能を使って画面にレンダリングされたReactのコンポーネントの変更点をチェックするため使っております。

テストコードの分離

Jestはテストコードを完全に分離して、互いに影響を与えません。このように完全に分離されたテストは同時に実行することが出来て、全てのテストの時間を減らしてくれます。

簡単なAPI

Jestをシンプルを目指しているので、提供してるAPIもすごく単純です。または–coverageオプションを使って簡単にテストコードのカバレッジを確認することが出来ます。

使い方

実際Jestを使う方法について説明します。ここに紹介してるソースコードは下記のGitHubのリンクで確認できます。

まずJestを使うためにはJavaScriptプロジェクトが必要です。Jestを練習するためフォルダを生成した後、次のコマンドを実行してJavaScriptのプロジェクトを準備します。

# mkdir jest-example
# cd jest-example
npm init

上のコマンドを実行したら、色んな質問が出ますが、全てEnterキーを押して進めます。

全ての質問にEnterキーを押して進めたら、当該フォルダへpackage.jsonファイルが生成されることが確認できます。次はこのフォルダへindex.jsファイルとindex.test.jsファイルを生成してJestを使う準備をします。

ここで生成したindex.jsファイルは実際開発する内容が追加されて、index.test.jsファイルにはindex.jsファイルに関するテストの内容が追加される予定です。

Jestインストール

次のコマンドを使ってJestをインストールします。

npm install --save-dev jest

インストールが終わったら、package.jsonファイルを開いてscriptsの項目を下記のように修正します。

"scripts": {
  "test": "jest --watch"
},

次のコマンドを実行してJestを実行します。

npm run test

まだ、テストコードがないので、エラーが出るはずです。今度はテストコードを追加しながらJestの使い方を説明します。

toBe

まず、index.jsファイルを開いて下記のように修正します。

const sum = (a, b) => {
  return a + b;
};

module.exports = {
  sum,
};

パラメーター二つを貰って単純に加算をする単純なJavaScriptコードです。次はこのコードのテストコードを作成するためindex.test.jsファイルを開いて次のように修正します。

const { sum } = require('./index');

describe('test index.js file', () => {
  it('sums a and b', () => {
    let result = sum(1, 2);
    expect(result).toBe(3);
    result = sum(3, 4);
    expect(result).toBe(7);
  });
});

まず、index.jsファイルからsum関数を取ってきます。

const { sum } = require('./index');

そしてJestのdescribe関数を使って説明文とテストコードが入るCallback関数を設定します。

describe('test index.js file', () => {
  ...
});

テストコード作成するためにはJestのit関数を使います。it関数はdescribeと同じように説明文とテストコードが作成されたCallback関数を指定します。

it('sums a and b', () => {
  ...
});

次は実際テストをするためJestのexpectの中で確認したい値を入れて、toBeを使ってその値の期待値を追加してテストが期待通り動いてるか確認します。

let result = sum(1, 2);
expect(result).toBe(3);

少し単純にすると下記のように使うことができます。

expect(sum(1, 2)).toBe(3);

Jestでは上のように私たちが確認したい値は期待値を入れることでテストコードを作成することができます。

このようにファイルを修正して保存すると前、実装したjest --watchのコマンドでJestが変更されたファイルを認識して自動でテストを実行して下記のようなテスト結果が表示されることが確認できます。

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.712 s, estimated 1 s

toEqual

JavaScriptを少し勉強した方はJavaScriptのObjectの比較は簡単ではないことが分かると思います。

const temp = {
  name: 'Yakuza',
  age: 20
}

console.log(temp == {
  name: 'Yakuza',
  age: 20
});
// false

Jestではオブジェクトを比較するためtoEqualと言う関数を提供してます。まず、index.jsファイルを開いて次のように修正します。


const makeUser = (name, age) => {
  return {
    name,
    age,
  };
};

module.exports = {
  
  makeUser,
};

そしてindex.test.jsファイルを開いて下記のように修正します。

const { ..., makeUser } = require('./index');

describe('test index.js file', () => {
  ...
  it('makes a person', () => {
    expect(makeUser('Yakuza', 20)).toEqual({
      name: 'Yakuza',
      age: 20,
    });
  });
});

JestではtoEqual関数を使って簡単にオブジェクトをテストすることができます。

このようにファイルを修正して保存すると、下記のような結果を確認することができます。

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b
    ✓ makes a person (1 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        0.577 s, estimated 1 s

toContain

Jestでは配列中に値が含まれているかどうか確認するtoContain関数を提供してます。

まず、index.jsファイルを開いて下記のように修正します。

...

const makeRange = (start, end) => {
  let result = [];
  for (let i = start; i <= end; i++) {
    result.push(i);
  }
  return result;
};

module.exports = {
  ...
  makeRange,
};

新しく追加した関数は配列の始める値と終わりの値を受けて配列を作ってくれる関数です。次はこの関数をテストするためindex.test.jsファイルを開いて下記のように修正します。

const { ..., makeRange } = require('./index');

describe('test index.js file', () => {
  ...
  it('has 3', () => {
    expect(makeRange(1, 4)).toContain(2);
  });
});

上のように配列に値が含まれているかどうか確認するため、JestではtoContainを使います。

このようにファイルを修正して保存すると、次のような結果を確認することができます。

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (1 ms)
    ✓ makes a person
    ✓ has 3

Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        0.604 s, estimated 1 s

その他

Jestではここで紹介した関数以外にもたくさんの関数を提供してます。下記のリンクを使ってJestが提供してる関数を確認することができます。

コードカバレッジ

最後にJestのコードカバレッジを実行してみましょう。現在実行中のコマンドをキャンセルして次のコマンドを実行してみます。

npx jest --coverage

このようにJestをカバレッジオプション(–coverage)を使って実行すると次のようにコードのカバレッジの結果を確認することができます。

 PASS  ./index.test.js
  test index.js file
    ✓ sums a and b (2 ms)
    ✓ makes a person
    ✓ has 3 (1 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |
 index.js |     100 |      100 |     100 |     100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        2.703 s

完了

このブログポストではcreate-react-appで基本的使えるJestに関して調べてみました。今後はcreate-react-appでJestを使ってテストしてみましょう。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts