概要
Cypress + TypeScript + Reactを導入してみたで作成したCypressテストをGitHubへのpushをトリガーにCircleCI上で動かしてみる。
事前準備
- Cypressのテスト(上記時にて作成済み)
- テスト対象のコード(上記時にて作成済み)
- CircleCIとの連携←ここではこれをやる
ちなみに対象のテストは、
https://google.com
へのリンクをクリックしHello World!
が検索できるかをチェックするものです。
CircleCIとの連携
https://circleci.com/ja/
こちらにアクセスして「ログイン」から「GitHubでログイン」
連携するRepositoryを選択した。(今回だと「cypress」)
.circleci/config.yml
がないので一番下を選択。
(自力でconfig.yml
作るので2番目で良かった気が。。。)
これでRepositoryとの連携は完了。
あとはconfig.yml
を作成すればCircleCIでCypressが実行できる(はず)。
config.yml作成
https://docs.cypress.io/guides/continuous-integration/circleci#Basic-Setup
Cypressの公式に親切にconfig.ymlの書き方があったので参考にします。
version: 2
jobs:
build:
docker:
- image: cypress/base:14.16.0
environment:
TERM: xterm
working_directory: ~/repo/e2e
steps:
- checkout:
path: ~/repo
- restore_cache:
keys:
- v1-deps-{{ checksum "package.json" }}
- run:
name: Install Dependencies
command: npm install
- run: ./node_modules/.bin/cypress install --force
- save_cache:
key: v1-deps-{{ checksum "package.json" }}
paths:
- node_modules
- ~/.cache
- run: npm run cy:cli
最後のコマンドnpm run cy:cli
の箇所で
the cypress npm package is installed but the cypress binary is missing.
とのエラーが出たので
https://stackoverflow.com/questions/62319657/how-to-resolve-the-cypress-npm-package-is-installed-but-the-cypress-binary-is
こちらを参考に
- run: ./node_modules/.bin/cypress install --force
を追加。
これでCircle CIは動くようになったのですが、肝心のReactを起動しないとテスト自体は失敗となる。
つまり、Circle CI上でReactを起動しながら、Cypressを実行する必要があるということ。
以下の二つが必要。(不細工な方法で実装した。)
- cypressフォルダからReactを起動すること
- Reactの起動を待ってからcypressを実行すること
cypressフォルダからReactを起動
cypressのpackage.json
に以下のような記述を追加。
"scripts": {
"cy:gui": "cypress open",
"cy:cli": "cypress run",
+ "React:start": "cd ../app && npm install && npm start"
},
無理やりディレクトリ移動して、Reactをインストールして、起動するというコマンドを追加しました。。。
不細工ですよね、、
Reactのローカルサーバーは起動中は返答が返ってこないのでbackgroundタスクにしました。
- run:
name: start React
command: npm run React:start
background: true
Reactの起動を待ってからcypressを実行
このままcypressテストを実行してもReact起動前に実行されて失敗となるので無理やりwaitを入れました。。
(こちらは別のやり方がありそう)
- run:
name: start React
command: npm run React:start
background: true
+ - run:
+ name: wait for React starts
+ command: sleep 60
- run:
name: e2e test
command: npm run cy:cli
ひとまず
これでひとまず
①GitHubへPush時にCircleCIが起動し
②ローカルのReactを
③cypressでテストする
ことができました。
version: 2
jobs:
build:
docker:
- image: cypress/base:14.16.0
environment:
TERM: xterm
working_directory: ~/repo/e2e
steps:
- checkout:
path: ~/repo
- restore_cache:
keys:
- v1-deps-{{ checksum "package.json" }}
- run:
name: Install Dependencies
command: npm install
- run: ./node_modules/.bin/cypress install --force
- save_cache:
key: v1-deps-{{ checksum "package.json" }}
paths:
- node_modules
- ~/.cache
- run: #ReactのInstallと起動
name: start React
command: npm run React:start
background: true
- run: #React起動までのwait
name: wait for React starts
command: sleep 60
- run:
name: e2e test
command: npm run cy:cli
"scripts": {
"cy:gui": "cypress open",
"cy:cli": "cypress run",
"React:start": "cd ../app && npm install && npm start"
},
CypressのDashboard管理
これでCircleCIからe2eテストを実施できるようになったのですが、
CircleCIからはテストの結果が詳しくわかりません。
ローカルのようにscreenshotや動画が残りません。(CI上には残るのですがすぐ消えてしまいます)
Dashboard
CypressはDashboardを用意してくれていて、
チームでプロジェクトを管理でき、無料プランでも過去500回のテスト結果を記録しておくことができます。
登録
https://dashboard.cypress.io/login
こちらからログインして登録することができます。
初回ログインのみ以下のような画面が出て、ユーザ登録が必要です。
スクリーンショット 2022-06-02 22.45.15
連携
projectを設定すると以下のような画面でprojectId
とrecord key
が表示される。(後で何度でも確認できます)
スクリーンショット 2022-06-02 22.47.16
それらを以下のように設定する。
{
"baseUrl": "http://localhost:3000",
"chromeWebSecurity": false,
+ "projectId": "******"
}
"scripts": {
"cy:gui": "cypress open",
- "cy:cli": "cypress run",
+ "cy:cli": "cypress run --record --key ********************",
"React:start": "cd ../app && npm install && npm start"
},
これだけでCircleCIからテストを実行するとDashBoardへ反映される。
サイドペインのLatest runs
から最新結果を確認できます。
また、GitHubのブランチやユーザ情報も自動で連携されているので、組織で利用できるようになっています。
(余談ですがAWSのCodeBuildは環境変数で渡さないといけないので大変でした)
Tips
CypressをCI上で実行した場合、動画が途中で終わってしまている場合があります。
https://github.com/cypress-io/cypress/issues/2370
I've kind of 'made it work' by adding a wait(1000) to the end of the test...
とか言っている人もいましたが、
最も簡単だと思う手法はテストの最後にスナップショットを撮ることです。
it("is serching hello world", () => {
cy.visit("/");
cy.get("[data-cy=correct]").click();
cy.url().should("contain", "google.com");
cy.get('[name="q"]').type("Hello,World").type("{enter}");
+ cy.screenshot();
});
これで動画は最後まで撮られますし、証跡が増えるのも良いことだと思います。
まとめ
- Circle CIのようなCI環境でもCypressは利用できる。
- Reactのローカルサーバをテストする場合は
package.json
のスクリプトをいじらないといけない。 - また、Reactを起動するまで、何らかの形でWaitを入れないといけない。
- CI上でテストする場合は、結果が残らないのでDashBoardを利用するのが吉
- ビデオが最後まで残らない場合は
cy.screenshot()
がおすすめ。