本記事では、去年に提供開始されたGithub Actionsを用いて、Gitにプッシュしたらphpunitを自動で実行するワークフローを作成してみたいと思います。 そのため、今回はPHPを用いた開発を想定して、テストコードの実行にphpunitを用いていきます。
Github Actionsとは
まずはGithub Actionsとは何なのか?以下が公式サイトにかかれている説明になります。
GitHub Actionsを使用すると、ワールドクラスのCI / CDですべてのソフトウェアワークフローを簡単に自動化できます。 GitHubから直接コードをビルド、テスト、デプロイでき、コードレビュー、ブランチ管理、問題のトリアージを希望どおりに機能させます。
とのことです。作業の自動化をGithub側に任せてしまおうということですね。
こちらが、公式ドキュメントになります。
GitHubホストランナーとセルフホストランナー
また、実行環境は、Githubによって管理・メンテナンスされているGitHubホストランナーと、自分たちが用意したクラウドサービスやローカルマシンとするセルフホストランナーが選択できます。 今回はコストをかけずに無料で行いたいため、GitHubホストランナーを用いることとします。
仮想環境のスペック
GitHubホストランナーで用意されている仮想環境は現状、以下のような仮想マシンが使用できます。
- 2コアCPU
- 7 GBのRAMメモリー
- 14 GBのSSDディスク容量
仮想環境 | YAMLのワークフローラベル |
---|---|
Windows Server 2019 | windows-latest or windows-2019 |
Ubuntu 18.04 | ubuntu-latestまたはubuntu-18.04 |
Ubuntu 16.04 | ubuntu-16.04 |
macOS Catalina 10.15 | macos-latest or macos-10.15 |
個人的に驚いたのが、WindowsサーバとmacOSが使用できることです。例えば、macでUnityのビルドをGithub Actionsにまかせてアプリを作成しようってことも可能そうですね。xcodeとかも使えるんでしょうか、そこは検証してみたいですね。
PHPプロジェクトを用意しよう
では、さっそくソースコードを用意しましょう。 今回はdocker-composeで動くローカル環境を用意して、それをGithub actions側でも利用してテストの実行をするようにしてみます。
ファイル一覧
今回使用するファイルは以下を想定しています。
$ tree . ├── README.md ├── app │ ├── composer.json │ ├── composer.lock │ ├── phpunit.xml │ ├── src │ │ └── Hoge.php │ ├── tests │ │ └── HogeTest.php │ └── vendor └── docker-compose.yml
appディレクトリにphpのソースファイルを配置して、srcにソースコード、testsにテストコードを配置しています。
docker-compose.yml
まずはローカル環境の作成のために、docker-compose.ymlを定義します。
version: "3.7" services: php: image: php:7.3-fpm ports: - "80:8080" volumes: - ./app:/var/www working_dir: /var/www
このようにphp7.3のイメージを用いて環境を構築します。
PHPソース
次に作成したソースコードを紹介します。上でtreeコマンドで表示しているHoge.phpが以下になります。
<?php namespace App; class Hoge { public static function fuga(float $height, float $weight) { $bmi = self::getBmi($height, $weight); if ($bmi >= 26.5) return 'very overweight'; if ($bmi >= 24.0) return 'overweight'; if ($bmi >= 20.0) return 'normal'; if ($bmi >= 17.7) return 'lean'; return 'very lean'; } public static function getBmi(float $height, float $weight) { return $weight/$height/$height; } }
このように、単純にBMIを求めて、その時の状態を文字列で返すという処理になります。文字列の内容はテキトーな英語なのでそこまで読まなくて結構ですよ。
composer.json
composer.jsonは以下のような感じで用意してみました。
{ "require": {}, "require-dev": { "phpunit/phpunit": "^8.5", }, "autoload": { "psr-4": { "App\\": "src/" } } }
phpunitとautoloadを追記しております。
テストコード
さて、用意したHogeTest.phpというテストコードの紹介です。
<?php namespace App; use PHPUnit\Framework\TestCase; class HogeTest extends TestCase { public function testHoge() { $this->assertEquals('very overweight', Hoge::fuga(1.60, 70)); $this->assertEquals('overweight', Hoge::fuga(1.60, 65)); $this->assertEquals('normal', Hoge::fuga(1.60, 60)); $this->assertEquals('lean', Hoge::fuga(1.60, 50)); $this->assertEquals('very lean', Hoge::fuga(1.60, 40)); } }
単純に身長と体重に対して正しい文字列をチェックしているテストコードです。
ローカル環境
上記のようなファイルを用意してローカルマシンで実行してみます。
$ docker-compose up -d $ composer install $ docker-compose exec php bash # vendor/bin/phpunit PHPUnit 8.5.2 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 678 ms, Memory: 6.00 MB OK (1 test, 5 assertions)
例えばこのようにしてphpunitの実行をすることができます。
GitHub Actionsの設定
さて、とうとう来ました。GitHub Actionsの設定です。 レポジトリの.githubディレクトリ内のworkflowsというディレクトリを作成して、その中でワークフローの定義ファイルをyamlで定義することで設定が完了になります。
今回は .github/workflows/unittest.yml
というファイルで用意してみました。
name: UnitTest on: push: jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: phpunit run: | php -v cd app docker-compose up -d composer install docker-compose exec -T php bash -c "vendor/bin/phpunit"
トリガーをpush(プッシュ時)としていますので、コミットごとにテストを実行してくれます。
- docker-compose up
- composer install
- phpunitの実行
これらを実行しています。
実際に実行してみる
さて、ではこれらのファイルをコミットしてプッシュしてみましょう。 GitHub側に実行結果がコンソールのように表示されます。
このようにテストの実行結果を確認することができます。
テストの成功と失敗
ではテストが成功/失敗するとどうなるでしょうか。
このように、それぞれのコミットに対してのテスト結果をアイコンで表示してくれます。そのため、このコミット時には正常なソースコードが表示されているかがわかります。
このようにレポジトリのトップページも右上のようにアイコンでわかります。
さいごに
今回はこのようにしてコミットごとにテストを自動で実行させることを実現できました。 これを応用して、例えばプルリクの作成時をトリガーとしてテストを実行すれば、そのプルリクをマージしても問題ないかの判断材料にすることができるようになるかもですね。