2019/11/18追記 日本語フォント表示用にDockerfileを修正しました。
はじめに : Cypressの紹介
Cypressは、無料で利用できるOSSのEnd-to-End(E2E)のテストツールです。以下のように自分のブラウザを利用してWeb UIテストを実行します。
以下のようなコードを元に、実際にブラウザで動かしながら、直感的にテストをすることができます。JavaScriptでテストコードを記述できるので、利用しているJSerも多いです。
describe('The Login Page', function () {
beforeEach(function () {
// reset and seed the database prior to every test
cy.exec('npm run db:reset && npm run db:seed')
// seed a user in the DB that we can control from our tests
// assuming it generates a random password for us
cy.request('POST', '/test/seed/user', { username: 'jane.lane' })
.its('body')
.as('currentUser')
})
it('sets auth cookie when logging in via form submission', function () {
// destructuring assignment of the this.currentUser object
const { username, password } = this.currentUser
cy.visit('/login')
cy.get('input[name=username]').type(username)
// {enter} causes the form to submit
cy.get('input[name=password]').type(`${password}{enter}`)
// we should be redirected to /dashboard
cy.url().should('include', '/dashboard')
// our auth cookie should be present
cy.getCookie('your-session-cookie').should('exist')
// UI should reflect this user being logged in
cy.get('h1').should('contain', 'jane.lane')
})
})
参考URL : https://docs.cypress.io/guides/getting-started/testing-your-app.html#Logging-in
E2EテストをCIサーバで実行する
ローカルブラウザでCypressを利用すると捗るのですが、CIへの組み込みがなかなか進まず、専用のマシンを用意しておこうか、と思ったところCypressの公式コンテナがあることに気が付きました。
そして少しのコードで専用マシンなどを用意せず、以下の構成でCIのフローに乗せることができました。
追加したファイルの紹介
追加したファイルは以下の3つです。
フロントエンド用のDockerfile
全環境共通のDockerfileです。環境変数で環境ごとの情報を管理します。
# ファイルをビルド
FROM node:13.1.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY . /app
RUN npm install --silent
RUN npm run build
# nginxコンテナにビルドしたファイルをコピー
FROM nginx:1.16.0-alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Cypress用Dockerfile
FROM cypress/base:10
# 日本語フォント表示用にnoto-cjkを追加
RUN apt-get install --no-install-recommends -y fonts-noto fonts-noto-cjk
WORKDIR /app
COPY package.json .
COPY package-lock.json .
ENV CI=1
RUN npm ci
RUN npx cypress verify
docker-compose.yml
version: '3'
services:
web:
image: frontend:latest
ports:
- "8080:80"
e2e:
build:
context: .
dockerfile: ./Dockerfile
command: npx cypress run
depends_on:
- web
environment:
- CYPRESS_baseUrl=http://web
- CYPRESS_browser=chrome
- CYPRESS_screenshotsFolder=/results/screenshots
- CYPRESS_videosFolder=/results/videos
volumes:
- ./cypress:/app/cypress
- ./cypress.json:/app/cypress.json
- ./results:/results
docker-compose.yamlの解説
CYPRESS_xxxx の環境変数部分でConfigurationを設定しています。CYPRESS_browserという変数もありますが、現在選べるのは、chrome/chromium/canaryのいずれかです。それ以外のブラウザはサポートされません。
ローカルで docker-compose up
を実行すれば、マウントされた results/videos
以下にスクリーンショットと、動作時の録画データが入ります。
※ /results/screenshots に出力される録画データ。 (mp4で出力されたものをgifに変換)
CI時、テストが失敗したら終了したい場合、以下のコマンドを利用します。
docker-compose up --abort-on-container-exit --exit-code-from e2e
CI上で試したいときは、Slackなどにファイルを添付して渡すと、原因究明がはかどります。
最後に : 実際の利用シーン
Google Chromeがインストールされていない環境でも、簡単にテストが行えるようになりました。
新しくテストコードを書く時は、実際にブラウザで操作しながら書く方が楽なので、ローカルでも動くようにしています。
以下のようなフローでテストを追加しているという一例です。
-
npx cypress open
を実行して、ローカルブラウザでテストを書く - docker-compose upを実行すると、コンテナ内でテストが自動実行される
リクエストが多ければGitHubにひな形を作成するので、興味がある方はリクエストをください。