Docker コンテナ内で起動している Python アプリケーションの自動ユニットテスト環境を構築する
前回の記事で、Docker コンテナ内の Webアプリケーション を Window 環境の VSCode からデバッグできるようにしました。
今回は、テストレポートおよびカバレッジレポートを出力できる、自動ユニットテスト環境を構築したいと思います。
今回のゴール
- Docker コンテナ内で起動している Python アプリケーションの自動ユニットテスト環境を構築する
- テストレポート(HTML形式/JUnit XML形式/Text形式)およびカバレッジレポート(HTML形式)を出力する
ディレクトリ構成
今回のディレクトリ構成は下記のようになります。
追加/修正対象のファイルのみを記載し、他は省略します。
/home/appuser
├── workspace
│ ├── docker-compose.yaml
│ └── web_app003
│ ├── Dockerfile
│ └── opt
│ ├── pytest
│ │ ├── run_pytest.sh
│ │ └── reports
│ │ └ {yyyyMMddHHmmss}
│ └── web_app
│ └── src
│ ├── pytest.ini
│ └── tests
│ └── test_web_app_001.py
~~~~~~~~~~ 以下省略 ~~~~~~~~~~
手順
資材作成
-
docker-compose.yaml
ファイルを修正
docker-compose.yaml
ファイルを下記のように修正します。- テストレポートをローカル(Ubuntu)のディレクトリと同期するように
volumes
を追加
docker-compose.yamlversion: '3' services: ############################################################################## # Web Application container(Python + Flask + Vue.js + Vuetify) ############################################################################## web_app003: build: "./web_app003/" command: "/bin/bash" # Flask アプリケーションが自動的に起動しないようにする設定 tty: true volumes: - "./web_app003/opt/pytest/reports/:/opt/pytest/reports/" # ローカル(Ubuntu)のディレクトリと同期する ports: - "5000:5000" # Flask port - "5173:5173" # Vue.js port - "5678:5678" # Debug port image: "web_app003:develop" container_name: "web_app003"
- テストレポートをローカル(Ubuntu)のディレクトリと同期するように
-
Dockerfile
ファイルを修正
Dockerfile
ファイルを下記のように修正します。- pytest 関連のライブラリをインストール対象に追加
- テストレポートの出力ディレクトリを追加
Dockerfile# Amazon Linux 2023 FROM public.ecr.aws/amazonlinux/amazonlinux:2023 # ミドルウェアをインストール RUN dnf install -y \ util-linux \ shadow-utils \ vim-enhanced-2:9.* \ sudo-1.9.* \ python3.11-3.11.* \ python3.11-pip-22.3.* \ python3.11-devel-3.11.* \ nodejs-1:18.* # Python のライブラリをインストール RUN pip3.11 install flask==3.0.* RUN pip3.11 install flask_socketio==5.3.* RUN pip3.11 install flask-cors==4.0.* RUN pip3.11 install flask-wtf==1.2.* RUN pip3.11 install debugpy==1.8.* RUN pip3.11 install pytest==8.1.* RUN pip3.11 install pytest-cov==4.1.* RUN pip3.11 install pytest-html==4.1.* RUN pip3.11 install pytest_env==1.1.* # ホストOS と同じユーザーを追加する # 1000 : host OS $(id -g) RUN groupadd -g 1000 appuser # 1000 : host OS $(id -u) RUN adduser -m appuser -u 1000 -g appuser # Add SUDO group. RUN groupadd sudo # Add SUDO authority. RUN usermod -aG sudo appuser # 資材を配置する WORKDIR /opt/web_app/ RUN mkdir -p /opt/web_app/ COPY ./opt/web_app/ /opt/web_app/ COPY ./opt/flask_start.sh /opt/ RUN mkdir -p /opt/pytest/reports/ COPY ./opt/pytest/ /opt/pytest/ # オーナーとパーミッションを変更する RUN chown appuser:appuser /opt/web_app -R RUN chmod 775 /opt/web_app -R RUN chown appuser:appuser /opt/pytest -R RUN chmod 775 /opt/pytest -R # vite で Vue.js 環境を構築してプロダクションビルドする WORKDIR /opt/web_app/frontend/ RUN npm install RUN npm run build # 起動時のコマンドを設定する CMD ["sh","/opt/flask_start.sh"]
-
テストコードファイルを作成
テストコードtest_web_app_001.py
ファイルを下記のように作成します。test_web_app_001.py# coding: UTF-8 import sys sys.path.append("/opt/web_app/src/") import importlib import app_controller def test_web_app_001_xxxxx(): """ 自動テストのサンプル """ try: _app = importlib.reload(app_controller) index_html = _app.get_index_html() assert index_html == "index.html" except AssertionError as ae: raise ae except Exception as e: msg = str(e) assert False, f"Exception occurred. {msg}"
-
pytest 設定ファイルを作成
pytest 設定ファイルpytest.ini
を下記のように作成します。pytest.ini[pytest] env = TZ=Asia/Tokyo AppEnv=TEST
-
テストレポートディレクトリを作成
権限を appuser にする都合上、テストレポートディレクトリを先に作成しておきます。WSL2 Ubuntumkdir -p /home/appuser/workspace/web_app003/opt/pytest/reports
-
pytest 起動シェルを作成
pytest 起動シェルrun_pytest.sh
を作成します。run_pytest.sh#!/bin/bash # pytest をカバレッジレポートを出力するモードで起動するシェルスクリプト datetime=$(date '+%Y%m%d%H%M%S') path=/opt/pytest/reports out_path=$path/$datetime sudo -u appuser mkdir -p $out_path/report_text/ sudo -u appuser mkdir -p $out_path/report_xml/ sudo -u appuser mkdir -p $out_path/report_html/ sudo -u appuser mkdir -p $out_path/coverage_html/ cd /opt/web_app/src/ sudo -u appuser python3.11 -m pytest -c pytest.ini -s -v \ --junitxml=$out_path/report_xml/report.xml \ --html=$out_path/report_html/report.html \ --cov-report=html:$out_path/coverage_html/ \ --cov=/opt/web_app/src/ \ --cov-branch /opt/web_app/src/ > $out_path/report_text/report.txt
動作確認
-
Docker Compose でビルド&起動
Docker Compose でカスタムイメージをビルドして起動します。WSL2 Ubuntucd /home/appuser/workspace docker-compose build docker-compose up -d
-
起動した Docker コンテナに入る
docker exec
コマンドで、起動した Docker コンテナに入ります。WSL2 Ubuntudocker exec -it web_app003 bash
-
pytest を起動する
シェルを実行して pytest を起動します。web_app003sh /opt/pytest/run_pytest.sh
-
テストレポートを確認する
Windows 環境から、出力されたテストレポートを確認します。
\\wsl$\Ubuntu-22.04\home\appuser\workspace\web_app003\opt\pytest\reports\{yyyyMMddHHmmss}
に下記のテストレポートが出力されています。
最後に
今回はコンテナ内にテストレポート出力を行いましたが、更に応用すれば、サーバで自動ユニットテストを定期起動し、テスト結果を公開するといったことも可能です。
特に、カバレッジレポートを視覚的に確認できるのは、重宝できるかと思っています。