どうしてわざわざ自動テストを導入したのか
今回、オリジナルプロダクトを進めるにあたり、毎日コードを push するたびに手作業で本番環境にデプロイするのではないかという不安がありました。
手動での作業は非効率で、人的ミスも増えるのではないかと考えたため、今回は自動化を導入することにしました。
また、これまではローカル環境でのみ運用していたため、本番環境へのリリース時に考慮すべきことを学ぶ良い機会でもあると思い、GitHub Actions を用いて CI(継続的インテグレーション)をとりあえず実装しました。
今回実装してみて、自分の環境とプロダクトに完全に一致する解説が見つからなかったため、まずはテンプレートを push し続けて試行する方針を取りました。その過程で出るエラー内容を読み解きながら、CIの仕組みをざっとですが理解することができました。
※Dockerは使用しません。
まず始めるための事前設定ができてなかった
事前に調べてわかったことは、.ymlファイルに書く内容は以下ということだけ。
ワークフロー
トリガー
job1:
job2:
参考動画
ymlファイルをまずは真似して書いてみた
まずはDocsの基本的な内容を記述して、テストしてみるか~といった具合です。
name: Run test
on:
push:
branches:
- feature/test
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
step:
- name:Checkout repository
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
tools: phpstan, phpcs
extensions: mbstring, bcmath, pdo_mysql, swoole
- name: Install dependencies
run: composer install --no-scripts --prefer-dist --no-interaction
- name: Run tests
run: php artisan test
通らないだろうと思いpush、エラーです。
当たり前の結果ですが、その前にworkflowの権限が付与されてなかったため、テストが動きもしなかったですね。
下記、記事を参考にリポジトリの「workflow」にチェックをいれました。
参考記事
気を取り直して再度挑戦。
それはもう、当たり前の結果ですね。

次からエラー内容をさばいていきます。
composerが不一致
まず先ほどのymlファイル初めてのエラー内容ですが、
composer.lock を無視して composer.json だけ更新していたため、一致しないよという内容でした。
依存関係の差異によるバグやローカルで動いた環境を本番では再現できない、、、といった理由があるため、composer.json と composer.lock は常に一致させることが重要で、
再度push。
「Unknown MySQL server host 'mysql'」って出るけど、ちゃんと指定してるよ?
続いてのエラー内容は「MySQLを直接インストールしている場合、ホスト名 mysql は存在しない」と言われてしまいました。
Unknown MySQL server host 'mysql' (-3)
調べても、.env の DB_HOST を 127.0.0.1 に変更する!としか出てこなかったり、
DB_HOST: mysqlに変更してpushしたり、127.0.0.1に戻したり。
依然としてエラー内容は変わらずでした。
そもそもマイグレーションを作る必要はあるのか?と考えて一度手放してみることに。
マイグレーションを作る必要のないUnitテストだけとりあえずテストを成功させたいと思い、下記を作成。

しかしFeatureテストや開発用に自動デプロイした際のテストも通せなくなると思い、やっぱりマイグレーションさせるのは必須だよなあと思いなおし、同じエラーと向き合うことにしました。
調べどchatGPTに質問せど、よくDockerでの実装方法を提案されました。
やっぱりDockerコンテナを立てないとダメなのか~と諦めもありました。
GitHub Actionsのrunnerはデフォルトで MySQL を持っていなかった
Dockerがなぜその役割を果たすのかが分からなかったので、もうこれ以上は実装できないなと思っていました。
しかし、Docker環境を実現できないかを調べると、
DockerはMySQLコンテナが独立したサーバーとして立ち上げるため、ymlファイルでは起動の内容だけを明記すればよいということ。私が今まで書いたコードは起動の内容だけでした。
しかし、Dockerではない場合は直接runnerにインストールする必要があったので、インストールして起動する必要があり、なおかつ権限設定なども必要でした。
このエラーの原因はMySQLコンテナを立ていないのに、「Wait for MySQL」を通していたので、一生進まない。
そりゃいくらWait for MySQLしても起動しないわけだ、、、、。
最初エラーに対して、何を求めているのかが理解できずにはまってしまいましたが、Actionではコンテナが必須であり、コンテナを立ててマイグレーションを実行する順番だということを理解することができました。

Actions内でMySQLコンテナを立ち上げてテストを実行する必要がある
そしていざpush、
マイグレーションは起動して立ち上がって、テストへ移行されるそうです。
services:
mysql:
image: mysql:8.0
env:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: onehouse
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -uroot -ppassword"
--health-interval=5s
--health-timeout=3s
--health-retries=10
追加して通すと、無事マイグレーションも作成完了。
テストも通りました。
まとめ
以上、もっとymlファイルやGitHubActionについての理解や内容を深めてから書いてみろ、と言われそうな内容でしたが、初心者にはやってみる、書いてみるという体験が一番効果的だと思っています。
まずはコードに見慣れる時間がとても大事だと思っていて、見るだけでは見慣れなくて、書くことで見慣れていくペースを掴みつつあります。
次のステップはデプロイ後の自動テスト実装です!
今回の実装で効率的に開発を進め、無駄な手作業や繰り返しによるストレスを感じずに済みそうです。
また自動テストや CI がバグを監視してくれるため、リリース時の安心感も得られたので完成できた時にはガッツポーズが出たほどでした。



