Open1
Cypressの初期設定
CypressをTypescriptで初期設定するときの備忘録。
依存ライブラリをインストール
npm install -D cypress @testing-library/cypress env-cmd start-server-and-test
env-cmd
.env.local, .env.develop.loocal, .env.test.localを環境ごとに使い分けるためのライブラリ
start-server-and-test
e2eテスト実行には一度ビルドしてから立ち上げたサーバーとは別にテスト用のサーバーを立ち上げなければいけないのを簡単にしてくてるライブラリ
package.json
package.json
"scripts": {
"db:reset": "source scripts/reset-db.sh",
"build:test": "npm run db:reset && export NODE_ENV=\"test\" && next build",
"start:test": "export NODE_ENV=\"test\" && next start",
"cypress:open": "env-cmd -f .env.test.local cypress open",
"cypress:start": "start-server-and-test 'npm run start:test' 3000 'npm run cypress:open'",
"cypress:build": "npm run build:test && npm run cypress:start"
},
tsconfig.json
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}
e2e.ts
cypress/support/e2e.ts
import "@testing-library/cypress/add-commands";
cypress:build
を実行するとビルドが走り、ビルド終了後Cypressのブラウザが立ち上がる。
ダイナミックルートのテスト
ダイナミックルートのテストには以下の3種類がある
- ビルド時にすでに存在している静的ページ
- 動的ページでビルド時に存在しているページ(存在してないページへのエラーページ含む)
- これから追加する動的ページ
1. ビルド時にすでに存在している静的ページへのテスト
cypress/e2e/routes/routes.cy.ts
describe("routes.cy.ts", () => {
it("displays correct heading when navigating to shows route", () => {
cy.visit("/");
cy.findByRole("button", { name: /shows/i }).click();
cy.findByRole("heading", { name: /upcoming shows/i }).should("exist");
});
it("display correct heading when navigating to bands route", () => {
cy.visit("/");
cy.findByRole("button", { name: /bands/i }).click();
cy.findByRole("heading", { name: /Our Illustrious Performers/i }).should(
"exist"
);
});
});
export {};
一度ビルドした後はcypress:start
でテストを再実行できる。
2. 動的ページでビルド時に存在しているページ(エラーページ含む)
cypress/e2e/routes/routes.cy.ts
describe("routes.cy.ts", () => {
// ...省略
// リセット後、最初に存在するバンドページのタイトルをテスト
it("displays correct band name for band route that existed at build time", () => {
cy.task("db:reset").visit("bands/1");
cy.findByRole("heading", { name: /Shamrock Pete/i }).should("exist");
});
// リセット後、存在しないバンドページのエラー文をテスト
it("displays error message for band not in db", () => {
cy.task("db:reset").visit("/bands/12345");
cy.findByRole("heading", { name: /Error: band not found/i }).should(
"exist"
);
});
});
3. 動的ページを追加した場合
まずバンドを追加する関数をcypress.config.ts
へ追加しcy.task()
で使用できるようにする
cypress.config.ts
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
on("task", {
"db:reset": () => resetDB().then(() => null),
// 追加
addBand: (newBand) => addBand(newBand).then(() => null),
});
},
},
});
cypress/e2e/routes/routes.cy.ts
describe("routes.cy.ts", () => {
// ...省略
// リセット後、新しくバンドを追加後ページが生成されているかテスト
it("displays name for band that was not present at build time", () => {
const bandId = generateRandomId();
const newBand = generateNewBand(bandId);
cy.task("db:reset").task("addBand", newBand).visit(`bands/${bandId}`);
cy.findByRole("heading", { name: /Avalanche of Cheese/i }).should("exist");
}); });
});
デプロイ時のCIでJestとCypressを実行する
JestとCypressを実行する前に、まずはCypressをCI内で実行できるスクリプトを追加する。
ローカルでのテストではcypress:open
で実際のブラウザを立ち上げてテストしていたが、
CI内では起動させずにcypress run
コマンドを用いる
package.json
"scripts": {
// ...省略
"cypress:run": "start-server-and-test 'npm run start:test' 3000 'env-cmd -f .env.test.local cypress run'"
},
実行するとCypressがmp4
の映像ファイルをcypressディレクトリー内に自動生成するので.gitignoreに追記する
.gitignore
# cypress
cypress/videos
jestを実行
npm test
現状だとエラーがでる。なぜならプロジェクトディレクトリ全体のテストファイルを見てJestがテストを実行しようとし、Cypressのテストファイルも含めてテストを試みたので、Jestに『cyなんかないよ』と怒られる。なのでJestのテストするディレクトリを限定させる。
jest.config.js
// ...省略
const customJestConfig = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
// /__tests__/.*/.*を追加
testRegex: "/__tests__/.*/.*\\.test\\.[jt]sx?$",
/// ...省略
};