docker環境でcomposerをインストールしてphpunitをでテストする

本記事ではdocker環境でcomposerをインストールして、phpunitを使用する方法について紹介しています。

最終的なディレクトリ構成は下図のような感じです。

dockerコンテナ起動

詳細は割愛しますが、以下でコンテナ起動まで可能です。

git clone https://github.com/masayan1126/docker-phpunit.git
cd docker-phpunit
docker-compose up -d

以下のように表示されたら、コンテナ起動完了です。

Creating nginx ... done
Creating php ... done

composerインストール

以下の1.もしくは2.の方法でDockerでcomposerをインストールします。
今回は2.の方法をdocker\php\Dockerfileに記載しているので、ビルドの際にcomposerがインストールされます。

1.Composer 公式 のインストール方法

※ハッシュ値の部分はComposer はバージョンアップごとに変更されるので、都度Dockerfile も変更する必要があるため後述の2.の方法がおすすめです。

FROM php:7.3-fpm

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
&& php -r "if (hash_file('sha384', 'composer-setup.php') === 'a5c698ffe4b8e849a443b120cd5ba38043260d5c4023dbf93e1558871f1f07f58274fc6f4c93bcfd858c6bd0775cd8d1') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
&& php composer-setup.php \
&& php -r "unlink('composer-setup.php');" \
&& mv composer.phar /usr/local/bin/composer

2.マルチステージビルドでインストール(Docker 17.05以上)

Dockerのマルチステージビルドを活用すると、以下のように1行で書ける。

FROM php:7.3-fpm

COPY --from=composer /usr/bin/composer /usr/bin/composer

バージョン指定したい場合は以下のように指定できる(未指定なら最新版)

COPY --from=composer:1.8.6 /usr/bin/composer /usr/bin/composer

Dockerのmulti-stage buildsは17.05以降で利用できるビルド方法で、一つのDockerfileの中でビルド用イメージの作成とデプロイ用イメージを作成できます。ビルド用のイメージ中でプログラムをコンパイルし、実行ファイルだけをデプロイ用のイメージに取り込むことでデプロイ用のイメージサイズを減らすことができます。

コンテナが起動後、以下でコンテナ内に入ります。

docker-compose exec app bash

composer.jsonの作成

コンテナ内で以下を実行してcomposerで管理するプロジェクトを初期化します

root@eb351c5a0b16:/var/www# composer init

そうするとコマンドライン上でいろいろと確認されますが、
以下のパッケージ名の箇所はvendor/appで指定(特に指定はないので、任意の名称でOK)しています。

Package name (<vendor>/<name>) [root/www]: vendor/app

それ以外はデフォルトの設定で問題ないので、すべてEnter(もしくはnのこうもくも)を押します。そうすると、ルートディレクトリにcomposer.jsonとsrcディレクトリ、vendorディレクトリが作成されます

{
    // パッケージ名
    "name": "vendor/app",
    "autoload": {
        "psr-4": {
       // srcディレクトは以下にある、名前空間がVendor\Appで指定されているクラスがオートロードの対象
            "Vendor\\App\\": "src/"
        }
    },
    "scripts": { "test": "vendor/bin/phpunit" },
    "require-dev": {
        "phpunit/phpunit": "^9.5"
    }
}

psr4というコーディング規約を指定すると、以下のルールを守る必要があります。

  • クラスファイルはnamespaceが必須。
  • namespaceとディレクトリ構成、名称は一致させる。
  • namespace名は大文字からはじめる。

Composerのautoloadの書き方についてはこちらの記事がとても分かりやすかったので、参考までに残しておきます。

Composerのautoloadの書き方早見表 - Qiita
composer.jsonでautoloadをどう書くか忘れっぽい人のための早見表 psr-4 (Vendor\Namespace) composer.json { "autoload": { "psr...

phpunitをインストールしテストを実行する

1.phpunitをインストール

コンテナ内のcomposer.jsonのあるディレクトリで、以下を実行

root@eb351c5a0b16:/var/www# composer require --dev phpunit/phpunit

composer.jsonに以下のように追記されます。これで、開発用パッケージにphpunitを導入することができました。

"require-dev": {
  "phpunit/phpunit": "^9.5"
}

2.phpunit.xmlの作成

vendorディレクトリと同じ階層にphpunit.xmlを作成し以下のように記載
※vendor/autoload.phpでは、マップファイル(クラスやネームスペースが定義されている配列が記述されたファイル)をrequireしています。(この場所のみrequireでの読み込みが必要)

<!-- テストの実行結果を着色する -->
<!-- テスト実行前に各ファイルをオートロード -->
<phpunit colors="true" bootstrap="vendor/autoload.php">
    <testsuites>
        <testsuite name="Sample">
<!-- テスト用のクラスがあるディレクトリを指定 -->
            <directory>tests</directory>
        </testsuite>
    </testsuites>
</phpunit>

PHPUnitでは複数のテストケースをテストスイートというグループ単位に分けることができ、定義したスイートごとにユニットテストを実行することが可能となります。また、ディレクトリの指定ではなく、以下のようにファイル単位で指定することも可能。

<testsuites>
  ・・・
  <testsuite name="Sample">
    <file>test/Sample1Test.php</file>
    <file>test/Sample2Test.php</file>
  </testsuite>
</testsuites>

3.テストケースの作成

testsディレクトリを作成し、その直下にGreetTest.phpというファイル名で簡単なテストケースを作成して実行してみます。
※メソッド名は test で始める必要がある

root@eb351c5a0b16:/var/www# mkdir tests
<?phpnamespace Vendor\App;use PHPUnit\Framework\TestCase;use Vendor\App\Greet;

class GreetTest extends TestCase
{
    /**
     * @test
     */
    public function testMultiple()
    {
        $greet = new Greet();
        $expected = "hello";
        $this->assertEquals($expected, $greet->sayHello());
    }
}

テスト対象のクラス(Greet.php)をsrcディレクトリ直下に作成する

<?php

namespace Vendor\App;

class Greet
{
    public function sayHello()
    {
        return "hello";
    }
}

テストを実行する

vendor/bin/phpunit tests

※毎回上記のコマンドを打つのは面倒なので、composer.jsonに以下のようにscriptとして登録すると、”composer test” と打つだけでテストが流れる

"scripts": {
  "test": "vendor/bin/phpunit"
},

以下のようにテストが通っていればOK

root@eb351c5a0b16:/var/www# composer test
PHPUnit 9.5.8 by Sebastian Bergmann and contributors.

. 1 / 1 (100%)

Time: 00:00.168, Memory: 4.00 MB

OK (1 test, 1 assertion)

以上になります。
次回はこの環境を用いて、GitHub ActionsでCI/CDを構築してみたいと思います。

コメント

タイトルとURLをコピーしました