AWS CDK × CodeBuildでLaravelのユニットテストを自動化 & テストレポート出力してみる

こんにちは!エンジニアの岩間です。

今回は、AWS CDK × CodePipeline × CodeBuildでLaravelのユニットテストを自動化&テストレポート出力してみる機会があったのでその手順とCDKのコードを公開したいと思います。

 

構成図

構成図は以下です。

 

開発者がAWS CodeCommitのdevelopブランチにソースコードをプッシュすると、AWS CodePipelineが自動的にトリガーされ、その後AWS CodeBuildでLaravelのユニットテストが行わる、といった流れです。

今回実行したいユニットテストには、データベース接続のテストも含まれています。
そのため、CodeBuild環境上ではテスト用のWEB、アプリケーション、データベース用のコンテナをDockerを使用して起動します。

通常、LaravelのユニットテストではデータベースのセットアップをLaravelのmigrationファイルを使用して行うことができますが、今回は直接SQLファイルを実行してデータベースをセットアップしたいため、コンテナを利用します。

 

前提条件

以下のバージョンで構築しています。

AWS CDK:2.116.0

AWS CodePipeline:v1

Laravel:10

Nginx:1.24.0

PostgreSQL:12.14

 

ディレクトリ構成

ディレクトリ構成は以下の通りです。

 

コーディング

以下のコードを書いていきます。

  • docker-compose.yml(Docker Composeの設定ファイル)
  • lib/piepline-cdk-stack.ts(CDKのコード)
  • buildspec_unit_test.yml(CodeBuildで実行されるファイル)
  • Laravelのコード

docker-compose.yml

まずはdocker-compose.ymlで、CodeBuildで立ち上げる3つのコンテナ(web、app、db)を以下のように定義します。

※sqlファイルはDBコンテナのdocker-entrypoint-initdb.d/配下に配置することでコンテナ初期立ち上げ時に実行してくれます。

各Dockerfileではタイムゾーンや言語の設定を行っています。※今回は省略します

 

CDK

次にCDKの設定です。今回はTypeScriptで、CI/CDプロセスを自動化するためのCDKスタックを定義しています。

pipeline-cdkディレクトリ配下で、

  • cdk init sample-app --language typescript
  • cdk bootstrap

を実行済みの状態で、lib/piepline-cdk-stack.tsに以下の記述を追加します。

CodeBuildの環境変数で渡しているDockerHubのユーザー名とパスワード(33~39行目)は、cdkディレクトリ内のconfig.tsで環境ごとに定義したり、SSMパラメータストアから取得するやり方がおすすめです。

※DockerHubのユーザーとパスワードの設定については、次のbuildspec_unit_test.ymlのセクションに記載しています。

 

上記の記述を追加後、cdk deployを実行し、正しくリソースが作成されていればOKです。

 

buildspec_unit_test.yml

buildspecファイルとは、AWS CodeBuildでビルドプロジェクトを実行する際に使用される構成ファイルです。

buildspec_unit_test.ymlを以下のように記述します。

 

ポイントは以下の3点です。

①DockerHubへのログイン

7行目のコマンド(echo $DOCKERHUB_PASS | docker login -u $DOCKERHUB_USER --password-stdin)では、DockerHubからのコンテナイメージの呼び出し回数制限エラー回避のため、DockerHubにログインしています。
DockerHubにログインしていない匿名ユーザーの状態だと、 IP アドレス単位での回数呼び出し制限がかかります。

今回、CodeBuild は非 VPC 環境で作成しているため、共用のグローバルIPが利用されることになります。
つまり、CodeBuildから自分がコンテナイメージを呼び出した回数に関係なく、制限に引っかかってしまいます。

※DockerHubにログインしない場合、以下のようなエラーがでることがあります。
toomanyrequests: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit

上記のIP制限に引っかからないように、DockerHubのアカウントを作成し、ユーザー名とパスワードでログインをします。DockerHubアカウント作成はこちら

②テストレポート出力引数

appコンテナ内でユニットテスト実行する18行目のコマンド(php artisan test --env=testing)の引数に--log-junit ./phpunit-log.xmlを指定することで テストレポートの出力に関して指定しています。

PHPUnitの公式ドキュメントに記載されているように、このオプションは、テスト実行の結果をJUnit形式のXMLファイルに出力するために使用されます。

③reportsセクション

20行目のreportsセクションは、AWS CodeBuildのビルドで生成されたレポートを指定するためのセクションです。
このセクションを使用すると、ビルドの結果や生成物を保存し、後で参照できるようにすることができます。
今回、file-formatにはJunitXmlを指定していますが、他の形式も指定可能です。
構文について詳しくはこちら

 

Laravel設定

最後にLaravel側でユニットテストの設定を行います。

1.テスト用の環境変数ファイルを作成します。

Laravelのプロジェクトディレクトリに移動し、docker/docker-php/laravel/.env.testingを作成し、以下を編集します。

アプリケーションキーはCodeBuild上で作成するので空欄にします。

 

2.次にLaravelプロジェクト内のdocker/docker-php/laravel/phpunit.xmlを開き、以下のように変更します。


 

3.テストケースをdocker/docker-php/laravel/tests以下に作成します。

 

動作確認

CodeCommitのdevelopブランチにすべてのソースをpushして、動作確認をします。

AWSコンソールでCodePipelineと検索し、対象のパイプライン名を選択すると以下の画面が確認できます。
CodeCommitのdevelopブランチにpushしたのをトリガーにCodePipelineが動いています!

 

レポート出力の動作確認

次にレポートが出力されているか確認します。
上記の画面でUnit-Testingステージが成功したら、画面内の「AWS CodeBuild」のリンクをクリックします。

 

次に、レポートタブをクリックし、レポート名をクリックします。

 

すると、以下の画像のようにレポート結果が作成されていることが確認できます。

 

テストに失敗したときは以下の画像のように、不合格の件数と割合も表示されます。

どのテストケースで失敗したのか、失敗時のエラーメッセージ等も確認することができます。

 

さらに、AWSコンソールのCodeBuild→レポートグループの画面からは、これまで行ったテストのパスレートや実行時間、テスト総数等がレポートグループごとに表示されています。

 

Artifacts出力の動作確認

ユニットテストのログファイルがアーティファクトとして保存されているか確認します。

Unit-Testingステージが成功した状態で画面内の「AWS CodeBuild」のリンクをクリック→「ビルドの詳細」タブに移動します。

以下の画像のように、アーティファクトのセクションに「アーティファクトのアップロード場所」の項目があるのでリンクをクリックします。

S3の画面が表示されるのでフォルダをダウンロードし、docker/docker-php/laravel/storage/logs/以下のファイルがアップロードされていればOKです。

 

まとめ

以上、AWS CDK×CodeBuildでLaravelのユニットテストを自動化&テストレポート出力してみるでした。

ここまでお読みいただきありがとうございました。

この記事が気に入ったら
いいね ! しよう

Twitter で

【採用情報】一緒に働く仲間を募集しています

採用情報
ページトップへ