JavaScriptの人気テストフレームワークJest

develop/JavaScript
概要

JavaScriptで人気のテストフレームワークのJestについて調査したので整理します。GNU social本体で部分的に使用されているJavaScriptやQvitterの開発・修正で活用したいと考えています。

Jest · 🃏 Delightful JavaScript Testing」が公式サイトです。「Getting Started · Jest」がチュートリアルとなっていますので、これを参考に使用方法を学習します。

設置

まず以下のコマンドでJestを設置・インストールします。

npm install -D jest

npm installのオプションの意味 | GNU social JP」で紹介した通り、これでpackage.jsonのdevDependenciesにJestの依存関係が追加されます。npm install –productionやNODE_ENV=productionの場合にはインストールされません。

基本

Jestではテストを記述したファイルはtest.jsの拡張子にします (Configuring Jest · Jest)。こうすることで、Jestが自動的にテスト対象を見つけてテストコードを実行してくれます。デフォルトである程度うまく動作するような作りのようです。

試しに加算を行う単純な関数を試験します。

// sum.js
export {sum}

function sum(a, b) { return a + b; } // module.exports = sum;
// sum.test.js
import {sum} from './sum.js'
test('adds 1 + 2 to equal 3', () => { expect(sum(1, 2)).toBe(3); });

Jestのサンプルコードだとmodule.exportsを使っています。見知らぬオブジェクトだったので調べたところ、これはnode.jsの組み込みオブジェクトでした (Modules | Node.js v8.17.0 Documentation)。node.jsを使っていないプロジェクトもあるので、ES2015のexport/import文に差し替えました (JavaScriptのexport/import文 | GNU social JP)。

最後にpackage.jsonに以下を追加します。

{
  "scripts": {
    "test": "jest"
  }
}

このままだとES2015に対応できていないので、「JestのES2015対応設定 | GNU social JP」に記した方法で、package.jsonを以下の内容にしました。

{
  "type": "module",
  "scripts": {
    "test": "NODE_OPTIONS='--experimental-vm-modules --no-warnings' jest"
  },
  "devDependencies": {
    "jest": "^29.5.0"
  }
}

この状態でnpm testを実行するとテストが実行されます。

 PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (1 ms)

以上がテストの基本的な実施方法です。

test

以上までがJestの基本でしたが、テストコードにtestとexportの2個だけ重要な項目が登場しているのでこれだけ整理します。

1個目はtest関数です。Jestでテストを実行するための関数で、非常に重要なものです。以下の書式です。

test(name, fn, timeout)
  • name: テスト名。
  • fn: テストの確認項目を含む関数。後述のexpect関数を使うことが多い。
  • timeout: テスト許容時間 (デフォルト=5 ms)。

基本はテスト名とテスト関数を指定するだけです。test関数1個につきテスト1回という感じです。

以下のように、test関数に複数のexpect関数を実行させて、一度に似た複数の試験も可能です。

test('null', () => {
  const n = null;
  expect(n).toBeNull();
  expect(n).toBeDefined();
  expect(n).not.toBeUndefined();
  expect(n).not.toBeTruthy();
  expect(n).toBeFalsy();
});

testの代わりにitという別名の関数も利用可能です (Jestのtestとitの違い | GNU social JP)。

その他に、チュートリアルだと説明がないのですが、describe関数があります。

describe(name, fn)

こちらはtestのブロックを作るための関数でです。上記のようなtest関数内で複数のexpectを実行しても、それは全体で1試験扱いでどれが失敗したかわかりません。

const myBeverage = {
  delicious: true,
  sour: false,
};

describe('my beverage', () => {
  test('is delicious', () => {
    expect(myBeverage.delicious).toBeTruthy();
  });

  test('is not sour', () => {
    expect(myBeverage.sour).toBeFalsy();
  });
});

上記のようにすることで、試験をグループ化できます。例えば、オブジェクトごとや関数ごとにグループを作って、個別の引数・ケース別にtestを実行すると、わかりやすいかもしれません。

describe自体は必須ではありませんが、試験コードを追加していく上では使ったほうが便利でしょう。

expect

expect関数は、引数に試験対象関数の戻り値を渡して呼び出し、expect関数の戻り値のオブジェクトに対して、試験のためのMatcherメソッドを使って、結果が期待通りかをチェックします。

Using Matchers · Jest」にMatchersの説明があります。

基本はtoBeメソッドによる値の一致です。

Matcherメソッドの他に、いくつか便利に修飾子があります。一番便利なのはnotプロパティーでこれを使うと期待値の否定をテストできます。

あとは、オブジェクト同士のプロパティー値の比較の場合はtoEqualです。他に、論理値や大小比較など、いろいろあります。必要になったタイミングで確認して追記します。

結論

JavaScriptの人気のテストフレームワークのJestでした。あくまでテストを行うためのツールなので、ツール特有の事項は最小限にして、実コードのテストに専念したほうが良いと思います。

(自分の) JavaScript のユニットテストの書き方」の考え方が参考になりました。

コードで問題になりがちなものは、nullアクセスなどある程度パターン化されています。そこを集中的にテストでカバーしたり、一度問題が起きたケースをテストにすることで再発を防止できます。

実際に使い込んでいってみたいです。

Comments

  1. This Article was mentioned on web.gnusocial.jp

  2. This Article was mentioned on web.gnusocial.jp

Copied title and URL