ポンコツエンジニアのごじゃっぺ開発日記。

いろいろポンコツだけど、気にするな。エンジニアの日々の開発などの記録を残していきます。 自動で収入を得られるサービスやシステムを作ることが目標!!

【Github Actions】プッシュ時にgithubに自動でテストを実行してもらおう!

本記事では、去年に提供開始されたGithub Actionsを用いて、Gitにプッシュしたらphpunitを自動で実行するワークフローを作成してみたいと思います。 そのため、今回はPHPを用いた開発を想定して、テストコードの実行にphpunitを用いていきます。

f:id:ponkotsu0605:20200322165241p:plain

Github Actionsとは

まずはGithub Actionsとは何なのか?以下が公式サイトにかかれている説明になります。

GitHub Actionsを使用すると、ワールドクラスのCI / CDですべてのソフトウェアワークフローを簡単に自動化できます。 GitHubから直接コードをビルド、テスト、デプロイでき、コードレビュー、ブランチ管理、問題のトリアージを希望どおりに機能させます。

とのことです。作業の自動化をGithub側に任せてしまおうということですね。

こちらが、公式ドキュメントになります。

help.github.com

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側に実行結果がコンソールのように表示されます。

f:id:ponkotsu0605:20200322165241p:plain

このようにテストの実行結果を確認することができます。

テストの成功と失敗

ではテストが成功/失敗するとどうなるでしょうか。

f:id:ponkotsu0605:20200322165503p:plain

このように、それぞれのコミットに対してのテスト結果をアイコンで表示してくれます。そのため、このコミット時には正常なソースコードが表示されているかがわかります。

f:id:ponkotsu0605:20200322165603p:plain

このようにレポジトリのトップページも右上のようにアイコンでわかります。

さいごに

今回はこのようにしてコミットごとにテストを自動で実行させることを実現できました。 これを応用して、例えばプルリクの作成時をトリガーとしてテストを実行すれば、そのプルリクをマージしても問題ないかの判断材料にすることができるようになるかもですね。