0
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】it.eachの活用とit.eachで現在のインデックスを取得する方法について

Posted at

はじめに

ボタンの表示テストを作成する際、ボタンテキストとclassが違うだけの類似テストをコピペしていたのですが、もっと良い方法ないかなと調査した結果、現状使用しているit.eachについての備忘録です。

環境

"@types/jest": "^29.0.3",
"jest": "^29.0.3",
"jest-preset-angular": "^13.0.1",

test.each(table)(name, fn, timeout)について

次のエイリアスでも使用可能です: it.each(table)(name, fn) と it.each`table`(name, fn)
異なるテストデータで同じ内容のテストスイートを行う場合は、test.eachを使用します。 test.eachによりテストを1回だけ記述し、データを渡すことができます。

jestjs.ioからの引用です。

網羅したいテスト・まとめたいテストはit.eachを使用する。

異なるデータで同じ内容のテストを行う場合などit.eachでまとめると確認がしやすくなります。
次の例はテスト数が2件なのでメリットを感じづらいですが、it.eachを使用することで、同じ内容のテストであることが分かりやすく、新たにボタンを追加する場合の行数も減らせるので可読性が上がりそうです。

it.eachを使用せず、itで書いたボタンの表示テスト

sample.spec.ts
it("新しい予約ボタンが表示されているか", () => {
  let button = fixture.nativeElement.querySelector(".create-reserv-button");
  expect(button).toBeTruthy();
  expect(button.textContent).toContain("新しい予約ボタン");
});
it("検索ボタンが表示されているか", () => {
  let button = fixture.nativeElement.querySelector(".search-button");
  expect(button).toBeTruthy();
  expect(button.textContent).toContain("検索ボタン");
});

it.eachを使用してまとめたボタンの表示テスト

sample.spec.ts
describe("ボタン表示のテスト", () => {
  it.each([
    ["新しい予約ボタン", ".create-reserv-button"],
    ["検索ボタン", ".search-button"],
  ])("%sボタンが表示されているか", (labelTxt, btnSelector) => {
    let button = fixture.nativeElement.querySelector(btnSelector);
    expect(button).toBeTruthy();
    expect(button.textContent).toContain(labelTxt);
  });
});

describeでまとめると、下記のように結果が出力されて確認もしやすくなりました。

image.png

it.eachで現在のインデックスを取得する方法

ngForで表示データ配列のインデックスをclass名に使用しているパターンがあり、必要になりました。

テストのタイトルにインデックスを追加し、タイトルから取得する方法で実現しました。以下手順です。

対応内容

it.eachnameテストブロックのタイトルの末尾に:%#を追加する。※:%#はテストケースインデックスのパラメータ。

it.each(["test", ".test-wrapper"])("%sの要素が表示されているか :%#",

expect.getState().currentTestName:現在のテストタイトルを取得する。
testName.lastIndexOf(":")+1:タイトルの末尾:以降をインデックスとして取得する。

it.each(["test", ".test-wrapper"])("%sの要素が表示されているか :%#",(lblText, selector) => {
  const testName = expect.getState().currentTestName;
  const testIndexPos = testName.lastIndexOf(":")+1;
  const currentIdx = parseInt( testName.substring(testIndexPos ));
  let element = fixture.nativeElement.querySelector(`${selector}_${currentIdx}`) as HTMLDivElement;
  expect(element).toBeTruthy();
});

上記でインデックスは取得できました。
自分はテストファイルを跨いで共通使用できるように、関数化・ヘルパーファイルを作成して追加しました。

_global.getCurrentTestIndex = function () {
    const testName = _global.expect.getState().currentTestName;
    const testIndexPos = testName.lastIndexOf(":") + 1;
    const currentTestIndex = parseInt(testName.substring(testIndexPos))
    return currentTestIndex;
};

共通処理について:【Jest】テストファイルを跨いで共通使用する関数を管理する方法について #TypeScript - Qiita

tableを連想配列の配列で受け渡すこともできる。

test.each(table)(name, fn, timeout)tableはfnに引数として渡される配列の配列です。
これを連想配列で下記のように受け渡すことも可能です。

it.each([
    {
        testTitle: "テスト要素1",
        selector: ".test-elem1",
        val: "テスト1"
    },
    {
        testTitle: "テスト要素2",
        selector: ".test-elem2",
        val: "テスト2"
    },
])("$testTitleが表示されているか", fakeAsync(({ testTitle, selector, val }) => {
    let elem = fixture.nativeElement.querySelector(selector) as HTMLDivElement;
    expect(elem).toBeTruthy();
    expect(elem.textContent).toBe(val);
}));

テストタイトルは「テスト要素1が表示されているか」のように出力されます。

参考

0
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
0
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?