Table of Contents
はじめに
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 nodeENV HOME=/app \ HOST=0.0.0.0
WORKDIR ${HOME}
COPY package.json ${HOME}COPY yarn.lock ${HOME}RUN yarn install
COPY . ${HOME}EXPOSE 3000CMD ["yarn", "dev"]
version: '3'
services: app: build: . volumes: - .:/app ports: - 3000:3000
これをビルドして起動してみます。
docker-compose builddocker-compose up
http://localhost:3000
にアクセスできていればOKです。
Dockerコンテナ内でブラウザを起動できるようにする
PuppeteerをDockerで使う場合、コンテナ内でブラウザを起動させられるようにする必要があります。 Puppeteerのトラブルシューティング にやり方が載っているので、それに合わせてDockerfileを更新します。
FROM nodeENV 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 3000CMD ["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ではデフォルトでtests
ディレクトリ次のファイルを読み込みます。( 参考 )
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 testCreating test_app_run ... doneyarn run v1.22.5$ jest -i tests/test.spec.js PASS tests/test.spec.js サンプルテストスイート ✓ トップページでアプリ名が表示されていること (344 ms)
Test Suites: 1 passed, 1 totalTests: 1 passed, 1 totalSnapshots: 0 totalTime: 1.371 sRan 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の公式サイトで言及されています。ソースをたどればそんなに難しくないかもです。
サポートもお待ちしております!