Cypress@E2Eテスト¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. 事前処理¶
cypress.config.ts¶
// テストデータの事前セットを読み込む
import seed from "fixtures/seed.json";
setupNodeEvents: (on, config) => {
on("task", {
dbSeed: async () => {
const { user1, user2 } = seed.user;
// テストデータをデータベースに投入する
await prisma.user.create({
data: {
id: user1.id,
email: user1.email,
name: user1.name,
},
});
// テストデータをデータベースに投入する
await prisma.user.create({
data: {
id: user2.id,
email: user2.email,
name: user2.name,
},
});
},
...
});
}
fixtures/foo/data.json¶
テストに使用する初期データ(例;DB値、リクエストパラメーターなど)を設定する。
fixtures/expected/foo.jsonファイル(期待値データ)の値と同じになる可能性がある。
# 初期データ
{
"users":
{
"user1":
{
"email": "user1@gmail.com",
"name": "testUser1",
"password": "password",
},
"user2":
{
"email": "user2@gmail.com",
"name": "testUser2",
"password": "password",
},
...,
},
}
fixtures/expected/foo.json¶
テストに使用する期待値データを設定する。
fixtures/foo/data.jsonファイル(初期データ)の値と同じになる可能性がある。
{
"users":
{
"user1":
{
"email": "user1@gmail.com",
"name": "testUser1",
"password": "password",
},
"user2":
{
"email": "user2@gmail.com",
"name": "testUser2",
"password": "password",
},
...,
},
}
ヘルパー¶
Cypress.Commands.add("login", () => {
// fixture/users/data.jsonファイルを使用する
cy.fixture("users/data").then((seed) => {
cy.visit("/");
// 待機することで、Cypressがハイドレーション前に画面をロードし、エラーが発生することを避ける
cy.wait(1000);
// アサーションを実行し、実際値と期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/signup");
// data-cy="signin" 要素をクリックする
cy.get("[data-cy=signin]").click();
// URLの実際値を取得し、期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/signin");
// 初期データをフォームに入力する
// データベースに投入したユーザー情報を使用する
cy.get("[data-cy=email]").type(seed.user.user1.email);
cy.get("[data-cy=password]").type(seed.user.user1.password);
// data-cy="submit" 要素をクリックし、送信する
cy.get("[data-cy=submit]").click();
// URLの実際値を取得し、期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/");
// data-cy="profileEmail" 要素をクリックする
cy.get("[data-cy=profile]").click();
// data-cy="profileName" 要素から実際値を取得し、実際値と期待値と一致するかを検証する
cy.get("[data-cy=profileName]").should("have.text", seed.user.user1.name);
// data-cy="profileEmail" 要素から実際値を取得し、実際値と期待値と一致するかを検証する
cy.get("[data-cy=profileEmail]").should("have.text", seed.user.user1.email);
});
});
02. テストスイート¶
テストスイートはテストケース (テスト関数) に分類できる。
// テストスイート
describe("ユーザーの一覧を表示するテスト", () => {
// 各テストケースに共通する処理をテスト
beforeEach(() => {
// 基本的な初期データをデータベースに投入する
cy.exec("yarn ts-node --require tsconfig-paths/register prisma/seed.ts");
// cypress.config.ts ファイルで定義したdbSeed関数を実行する
cy.task("dbSeed");
// テスト用の初期データをデータベースに投入する
cy.exec(
'yarn ts-node --require tsconfig-paths/register "cypress/seed/users.ts"',
);
// エラーハンドリングをイベントリスナーとして登録する
cy.on("uncaught:exception", (error) => {
console.log(`${error.message}`);
return false;
});
// ヘルパーを使用してログインする
cy.login();
// data-cy="users" 要素をクリックする
cy.get("[data-cy=users]").click();
});
// 正常系テストケース
it("ユーザーの一覧を表示できる", () => {
// テストケース固有のテストデータ
// fixture/expected/users.jsonファイルを使用する
cy.fixture("users/data").then((expected) => {
// URLの実際値を取得し、期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/users");
// data-cy="userName" 要素から実際値を取得し、実際値と期待値と一致するかを検証する
cy.get("[data-cy=userName]")
.its(0)
.should("contain.text", expected.user1.name);
// data-cy="userEmail" 要素から実際値を取得し、実際値と期待値と一致するかを検証する
cy.get("[data-cy=userEmail]")
.its(0)
.should("contain.text", expected.user1.email);
});
});
// 正常系テストケース
it("ページネーションを実行できる", () => {
// 汎用的なテストデータ
cy.fixture("dbSeed").then((expected) => {
// テストケース固有のテストデータ
// fixture/expected/users.jsonファイルを使用する
cy.fixture("users/data").then((expected) => {
const {user2} = expected.user;
cy.wait(1000);
cy.get("[data-cy=next]").click();
// URLの実際値を取得し、期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/users/?page=2");
// data-cy="previous" 要素から実際値を取得し、期待値と一致するかを検証する
cy.get("[data-cy=userName]").its(0).should("contain.text", user2.name);
// data-cy="previous" 要素をクリックする
cy.get("[data-cy=previous]").click();
// アサーションを実行し、実際値と期待値と一致するかを検証する
cy.url().should("eq", Cypress.config().baseUrl + "/users/?page=1");
// data-cy="userName" 要素から実際値を取得し、期待値と一致するかを検証する
cy.get("[data-cy=userName]")
.its(0)
.should("contain.text", expected.user1.name);
});
});
});
});