SQL Server 2017を使ったLaravelアプリをCircleCI上でテストする。

仕事でAzure上で動くLaravelアプリケーションの開発をしている。開発を始めたころ、まだAzure Database for MySQL/PostegreSQL などはベータ版だったので、Azure SQL Databaseを使っている。開発環境はDockerを使い、Macbook 上でSQL Server for Linuxのコンテナを起動し、同じく PHPのコンテナを立ち上げて、それらをつなげている。

そろそろ真面目に自動テストを書いていかないといけないねぇ、という話をチームでしていて、CircleCIを使ってテストを実行するための準備をしてみた。思いのほか、手間がかかったので、そのことを書き残しておきます。

CircleCI

CircleCIはCI/CDのSaaSです。YAMLファイルを記述することでテスト、ビルド、デプロイを定義でき、テスト環境の作成にはDockerイメージを使えます。予めCircleCIで提供されている言語ごとのイメージや、データベースなどミドルウェアのイメージが提供されています。

困ったこと

CircleCI上でDockerイメージを使う場合、今回は2つのイメージが必要です。1つは、テストを実際に実行する環境としてのイメージ、もう1つはデータベース、即ちSQL Serverのイメージです。予めCircleCIが用意しているDockerイメージはあり、これらを使うことでCI環境を作ることができます。

と、便利にサクッとCI環境を手に入れられると思ったのですが、SQL Serverを使うには乗り越えなければいけない課題があります。

  1. SQL Server のイメージは提供されていない。
  2. CircleCIのPHPのイメージは、SQL Serverに接続するためのPDOはインストールされていない。

という2つです。1つ目は、既にマイクロソフトから提供されているSQL Server for LinuxのDockerイメージがあるので、それを使えば解決できます。2つ目は自前で用意する必要があります。

SQL Serverに接続できるPHPイメージを作る

実際に作ったDockerfileがこちらです。

Dockerfile

簡単に解説します。Step 1. は、CircleCI上でテストする環境として必要なパッケージをインストールしています。Step 2. でSQL Serverへ接続するために必要なライブラリやツールをインストールし、Step 3. でPDOをpeclでインストールしています。それ以降はテスト時には必要無いのですが、せっかくなのでローカルで動かす時の環境としても使えるように書いています。

ビルドしたイメージは予めDocker Hubにpushしておきます。次に、このイメージを使用したCircleCI上のビルドの定義を書きます。

CircleCI上でのビルドを定義する。

jobs.build.steps の中で、36行目にあるようにsleepを入れている。ここでデータベースを作成する前に、SQL Serverが応答可能になるまで待っている。これが無いと、SQL Serverの起動が完了せずに、40行にあるCREATE DATABASEを実行しようとしてしまい、テストが失敗する。とても面倒なのは、タイミングによってはSQL Serverが応答可能になることもあり、成功する場合もあるということです。色々試してく中で成功したりもしたので、何が効いたのかがわからず惑わされてしまった…

ということで、SQL Server を CircleCI でも使えるようになったので、PHPUnitでテストを書けそうです。