Chaliceを用いたCD環境の構築(テスト編)

はじめに

みなさんこんにちは。
今回の記事は前回の「Chaliceを用いたCD環境の構築(基本編)」の続きです。

xp-cloud.jp

前回は基本的なCD環境を構築するだけにとどまりましたが、今回はChaliceの機能を超えて環境を改良していきます。

テストフェーズの追加

テストコードの準備

テストフェーズを追加するにあたって、まずはテストコードを書きましょう。
chalice用のテストライブラリがあるのでそれインストールします。

$ pip install pytest-chalice
$ pip freeze > requirements.txt

テストコードの実行環境はCodeBuild実行時に生成されるコンテナ環境となります。
そのため、テストコード実行時に必要なライブラリもrequirements.txt等に含めておいてインストールできるようにしておきましょう。

$ mkdir tests
$ cd tests
$ touch __init__.py
$ touch conftest.py
$ touch test_app.py
conftest.py
import pytest

from chalice import Chalice

from app import app as chalice_app


@pytest.fixture
def app() -> Chalice:
    return chalice_app
test_app.py
from http import HTTPStatus
from pytest_chalice.handlers import RequestHandler


def test_index(client: RequestHandler) -> None:
    response = client.get('/')
    assert response.status_code == HTTPStatus.OK
    assert response.json == {'hello': 'world'}

ここまでファイルを作成したらテストコードを実行できます。
以下のようにテストコードがパスできたでしょうか。

$ pytest --vv
================================================= test session starts =================================================
~(中略)~
plugins: chalice-0.0.4
collected 1 item

tests/test_app.py::test_index PASSED                                                                             [100%]

================================================== 1 passed in 0.04s ==================================================

 

テンプレートの編集

テストコードが準備できたらパイプライン上でテストコードが実行されるようにする必要があります。
パイプラインの設定はCloudformationのスタックで管理されているため、スタックのテンプレートを編集します。

Cloudformationを見ると、Chaliceの導入を始めてから2つのスタックがあることが確認できると思います。

Cloudformation スタック

プロジェクト名と同じスタックがCD環境を構成する各リソースのスタックで、BetaStackというものはApiGatewayなどを構築するためにChaliceが生成するスタックです。
なので環境をいじるときはプロジェクト名と同じスタックを編集するようにしましょう。

変更セットからテンプレートを編集します。

Chalice テンプレート

デザイナーからテンプレートを編集できます。
デザイナーで編集した内容は一度、ローカルかS3に保存してから変更セットに対してアップロードする流れになるので注意してください。

Chalice テンプレート

テストを実行するCodeBuildプロジェクトを追加して、それをPipelineに追加するような修正を加えます。


テスト実行用CodeBuildプロジェクト

もとのテンプレートをいじっていなければ84,85行目の間に入れておきましょう。
※リソースの追加なので、リソースの階層と合っていればどこでもよいです。

   "AppPackageTest": {
  "Type": "AWS::CodeBuild::Project",
  "Properties": {
    "Artifacts": {
      "Type": "CODEPIPELINE"
    },
    "Environment": {
      "ComputeType": "BUILD_GENERAL1_SMALL",
      "Image": {
        "Ref": "CodeBuildImage"
      },
      "Type": "LINUX_CONTAINER"
    },
    "Name": {
      "Fn::Sub": "${ApplicationName}Test"
    },
    "ServiceRole": {
      "Fn::GetAtt": "CodeBuildRole.Arn"
    },
    "Source": {
      "Type": "CODEPIPELINE",
      "BuildSpec": "version: 0.1\nphases:\n install:\n commands:\n - sudo pip install --upgrade awscli\n - aws --version\n - sudo pip install 'chalice>=1.6.0,<1.7.0'\n - sudo pip install -r requirements.txt\n build:\n commands:\n - pytest -vv\n"
    }
  }
},

 

続いてパイプラインの編集ですが、少し複雑なのでパイプラインの構成を説明します。
パイプラインはもっとも大きな塊として「Stage」というものが存在します。

現段階では「Source」、「Build」、「Beta」の3ステージがあるはずです。
これらのステージの中に複数のアクションが存在します。
「Build」ステージには「CodeBuild」アクションがあるます。

テンプレートでもこの構成を表すように記載されています。
今回は「Build」ステージ内で、「CodeBuild」アクションの前に「Test」アクションを作成するようにします。

テストコードをパスしてからビルドを行うという流れになるわけですね。
それを踏まえたうえで見てましょう。

パイプライン

{
  "InputArtifacts": [
    {
      "Name": "SourceRepo"
    }
  ],
  "Name": "Test",
  "ActionTypeId": {
    "Category": "Build",
    "Owner": "AWS",
    "Version": 1,
    "Provider": "CodeBuild"
  },
  "Configuration": {
    "ProjectName": {
      "Ref": "AppPackageTest"
    }
  },
  "RunOrder": 1
},

引き続き187行目の下に入れましょう。
Buildステージのアクションに加えるように記載できたでしょうか。

これが加えられたら、「CodeBuild」アクションの「RunOrder」を2に修正します。

各ステージ内のアクションの順番はこのRunOrderによって決まります。
数字の小さいものから順番に起動していき、同じ数字のアクションは並列で動きます。

今回はテストが完了後にビルドを行いたいので、そのような順番となるようにRunOrderを採番する必要があります。

この内容をもとに変更セットを作成して実行します。

パイプラインがこのように変更されていたら成功です。
CodeBuild パイプライン

 

先ほどのソースをPushしてテストコードが実行されるか見てみましょう。

ビルドログ テストコード実行

CodeBuild上でテストコードが実行されていますね。

おわりに

今回はテストコードを実行させるという内容でした。
単にテストコードを実行させるだけならCodeBuild上で直接アクションを追加したり、Buildspec内にコマンドだけを追加するというやり方もありますが、Cloudformationで一元管理できるようにテンプレートを編集する形をとりました。
アクションという形で追加すると、その間にさらにアクションを追加できたりするのでユースケースによってどのような形で追加するのか使い分けるとよいでしょう。

 

 

 

ブログ著者

 

 

アプリケーション開発バナー