Nuxt on Dockerにて、Jest + Puppeteer でE2Eテスト環境をセットアップする
はじめに
テスト自動化したい...テスト駆動したい...E2Eで!!
Nuxt.jsをDockerで開発するにあたって、E2Eテスト環境を用意するまでの軌跡です。
テストフレームワークにはJest、ブラウザ操作にはPuppeteerを利用します。
手順
- DockerでNuxtアプリをつくる
- Dockerコンテナ内でブラウザを起動できるようにする
- Jest+PuppeteerでE2Eテストできるようにする
DockerでNuxtアプリをつくる
アプリの前提の意味で、こんな感じでNuxt on Dockerを作っています紹介です。
$ docker run -it -w /app -v `pwd`:/app node yarn create nuxt-app .
...
create-nuxt-app v3.5.2
✨ Generating Nuxt.js project in .
? Project name: app
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: -
? Linting tools: -
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: -
n)
? What is your GitHub username? -
? Version control system: None
yarn create nuxt-app
はターゲットのディレクトリ(今回はカレントディレクトリ)が空でないとエラーになるので要注意。初期設定は特に何も入れてません。
これでローカルにNuxtアプリのファイルが生成されるので、このアプリを動かすためのDockerfile
とdocker-compose.yml
をつくっていきます。
FROM node
ENV HOME=/app \
HOST=0.0.0.0
WORKDIR ${HOME}
COPY package.json ${HOME}
COPY yarn.lock ${HOME}
RUN yarn install
COPY . ${HOME}
EXPOSE 3000
CMD ["yarn", "dev"]
version: '3'
services:
app:
build: .
volumes:
- .:/app
ports:
- 3000:3000
これをビルドして起動してみます。
$ docker-compose build
$ docker-compose up
http://localhost:3000
にアクセスできていればOKです。
Dockerコンテナ内でブラウザを起動できるようにする
PuppeteerをDockerで使う場合、コンテナ内でブラウザを起動させられるようにする必要があります。puppeteerのトラブルシューティングにやり方が載っているので、それに合わせてDockerfileを更新します。
FROM node
ENV HOME=/app \
HOST=0.0.0.0
WORKDIR ${HOME}
+ RUN apt-get update \
+ && apt-get install -y wget gnupg \
+ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
+ && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
+ && apt-get update \
+ && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \
+ --no-install-recommends \
+ && rm -rf /var/lib/apt/lists/*
COPY package.json ${HOME}
COPY yarn.lock ${HOME}
RUN yarn install
COPY . ${HOME}
EXPOSE 3000
CMD ["yarn", "dev"]
これでHeadless Chromeを使ってPuppeteerでブラウザ操作をする環境ができます。
Jest+PuppeteerでE2Eテストできるようにする
最後にJest+Puppeteerの環境を整えていきます。
JestでPuppeteerを利用する手順は公式ドキュメントにも載っています。
まず、Jest、Puppeteer、そしてその2つの設定をいい感じにやってくれるjest-puppeteer
のライブラリをインストールします。jest-puppeteer
のおかげで、page
やbrowser
などのPuppeteerのAPIが特に意識することなくGlobalに扱えたりします。
$ docker-compose run --rm app yarn add --dev jest puppeteer jest-puppeteer
package.json
に追加されるのでコンテナを再ビルドしてコンテナイメージにも適用してきます。
$ docker-compose build
次にconfigファイルをつくります。まずはjestの設定から。
module.exports = {
verbose: true,
preset: 'jest-puppeteer'
}
これでjest-puppeteer
を活用できるようになります。次はjest-puppeteer
の設定をします。
module.exports = {
launch: {
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
},
server: {
command: 'yarn dev',
port: 3000,
launchTimeout: 50000
}
}
Headless chromeの設定と、サーバー(アプリの起動)についての設定をします。
最後に、package.json
でテスト実行コマンドを定義します。
{
...
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
- "generate": "nuxt generate"
+ "generate": "nuxt generate",
+ "test": "jest -i"
}
...
}
-i
オプションは--runInBand
オプションの省略形で、テストスイートを並列でテストしないオプションです。並列でテストしたときにそれぞれのテストスイートが影響しあってしまったのか、うまく行かないことがあったのでつけてます。
他のオプションはJestの公式ドキュメント参照です。
テストしてみる
では実際にテストが動作するか確認してみます。
まずはテストファイルを格納するディレクトリを作成し、テストファイルをつくりましょう。
Jestではデフォルトでtests
ディレクトリ以下のファイルを読み込みます(Jestの設定 · Jest)。
$ mkdir tests
describe('サンプルテストスイート', () => {
test('トップページでアプリ名が表示されていること', async () => {
await page.goto('http://localhost:3000')
await expect(await page.$eval('h1.title', el => el.innerText)).toBe("app")
})
})
トップページにアクセスして、「app」の文字列がh1.title
要素に表示されていることをチェックするテストです。
では、実行。
$ docker-compose run app yarn test
Creating test_app_run ... done
yarn run v1.22.5
$ jest -i tests/test.spec.js
PASS tests/test.spec.js
サンプルテストスイート
✓ トップページでアプリ名が表示されていること (344 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.371 s
Ran all test suites matching /tests\/test.spec.js/i.
Done in 19.83s.
パス!
コマンドの後ろにファイルパスを付けてもOKですし、つけない場合は対象のファイルを全部実行します。
テストの設定から動作確認まで、完了です!
結論
本記事では、Nuxt on DockerにおけるJest + PuppeteerのE2Eテスト環境のセットアップをしました。
Dockerコンテナ内でHeadless Chromeを操作できるようにするところがやや引っかかるかなと思いますが、公式のトラブルシューティングに載っていますし、jest-puppeteerの利用についてもJestの公式サイトで言及されているので、ソースをたどればそんなに難しくないかもです。
Discussion