jest テストコード

今日から始める!:Jestでテスト(基本的なテスト)

Jestアイキャッチ画像

 

nao
これからJestを使ってテストコードを書いていこうと思うんだけど、そもそも何を書けばいいのかわからない、、、

 

今回はこんな疑問を解消します。

 

こんな方におすすめ

  • Jestを用いたテストコードの書き方を知りたい人
  • Jestの導入方法がわからない人

 

テストコードについて解説をしている記事や書籍ってあまりなく体形的に学ぶのって難しいですよね。

今回はこれからテストコードを書きたいと思っている人向けの記事となっており

環境構築から解説をしていくので安心してください。

 

nao
さっそくやっていきましょう

 

Jestの概要

 

環境構築をする前にまずはJestの概要についてさらっと解説をします。

Jestは、JavaScriptおよびTypeScriptのテストフレームワークであり、Facebookによって開発されました。

Jestは、ReactやVueなどのフロントエンドライブラリ/フレームワークだけでなく、Node.jsなどのサーバーサイドの環境でも広く使用されています。Jestは、コードベースが大きなプロジェクトから小さなプロジェクトまで対応しています。

主な特徴としては以下になります。

 

  • Zero Configuration: ほとんどのJestの機能は設定なしで即座に利用可能。
  • Snapshot Testing: UIの変更を自動的に検出するスナップショットテストが容易にできます。
  • Built-in Test Runners: テストケースの実行環境が組み込まれているため、外部ライブラリへの依存が少ない。
  • Isolation: Jestは各テストファイルを独立した環境で実行するため、テストが互いに影響を与えにくい。
  • Rich Matchers: 数多くのマッチャ(アサーションメソッド)が用意されており、テストケースを多角的に記述できる。
  • Mocking and Spying: Jestにはモッキングとスパイ機能が豊富に用意されているため、外部依存性のある関数やモジュールを容易にテスト可能。

 

以下の画像をみるとテストフレームワークにおいても1位になっているのがわかります。

JavaScriptで開発をしているとテストフレームワークはJestを導入しているケースが多いのでこの機会に

一緒に使い方を学んでいきましょう!

 

Jestシェア率画像

 

 

環境構築

 

ではさっそく環境構築を進めていきましょう!

作業用ディレクトリは自由で大丈夫ですが私はjest-practiceとしました。

jest-practiceディレクトリで以下のコマンドを入力してください。

エディタはVsCodeを使用しています。

 

 command
npm init -y
npm i -D typescript
npm i -D jest @types/jest ts-jest
npx ts-jest config:init
code .

 

次にpackage.jsonを開いてscriptsの項目を探しtestを以下のように変更してください。

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

これで環境構築は完了です。

 

Jestを用いた最初のテスト

 

環境構築が終わったのでさっそくテストを書いていきましょう。

ルートディレクトリにsrcフォルダを作成して、その中にpracticeフォルダを作成してください。

practice配下にsum.tsとsum.test.tsを作成してください。

sum.tsになんらかのプログラムを書き、sum.test.tsではsum.tsで作成したプログラムをテストします。

以下のように記述をしてください。

 

 sum.ts
export function sum(a: number, b: number): number {
return a + b;
}

 

 sum.test.ts
import { sum } from "./sum";
it("1と2を足すと3になる", () => {
expect(sum(1, 2)).toBe(3);
});

簡単なコードですが、ここから始めてみましょう。

it("1と2を足すと3になる", () => { ... });
Jestのit関数を用いて、テストケースを定義しています。it関数は、第一引数にテストケースの説明(文字列)を受け取り、第二引数に実際のテスト処理(関数)を受け取ります。

expect(sum(1, 2)).toBe(3);
expectとtoBeは、Jestのアサーション(確認)メソッドです。

expect(sum(1, 2))で、sum(1, 2)という関数呼び出しの結果(戻り値)を取得しています。
.toBe(3)で、その結果が3であることを確認しています。

この状態でターミナルを開き

npm testを実行してください。

そうするとtestが成功しているのがわかると思います。toBeを3以外にするとテストは失敗します。

 

マッチャー関数

 

次はマッチャー関数です。

Jestのマッチャー(Matcher)関数とは、実際にテストで値やオブジェクトが期待通りであるかを確認するための関数です。expect関数によって生成されたオブジェクトに対して、マッチャー関数をチェーンして使用します。これによって、様々な条件で値を評価・比較できます。

公式ドキュメント

https://jestjs.io/ja/docs/expect#matchers

 

macher.test.tsを作成してください。

 

 matcher.test.ts
// toBe
it("数値のテスト", () => {
expect(4 + 4).toBe(8);
});
it("文字列テスト", () => {
expect("jest").toBe("jest");
});
it("真偽値テスト", () => {
expect(true).toBe(true);
});
//toEqual
it("配列の検証", () => {
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
expect(arr1).toEqual(arr2);
});
it("オブジェクトの検証", () => {
const obj1 = {
a: 2,
b: 1,
};
const obj2 = {
a: 2,
b: 1,
};
expect(obj1).toEqual(obj2);
});
//not
it("1+1は3ではない", () => {
expect(1 + 1).not.toBe(3);
});

 

toBeやtoEqualを使うことで比較をすることができ、逆を検証したい場合はnotをつけることで検証することができます。

 

例外処理のテスト

 

続いては例外処理のテストです。

exception.ts、exception.test.tsを作成してください。

 exceotion.ts
export class ExceptionError extends Error {}
export function divide(dividend: number, divisor: number) {
if (divisor === 0) throw new ExceptionError("0で割ることはできない");
return dividend / divisor;
}

Errorクラスを継承して、引数のdevisorが0であれば割ることができないので

例外を発生させています。

ではこの関数で例外が発生するのかをテストしましょう。

 

 exception.test.ts
import { divide, ExceptionError } from "./exception";
it("0で割るとエラーが発生する", () => {
expect(() => divide(10, 0)).toThrow(ExceptionError);
});

 

非同期関数のテスト

 

次は非同期関数のテストです。

使用する頻度は高いのでこちらもぜひ使えるようになりましょう。

async.test.ts、async.tsを作成してください。

 

 async.ts
export function delay(message: string, time: number) {
return new Promise((resolve, reject) => {
if (time >= 0) {
return setTimeout(() => resolve(message), time);
} else {
reject(new Error("timeは0以上で指定"));
}
});
}

 

もしtimeが0以上なら、setTimeout関数を用いて指定した時間だけ処理を遅延させ、遅延後にresolve関数が呼び出され、Promiseはmessageと共に正常に完了します。
time < 0: もしtimeが0未満なら、reject関数が呼び出され、Promiseは失敗として扱われます。このとき、新しいErrorオブジェクトが生成され、"timeは0以上で指定"というエラーメッセージと共に投げられます。

こちらのテストコードはいかとなります。

 

 async.test.ts
import { delay } from "./async";
it("delayが指定された時間の後にメッセージを返却", async () => {
const result = await delay("Hello Jest", 1000);
expect(result).toBe("Hello Jest");
});
it("マイナスの場合はエラーが発生する", async () => {
try {
await delay("Hello Jest", -1);
} catch (e: any) {
expect(e.message).toBe("timeは0以上で指定");
}
});

 

特に難しい部分はないですが、非同期関数のテストをする際は

async、awaitをつけてテストを実行する必要があります。

 

テストのグループ化

 

ここではテストのグループ化についてみていきましょう。

今まではitでテストコードを定義していたのですがこれだと見通しが悪く

各検証したいごとにテストのグループを作ることができます。

 

 group.test.ts
describe("配列のテスト", () => {
it("配列に要素を追加", () => {
const arr = [];
arr.push("ele");
expect(arr).toEqual(["ele"]);
});
it("配列の長さを検証", () => {
const arr = ["ele1", "ele2"];
expect(arr.length).toBe(2);
});
describe("配列検索", () => {
{
it("配列の要素を検索", () => {
const arr = ["ele1", "ele2"];
expect(arr.indexOf("ele2")).toBe(1);
});
}
});
});

 

describeで囲んであげるとテストに関しても一括で実行することができます。

 

テストの前後処理

次はテストの前後処理に関してです。

テストの規模が大きくなるとあらかじめデータを用意したりするケースが

あると思います。そういった際に最初にやる、最後にやるといった関数が

jestには用意されています。

 set_up.test.ts
// beforeEach: 各テスト(it)の前に実行される
// afterEach: 各テスト(it)の後に実行される
// beforeAll: グループ内のすべてのテストの前に1度だけ実行される
// afterAll: グループ内のすべてのテストの後に1度だけ実行される
describe("outer describe block", () => {
beforeEach(() => {
console.log("outer beforeEach");
});
afterEach(() => {
console.log("outer afterEach");
});
beforeAll(() => {
console.log("outer beforeAll");
});
afterAll(() => {
console.log("outer afterAll");
});
it("outer test 1", () => {
console.log("outer test 1");
});
it("outer test 2", () => {
console.log("outer test 2");
});
describe("inner describe block", () => {
beforeEach(() => {
console.log("inner beforeEach");
});
afterEach(() => {
console.log("inner afterEach");
});
beforeAll(() => {
console.log("inner beforeAll");
});
afterAll(() => {
console.log("inner afterAll");
});
it("inner test 1", () => {
console.log("inner test 1");
});
it("inner test 2", () => {
console.log("inner test 2");[st-pre myclass="" text="html" webicon=""]
 

 

パラメタライズテスト

 

最後にパラメタライズテストです。

パラメタライズテストとは引数を切り替えて同じテストを繰り返し実行するテストのことでコードの重複を防ぐのが目的となります。

一番最初にやったsum関数のテストだと以下のようになります。

 

 sum.test.ts
import { sum } from "./sum";
it.each`
a | b | expected
${1} | ${2} | ${3}
${1} | ${-2} | ${-1}
`("$aと$bを足すと$expectedになる", ({ a, b, expected }) => {
expect(sum(a, b)).toBe(expected);
});

 

この状態でテストをすると2回テストを一度に回すことができます。

このように書くことで記述量が少なくなり見通しが一気に良くなります。

 

 

まとめ

 

今回はjestの基本ということで簡単なテストを実施しました。

次回はmockとspyを使ったテストの記事となります。

こちらもCHECK

Jest アイキャッチ画像
今日から始める!:Jestでテスト(モックテスト)

続きを見る

 

ここまでみてくださりありがとうございました!

-jest, テストコード