CircleCI
テストの準備ができたので、次はこのテストを継続的インテグレーション(CI)に組み込んでみましょう。テストを自動化することで、意図していないバグを早期に発見できる可能性が高まります。
本連載ではCIサービスとして、CircleCIを利用します。CircleCI 1.0では、2種類の仮想マシンから実行環境を選ぶしくみになっていましたが、2.0からは任意のDockerイメージを指定できるようになりました。このおかげで、設定の柔軟性が増し処理の高速化にもつながりました。
1コンテナまでは無料で使用できるので、業務だけでなく個人利用でも人気のあるCIサービスです。
CircleCIの設定
それではCircleCIを使い始めるための設定を行います。CircleCIの説明に従って、以下の流れで進めていきましょう。
- https://circleci.com/signup/からサインアップ
- ダッシュボード左サイドバー「ADD PROJECTS」から、CircleCIと連携したいリポジトリを選択
- OSと開発言語を選択をして、設定ファイルのひな型を取得
-
リポジトリルートの
.circleci/config.yml
に設定ファイルを配置
OSにLinux、開発言語にPythonを選択すると、以下のようなひな型を取得できます。
# Python CircleCI 2.0 configuration file # # Check https://circleci.com/docs/2.0/language-python/ for more details # version: 2 jobs: build: docker: # specify the version you desire here # use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers` - image: circleci/python:3.6.1 # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ # - image: circleci/postgres:9.4 working_directory: ~/repo steps: - checkout # Download and cache dependencies - restore_cache: keys: - v1-dependencies-{{ checksum "requirements.txt" }} # fallback to using the latest cache if no exact match is found - v1-dependencies- - run: name: install dependencies command: | python3 -m venv venv . venv/bin/activate pip install -r requirements.txt - save_cache: paths: - ./venv key: v1-dependencies-{{ checksum "requirements.txt" }} # run tests! # this example uses Django's built-in test-runner # other common Python testing frameworks include pytest and nose # https://pytest.org # https://nose.readthedocs.io - run: name: run tests command: | . venv/bin/activate python manage.py test - store_artifacts: path: test-reports destination: test-reports
この設定ファイルで使われている設定項目について、いくつか紹介します。
- version: CircleCIのバージョンを指定
-
jobs: 実行単位である
job
を束ねるセクション -
build: リポジトリへのPushがトリガーとなって実行されるデフォルトの
job
-
docker:
steps
を実行するDocker環境を指定 -
working_directory:
steps
を実行するディレクトリ - steps: ビルドステップを束ねるセクション
-
checkout:
working_directory
にソースコードをチェックアウト - run: 実行するコマンドを指定
-
restore_cache:
key
をもとにキャッシュを取得 -
save_cache:
key
を指定してキャッシュを保存 -
store_artifacts: カバレッジレポートやバイナリなど
job
の成果物を保存
設定ファイルに関してより詳しく知りたい方は、公式ドキュメントConfiguring CircleCIを参照してください。
それではこのひな型をもとに、先ほど実装したテストを実行するために以下のように編集しましょう。
version: 2 jobs: build: docker: - image: circleci/python:3.6 working_directory: ~/repo steps: - checkout - restore_cache: key: v1-dependencies-{{ checksum "requirements/base.txt" }}-{{ checksum "requirements/test.txt" }} - run: name: install dependencies command: | python3 -m venv venv . venv/bin/activate pip install -r requirements/test.txt - save_cache: paths: - ./venv key: v1-dependencies-{{ checksum "requirements/base.txt" }}-{{ checksum "requirements/test.txt" }} - run: name: run migrate command: | . venv/bin/activate python manage.py migrate - run: name: run tests command: | . venv/bin/activate python -Wd manage.py test
主な変更は以下の3つです。
-
キャッシュのkeyに、
requirements/base.txt
とrequirements/test.txt
のチェックサム値を記述 - migrationを実行するためのstepを追加
-
python manage.py test
に、前回紹介した-Wd
オプションを追加
あとはリポジトリにPushして、CircleCIのプロジェクト設定画面で「Start building」ボタンをクリックすれば、ビルドが実行できます。
しかし現状のコードだと、ModuleNotFoundError: No module named 'django_extensions'
というエラーが発生してビルドが失敗してしまいます。
これはrequirements/local.txt
のrequirementsを、CI環境でインストールしていないために起きているエラーです。しかしローカルでの開発だけで使用するrequirementsに各環境が依存するのは避けたいので、settingsについて見直しましょう。
問題となっているのはmanage.py
の6行目os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.local")
というコードで、ここでローカル用のsettingsがDJANGO_SETTINGS_MODULE
にセットされています。普段の開発では問題ないのですが、CI環境ではローカル用の設定が含まれていないconfig.settings.base
を使うようにしましょう。
manage.py
コマンドに--settings
オプションを付与することで、settingsの参照先を自由に変更できます。.circleci/config.yml
の最後の部分を以下のように編集します。
- run: name: run migrate command: | . venv/bin/activate python manage.py migrate --settings=config.settings.base - run: name: run tests command: | . venv/bin/activate python -Wd manage.py test --settings=config.settings.base
この変更をPushして再度ビルドが実行されると、無事成功することが確認できました。
今回は便宜上--settings
オプションで解決しましたが、次回の連載では環境変数を用いた設定ファイルの管理方法を紹介する予定です。
ここまで解説したソースコードは以下から見ることができます。