SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

モダンDjango入門

Djangoのテストの書き方とCircleCIを活用した継続的インテグレーション

モダンDjango入門 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

CircleCI

 テストの準備ができたので、次はこのテストを継続的インテグレーション(CI)に組み込んでみましょう。テストを自動化することで、意図していないバグを早期に発見できる可能性が高まります。

 本連載ではCIサービスとして、CircleCIを利用します。CircleCI 1.0では、2種類の仮想マシンから実行環境を選ぶしくみになっていましたが、2.0からは任意のDockerイメージを指定できるようになりました。このおかげで、設定の柔軟性が増し処理の高速化にもつながりました。

 1コンテナまでは無料で使用できるので、業務だけでなく個人利用でも人気のあるCIサービスです。

CircleCI
CircleCI

CircleCIの設定

 それではCircleCIを使い始めるための設定を行います。CircleCIの説明に従って、以下の流れで進めていきましょう。

  1. https://circleci.com/signup/からサインアップ
  2. ダッシュボード左サイドバー「ADD PROJECTS」から、CircleCIと連携したいリポジトリを選択
  3. OSと開発言語を選択をして、設定ファイルのひな型を取得
  4. リポジトリルートの.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.txtrequirements/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オプションで解決しましたが、次回の連載では環境変数を用いた設定ファイルの管理方法を紹介する予定です。

 ここまで解説したソースコードは以下から見ることができます。

次のページ
DjangoCongress JP 2018

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
モダンDjango入門連載記事一覧

もっと読む

この記事の著者

新井 正貴(アライ マサタカ)

 東京大学文学部卒業、アライドアーキテクツ株式会社にて勤務。2016年4月、株式会社SQUEEZEに入社。コミュニティ活動として、PyCon JP 2015〜 スタッフ、Pythonもくもく会の主催を行う。趣味はラクロスとPerfume。 Site:http://massa142.github.io/ Twitter:@massa142 Facebook:新井 正貴

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10995 2018/08/03 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング