1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jest入門1 Matchersを組んで出力結果をテスト

Last updated at Posted at 2024-03-04

テストの自動化をJavaScriptから行う方法を調査していたところ、Jestというテストフレームワークに出会いました。
試しに使用してみたところ、期待通りに動作したので、今回ご紹介したいと思います。

公式:https://jestjs.io/ja/docs/getting-started
インストール方法は以下
・npm
・Yarn
・pnpm

チュートリアルファイルを作成し、コードを実行したところ、以下の結果となりました。

試験内容: 1 + 2 は 3 という結果が返りますか?

training@1.0.0 test
jest

jest-haste-map: Haste module naming collision: countdown
The following files share their name; please adjust your hasteImpl:
* \chap17\countdown\package.json
* \chap17\practice\sec_end3\package.json

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

----------|---------|----------|---------|---------|-------------------

File % Stmts % Branch % Funcs % Lines Uncovered Line #s
All files 100 100 100 100
sum.js 100 100 100 100
---------- --------- ---------- --------- --------- -------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.067 s
Ran all test suites.

試験にパスできたので、期待値通りですね。

Jestは英語のフレームワークですが、一部日本語にも対応しています。
読みやすさ向上のために日本語を活用するのも良いでしょう。

Jestでは様々な値をテストすることができます。
値をチェックする「Matchers」と呼ばれる機能があり、
今回は試験的にMatchersを作成しました。

・describe いくつかの関連するテストを1つのブロックとしてまとめるためのメソッド。

describe("テストブロックの説明(日本語が使えます)", () => {
//テストケースを書く//
});

test(it)実際のテストコードを記述するためのメソッド。describeメソッドの中に関連するテストケースを記述する。testの代わりにitも可。
describe("テストブロックの説明", () => {
test("テストケース1の説明", () => {
//テストコードを記述//
});
test("テストケース2の説明", () => {
//テストコードを記述//
});
});

・expect テスト結果を評価するためのメソッド。マッチャ関数とともに使用される。

test("Xの値がAになることの確認", () => {
expect(X).toBe(A)
});

//1+2が3となることが期待値
test('1+2が3になるかをテストする', () => {
expect(1 + 2).toBe(3);
});
//toBeというのががMatchersとなる

・正常
describe('たし算', () => {
it('1たす3は4です', () => {
const result = 1 + 3;
expect(result).toBe(4);
});
});
・誤ったもの
describe('ひき算', () => {
it('2ひく1は1です', () => {
const result = 2 - 11;
expect(result).toBe(2);
});
});

・スキップ
describe('わり算', () => {
it.skip('3わる3は1です', () => {
const result = 3 / 3;
expect(result).toBe(1);
});
});


・変数も扱える
describe('たし算', () => {
describe('変数を使います', () => {
let number_a = 100;
let number_b = 100;
// このテストファイルのすべてのテストが実行される前1回だけ実行される
beforeAll(() => {
number_a = number_a + 50;
});
// このテストファイルのすべてのテストが実行された後1回だけ実行される
afterAll(() => {
number_a = 100;
});
// このテストファイルにあるテスト(it)が実行される前に毎回実行される
beforeEach(() => {
number_b = number_b + 50;
});
// このテストファイルにあるテスト(it)が実行された後に毎回実行される
afterEach(() => {
number_b = number_b - 50;
});
it('100に50をたすと150です', () => {
expect(number_a).toBe(150);
});
it('100に50をたすと150です', () => {
expect(number_b).toBe(150);
});
});
});


・.not 検証を否定する
test('2+2が5にならないことをテストする', () => {
expect(2 + 2).not.toBe(5);
});


・toBeNull は null のみ一致します
test('nullになることをテストする', () => {
expect(null).toBeNull();
expect(null).not.toBeNull();//nullにならないこと
});


・toBeUndefined は undefined のみ一致します
test('undefinedになることをテストする', () => {
expect(undefined).toBeUndefined();//undefined
expect(undefined).not.toBeDefined();//undefinedではない
});


・toBeDefined は toBeUndefined の反対です
test('undefinedにならないことをテストする', () => {
expect(1).toBeUndefined();//undefined
expect(1).not.toBeDefined();//undefinedではない
});

//toBeTruthy は if ステートメントが真であるとみなすものに一致します
test('trueになることをテストする', () => {
expect(true).toBeTruthy();
expect(1).toBeTruthy();
expect('aaa').toBeTruthy();
});


・toBeFalsy は if ステートメントが偽であるとみなすものに一致します

test('falseになることをテストする', () => {
expect(false).toBeFalsy();
expect(undefined).toBeFalsy();
expect(null).toBeFalsy();
expect(0).toBeFalsy();
});


・toBeGreaterThan(number)数値の比較する
test('2+2の計算', () => {
const value = 2 + 2;
expect(value).toBeGreaterThan(3);//numberより大きくなることを検証します。〇〇より大きいなので同じ値を含みません。
expect(value).toBeGreaterThanOrEqual(3.5);//number以上になることを検証します。〇〇以上なので同じ値を含みます。
expect(value).toBeLessThan(5);//numberより小さくなることを検証します。〇〇より小さいなので同じ値を含みません。
expect(value).toBeLessThanOrEqual(4.5);//number以下になることを検証します。〇〇以下なので同じ値を含みます。
expect(value).toBe(4);// toBeは数値として同じ値であるか
expect(value).toEqual(4);//toEqualはとして同じ値であるか
});


・丸め誤差が原因で期待通りにならない場合は
test('浮動小数点数の加算', () => {
const value = 0.1 + 0.2;
expect(value).toBe(0.3);//このように書くと、丸め込み誤差が原因で期待通りに動作しない
expect(value).toBeCloseTo(0.3); // これならば正しく動く
});


・文字列に対して正規表現でマッチするかを検証します。
test('Iはありますか?', () => {
expect('team').not.toMatch(/I/);
});
test('stopは含まれているか', () => {
expect('Christoph').toMatch(/stop/);
});


・配列と反復可能なオブジェクト、 配列やオブジェクトの中にitemが含まれているかを検証するために使います。
const noodles = [
'そば',
'うどん',
'ラーメン',
'そうめん',
'にゅうめん',
];
test('そばが含まれているかをテストする', () => {
expect(noodles).toContain('そば');
expect(new Set(noodles)).toContain('そば');
});


・ある関数が呼び出し時に例外を投げることをテストする
function compileAndroidCode() {
throw new Error('例外が発生しました。');
}

test('例外が発生したかをテストする', () => {
expect(() => compileAndroidCode()).toThrow();
expect(() => compileAndroidCode()).toThrow(Error);
expect(() => compileAndroidCode()).toThrow('例外が発生しました');

});


上記のテストコードの結果は以下のようになりました

FAIL ./index.test.js
√ 2+2が5にならないことをテストする
× nullになることをテストする (1 ms)
√ undefinedになることをテストする (1 ms)
× undefinedにならないことをテストする (1 ms)
√ trueになることをテストする
√ falseになることをテストする (1 ms)
√ 2+2の計算 (2 ms)
× 浮動小数点数の加算 (1 ms)
√ Iはありますか? (1 ms)
√ stopは含まれているか (1 ms)
√ そばが含まれているかをテストする (1 ms)
√ 例外が発生したかをテストする (4 ms)
たし算
√ 1たす3は4です (3 ms)
変数を使います
√ 100に50をたすと150です (1 ms)
√ 100に50をたすと150です
ひき算
× 2ひく1は1です (3 ms)
わり算
○ skipped 3わる3は1です

● ひき算 › 2ひく1は1です

expect(received).toBe(expected) // Object.is equality

Expected: 2
Received: -9

  44 |    it('2ひく1は1です', () => {
  45 |      const result = 2 - 11;
> 46 |      expect(result).toBe(2);
     |                     ^
  47 |    });
  48 |  });
  49 |

  at Object.toBe (index.test.js:46:21)

● nullになることをテストする

expect(received).not.toBeNull()

Received: null

   95 |  test('nullになることをテストする', () => {
   96 |    expect(null).toBeNull();
>  97 |    expect(null).not.toBeNull();//nullにならないこと
      |                     ^
   98 |  });
   99 |
  100 |  //toBeUndefined は undefined のみ一致します

  at Object.toBeNull (index.test.js:97:21)

● undefinedにならないことをテストする

expect(received).toBeUndefined()

Received: 1

  106 |  //toBeDefined は toBeUndefined の反対です
  107 |  test('undefinedにならないことをテストする', () => {
> 108 |    expect(1).toBeUndefined();//undefined
      |              ^
  109 |    expect(1).not.toBeDefined();//undefinedではない
  110 |  });
  111 |

  at Object.toBeUndefined (index.test.js:108:14)

● 浮動小数点数の加算

expect(received).toBe(expected) // Object.is equality

Expected: 0.3
Received: 0.30000000000000004

  140 | test('浮動小数点数の加算', () => {
  141 |    const value = 0.1 + 0.2;
> 142 |    expect(value).toBe(0.3);//このように書くと、丸め込み誤差が原因で期待通りに動作しない
      |                  ^
  143 |    expect(value).toBeCloseTo(0.3); // これならば正しく動く
  144 |  });
  145 |

  at Object.toBe (index.test.js:142:18)

Test Suites: 1 failed, 1 total
Tests: 4 failed, 1 skipped, 12 passed, 17 total
Snapshots: 0 total
Time: 0.889 s, estimated 1 s
Ran all test suites matching /index.test.js/i

日本語が使えることにより、成功・失敗の判別が非常に分かりやすくなりました。
Jestでは日本語が使えるので、積極的に活用していきたいです。
上記のMatchersだけでなく、公式ドキュメントには完全なリストが掲載されています。
https://jestjs.io/ja/docs/expect

現在は単に出力をテストしているだけですが、Jestには豊富な拡張機能が用意されているので、結合テストまでできるように挑戦したいですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?