はじめに
ボタンの表示テストを作成する際、ボタンテキストと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で書いたボタンの表示テスト
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
を使用してまとめたボタンの表示テスト
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でまとめると、下記のように結果が出力されて確認もしやすくなりました。
it.each
で現在のインデックスを取得する方法
ngForで表示データ配列のインデックスをclass名に使用しているパターンがあり、必要になりました。
テストのタイトルにインデックスを追加し、タイトルから取得する方法で実現しました。以下手順です。
対応内容
it.each
のname
テストブロックのタイトルの末尾に:%#
を追加する。※:%#
はテストケースインデックスのパラメータ。
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が表示されているか」のように出力されます。