Jestでsetup/teardownとparametrized testをやってみる

2019.10.17

CX事業本部の夏目です。

案件でも使っているのもあって、Lambdaの言語としてPythonを使用することが多いのですが、型が欲しいなぁと思ったのでTypeScriptの勉強を少しずつしています。

Pythonでの単体テストではpytestを使用して、setup/teadownやParametrized Testを多用しています。

TypeScriptの単体テストでよく使われるJestでそれらを使うにはどうすればいいのか調べてみました。

setup/teadown

シンプルに書いてみる

コード

beforeAll(() => {
  console.log("before all");
});

afterAll(() => {
  console.log("after all");
});

beforeEach(() => {
  console.log("before each");
});

afterEach(() => {
  console.log("after each");
});

test("case 1", () => {
  console.log("case 1");
});

test("case 2", () => {
  console.log("case 2");
});

実行結果

 PASS  test/setup_teardown.test.ts
  ● Console

    console.log test/setup_teardown.test.ts:2
      before all
    console.log test/setup_teardown.test.ts:10
      before each
    console.log test/setup_teardown.test.ts:18
      case 1
    console.log test/setup_teardown.test.ts:14
      after each
    console.log test/setup_teardown.test.ts:10
      before each
    console.log test/setup_teardown.test.ts:22
      case 2
    console.log test/setup_teardown.test.ts:14
      after each
    console.log test/setup_teardown.test.ts:6
      after all

(before|after)All はテストの実行前後で一度だけ、(before|after)Eachはテストの実行前後で毎回実行されるようです。

グループ化してみる

コード

beforeEach(() => {
  console.log("outer - before each");
});

afterEach(() => {
  console.log("outer - after each");
});

describe("group 1", () => {
  beforeEach(() => {
    console.log("group 1 - before each");
  });
  afterEach(() => {
    console.log("group 1 - after each")
  });

  test("case 1", () => {
    console.log("group 1 - case 1");
  });

  test("case 2", () => {
    console.log("group 1 - case 2");
  });
});

describe("group 2", () => {
  beforeEach(() => {
    console.log("group 2 - before each");
  });
  afterEach(() => {
    console.log("group 2 - after each")
  });

  test("case 1", () => {
    console.log("group 2 - case 1");
  });

  test("case 2", () => {
    console.log("group 2 - case 2");
  });
});

実行結果

PASS  test/grouped_setup.test.ts
  ● Console

    console.log test/grouped_setup.test.ts:2
      outer - before each
    console.log test/grouped_setup.test.ts:11
      group 1 - before each
    console.log test/grouped_setup.test.ts:18
      group 1 - case 1
    console.log test/grouped_setup.test.ts:14
      group 1 - after each
    console.log test/grouped_setup.test.ts:6
      outer - after each
    console.log test/grouped_setup.test.ts:2
      outer - before each
    console.log test/grouped_setup.test.ts:11
      group 1 - before each
    console.log test/grouped_setup.test.ts:22
      group 1 - case 2
    console.log test/grouped_setup.test.ts:14
      group 1 - after each
    console.log test/grouped_setup.test.ts:6
      outer - after each
    console.log test/grouped_setup.test.ts:2
      outer - before each
    console.log test/grouped_setup.test.ts:28
      group 2 - before each
    console.log test/grouped_setup.test.ts:35
      group 2 - case 1
    console.log test/grouped_setup.test.ts:31
      group 2 - after each
    console.log test/grouped_setup.test.ts:6
      outer - after each
    console.log test/grouped_setup.test.ts:2
      outer - before each
    console.log test/grouped_setup.test.ts:28
      group 2 - before each
    console.log test/grouped_setup.test.ts:39
      group 2 - case 2
    console.log test/grouped_setup.test.ts:31
      group 2 - after each
    console.log test/grouped_setup.test.ts:6
      outer - after each

describeの外に書いた(before|after)Eachは毎回、describeの中で書いた(before|after)Eachdescribeの中のテストでのみ毎回実行されています。

describeでくくるとsetup/teardownもグループ化できるようです。

Parametrized Test

array

コード

test.each([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
])("parametrized test (array)", (a, b, c) => {
  console.log("test.each", a, b, c);
});

describe.each([
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
])("", (a, b, c) => {
  test("case", () => {
    console.log("describe.each", a, b, c);
  });
});

実行結果

 PASS  test/parametrize_array.test.ts
  ● Console

    console.log test/parametrize_array.test.ts:6
      test.each 1 2 3
    console.log test/parametrize_array.test.ts:6
      test.each 4 5 6
    console.log test/parametrize_array.test.ts:6
      test.each 7 8 9
    console.log test/parametrize_array.test.ts:15
      describe.each 1 2 3
    console.log test/parametrize_array.test.ts:15
      describe.each 4 5 6
    console.log test/parametrize_array.test.ts:15
      describe.each 7 8 9

(test|describe).eachに配列in配列でデータを渡すだけですね。

table

コード

test.each`
a    | b    | c
${1} | ${2} | ${3}
${4} | ${5} | ${6}
${7} | ${8} | ${9}
`("case", ({a, b, c}) => {
  console.log("test.each", a, b, c);
});

describe.each`
a    | b    | c
${1} | ${2} | ${3}
${4} | ${5} | ${6}
${7} | ${8} | ${9}
`("describe", ({a, b, c}) => {
  test("case", () => {
    console.log("describe.each", a, b, c);
  });
});

実行結果

 PASS  test/parametrize_table.test.ts
  ● Console

    console.log test/parametrize_table.test.ts:7
      test.each 1 2 3
    console.log test/parametrize_table.test.ts:7
      test.each 4 5 6
    console.log test/parametrize_table.test.ts:7
      test.each 7 8 9
    console.log test/parametrize_table.test.ts:17
      describe.each 1 2 3
    console.log test/parametrize_table.test.ts:17
      describe.each 4 5 6
    console.log test/parametrize_table.test.ts:17
      describe.each 7 8 9

なんでこんな書き方できるのかわかりませんが、こんな書き方もできます。

まとめ

Jestでsetup/teardownやParametrized Testを行う方法について調べてみました。

TypeScriptのテストの一助になれば幸いです。