0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Dockerでjavascriptの自動テスト環境を作る

Last updated at Posted at 2023-10-11

概要

プログラミングすることがめっきり少なくなったのですが、プログラミングはとても好きで、図書館でこちらの本を借りてきました。

フロントエンド開発のためのテスト入門 - Amazon | Kindle

UNITテストの自動化がわかりやすく、とても勉強になりました。

そしてDockerコンテナでテスト環境を配れたりしたら素敵だなと思って、javascriptのUNITテスト環境をDockerコンテナで作ってみました。

UNITテストのツールは jest(https://jestjs.io/ja/) を導入しています。

最終的にできること

Dockerコンテナ内にjavascriptアプリのunitテスト(jest)の環境を作ります。

以下は、そのコンテナ内でのUNITテストの実行がPASSした結果です。

root@edf58454f2f8:/usr/src/app# npm test

> docker_web_app@1.0.0 test
> jest

 PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.208 s
Ran all test suites.

前提

PCにDockerDesktopがインストールされていること。
node.js version 20をベースにしています。

3種類のnodejsのDockerイメージ

node.jsは大きく分けて以下3種類のDockerイメージがあります。
今回は、以下のとおりデファクトイメージのnode:<version>を使うとよいです。

node:<version>
これがデファクトイメージです。自分のニーズが何かわからない場合は、おそらくこれを使用するとよいでしょう。これは、使い捨てコンテナ (ソース コードをマウントし、コンテナを起動してアプリを起動する) としても、他のイメージを構築するためのベースとしても使用できるように設計されています。

node: <version> -alpine
このイメージは、公式イメージで入手できる人気のあるAlpine Linux プロジェクトに基づいています。>Alpine Linux は、ほとんどのディストリビューション ベース イメージ (約 5MB) よりもはるかに小さいため、一般的にイメージがよりスリムになります。alpine

node:<version>-slim
このイメージには、デフォルト タグに含まれる共通パッケージは含まれておらず、実行に必要な最小限のパッケージのみが含まれていますnode。イメージのみがデプロイされ、スペースの制約がある環境で作業している場合を除きnode、このリポジトリのデフォルトのイメージを使用することを強くお勧めします。
(引用元:https://hub.docker.com/_/node)

こちらにもnodeイメージの選定について同じ意見がありました。

近年、slimイメージは150MBまでサイズが小さくなっており、かつさまざまな状況で最もよく動作するようになっています。 Alpineはとても小さなコンテナディストリビューションで、最小のnodeイメージはたった75MBです。しかし、パッケージマネージャをaptからapkに取り替えたり、 特別な状況 に対応したり、 セキュリティスキャンの制限 を回避したりする努力をするくらいなら、ほとんどの場合node:alpineをお勧めしません。
(引用元:https://www.creationline.com/tech-blog/29422)

完成時のディレクトリ構成

適宜どこかにプロジェクトフォルダ(YOUR-PROJECT-FOLDER)を作成して、以降で以下のファイルを作っていきます。

  YOUR-PROJECT-FOLDER
 ├package.json -----npmでパッケージを管理するために使われる構成ファイル
 ├server.js -----Webアプリ
 ├Dockerfile    -----Dockerfile
 ├.dockerignore   -----dockerイメージに含めないファイル
 ├sum.js   -----サンプルコード
 └sum.test.js   -----サンプルコード(sum.js)の単体テスト用のコード

各ファイル

package.json

https://nodejs.org/ja/docs/guides/nodejs-docker-webapp にあるpackage.jsonを編集し、"scripts"に"jest"を追加しています。

package.json
{
    "name": "docker_web_app",
    "version": "1.0.0",
    "description": "Node.js + jest on Docker",
    "author": "First Last <first.last@example.com>",
    "main": "server.js",
    "scripts": {
        "start": "node server.js",
        "test": "jest"
    },
    "dependencies": {
        "express": "^4.16.1"
    },
    "devDependencies": {
        "jest": "^29.7.0"
    }
}

Dockerfile

Dockerfileもhttps://nodejs.org/ja/docs/guides/nodejs-docker-webapp にあるDockerfileを編集して、

npm install --save-dev jest

追加すると、全体は次のような定義になります。

Dockerfile
#FROM node:12
FROM node:20
# アプリケーションディレクトリを作成する
WORKDIR /usr/src/app
# アプリケーションの依存関係をインストールする
# ワイルドカードを使用して、package.json と package-lock.json の両方が確実にコピーされるようにします。
# 可能であれば (npm@5+)
COPY package*.json ./
RUN npm install && \
    npm install --save-dev jest
# 本番用にコードを作成している場合
# RUN npm install --only=production
# アプリケーションのソースをバンドルする
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]

sample.js

サンプルのコードを用意します。今回は簡単な足し算にしてみました。

sample.js
function sum(a, b) {
    return a + b;
  }
  module.exports = sum;

sample.test.js

sample.jsのテストコードを作ります。サンプルコードの結果が「1+2=3にるか」を評価したUNITテストです。

sample.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

.dockerignore

これはなくてもよいのですが、dockerに無視して欲しいファイルを記載しています。

.dockerignore
node_modules
npm-debug.log

dockerイメージのbuild

プロジェクトフォルダ内(以下ではdocker-webapp-jest)に移動して、作成したDockerfileでDockerイメージをビルドします。ビルドコマンドは、

docker build . -t ryu/node-web-app 

としています。オプション(-t)は、 名前:タグ の形式で指定しますが、名前のみつけて、ryu/node-web-app としました

docker-webapp-jest % docker build . -t ryu/node-web-app          
[+] Building 74.3s (10/10) FINISHED                                                                                                                                  
 => [internal] load build definition from Dockerfile                                                                                                            0.1s
 => => transferring dockerfile: 37B                                                                                                                             0.0s
 => [internal] load .dockerignore                                                                                                                               0.0s
 => => transferring context: 34B                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/node:12                                                                                                      7.7s
 => [1/5] FROM docker.io/library/node:12@sha256:01627afeb110b3054ba4a1405541ca095c8bfca1cb6f2be9479c767a2711879e                                                0.0s
 => [internal] load build context                                                                                                                               0.0s
 => => transferring context: 688B                                                                                                                               0.0s
 => CACHED [2/5] WORKDIR /usr/src/app                                                                                                                           0.0s
 => [3/5] COPY package*.json ./                                                                                                                                 0.0s
 => [4/5] RUN npm install &&      npm install --save-dev jest                                                                                                  65.9s
 => [5/5] COPY . .                                                                                                                                              0.0s
 => exporting to image                                                                                                                                          0.5s
 => => exporting layers                                                                                                                                         0.5s
 => => writing image sha256:9b90a3ebd100cb3bea82c80b97caa4f8b5d3238bd7711c87004328bb1a0169fe                                                                    0.0s 
 => => naming to docker.io/ryu/node-web-app   

Dockerの起動

ビルドしたイメージでDockerコンテナを起動します。
外部ポートは49161をコンテナ内の8080にポートフォワードします。

docker-webapp-jest %  % docker run -p 49161:8080 -d ryu/node-web-app

# Dockerコンテナの起動を確認
コンテナの起動をdocker psコマンドで確認します。STATUSがUPとなればOKです。

docker-webapp-jest %docker ps       
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                         NAMES
77f093b9b8ab   ryu/node-web-app   "docker-entrypoint.s…"   34 seconds ago   Up 32 seconds   0.0.0.0:49161->8080/tcp, :::49161->8080/tcp   elegant_dirac

外部からコンテナ内のWebアプリにアクセスできることをcurlで確認

docker-webapp-jest % curl -i localhost:49161
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 11
ETag: W/"b-Ck1VqNd45QIvq3AZd8XYQLvEhtA"
Date: Sat, 07 Oct 2023 04:30:39 GMT
Connection: keep-alive
Keep-Alive: timeout=5

Hello World% 

Hello Worldが出力され、外部からWebアクセスできました。

Dockerコンテナに入る

docker execコマンドでDockerコンテナ内に入ります。-it オプション指定し、コンテナIDを指定(この例では77f093b9b8ab)します。
コンテナ内ではnpm testコマンドでjestを実行します。

docker-webapp-jest  % docker exec -it 77f093b9b8ab /bin/bash
root@77f093b9b8ab:/usr/src/app# npm test

> docker_web_app@1.0.0 test
> jest

 PASS  ./sum.test.js
  ✓ adds 1 + 2 to equal 3 (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.208 s
Ran all test suites.

無事にUNITテストを実行できました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?