こんにちは。よっしーです(^^)
今日は、PHPUnitの環境構築についてご紹介します。
背景
PHPで単体テストを実施したいと思い、PHPUnitを実行できる環境を構築したので、その時の方法を記事にしました。
今回は、PHPのフレームワークにPHPUnitを導入した話ではなく、PHPの実行環境にPHPUnitを導入した方法をご紹介しています。
修正内容
下記のファイルを作成します。下記の各セクションに各ファイルの修正内容を記載しています。
new file: 19_learn_phpunit/compose.yml
new file: 19_learn_phpunit/composer.json
new file: 19_learn_phpunit/php/Dockerfile
new file: 19_learn_phpunit/src/Greeter.php
new file: 19_learn_phpunit/tests/GreeterTest.php
ディレクトリ構造は下記のようになっています。
19_learn_phpunit
├── compose.yml
├── composer.json
├── php
│ └── Dockerfile
├── src
│ └── Greeter.php
└── tests
└── GreeterTest.php
compose.yml
下記の内容で新規作成します。
version: '3.8'
services:
php-cmd:
build: ./php
container_name: php-cmd
volumes:
- .:/work
composer.json
下記の内容で新規作成します。
{
"autoload": {
"files": ["./src/Greeter.php"]
},
"require-dev": {
"phpunit/phpunit": "^10.2"
}
}
php/Dockerfile
下記の内容で新規作成します。
FROM ubuntu:23.04
RUN apt update \
&& apt upgrade -y
RUN apt install -y unzip
RUN apt install -y php-cli
RUN apt install -y php-json
RUN apt install -y php-mbstring
RUN apt install -y php-xml
RUN apt install -y php-pcov
RUN apt install -y php-xdebug
RUN apt clean
COPY --from=composer /usr/bin/composer /usr/bin/composer
WORKDIR /work
src/Greeter.php
下記の内容で新規作成します。
<?php declare(strict_types=1);
final class Greeter
{
public function greet(string $name): string
{
return 'Hello, ' . $name . '!';
}
}
tests/GreeterTest.php
下記の内容で新規作成します。
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class GreeterTest extends TestCase
{
public function testGreetsWithName(): void
{
$greeter = new Greeter;
$greeting = $greeter->greet('Alice');
$this->assertSame('Hello, Alice!', $greeting);
}
}
動作確認
上記のファイル群が用意できたら、下記のコマンドを実施します。
cd 19_learn_phpunit
docker compose build
docker compose run -it --rm php-cmd composer install
docker compose run -it --rm php-cmd composer dumpautoload
docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/GreeterTest.php
下記の結果になっていれば成功です。
% docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/GreeterTest.php
[+] Building 0.0s (0/0)
[+] Building 0.0s (0/0)
PHPUnit 10.2.6 by Sebastian Bergmann and contributors.
Runtime: PHP 8.1.12-1ubuntu4.2
. 1 / 1 (100%)
Time: 00:00.035, Memory: 6.00 MB
解説
composer.json
このコードは、PHPプロジェクトに対するComposerの設定ファイルである composer.json
に関する内容です。ComposerはPHPの依存関係管理ツールであり、パッケージのインストールや自動ロードなどをサポートします。
以下は、各セクションの詳細な説明です:
- autoload セクション:
"autoload": {
"files": ["./src/Greeter.php"]
}
autoload
セクションでは、クラスやファイルの自動ロードを定義します。files
キーを使用して、指定されたファイルが自動的に読み込まれるようになります。今回の設定では、./src/Greeter.php
ファイルが自動的にロードされます。通常、プロジェクト内のクラスファイルを自動的にロードするために使用されます
- require-dev セクション
"require-dev": {
"phpunit/phpunit": "^10.2"
}
require-dev
セクションでは、開発時にのみ必要な依存関係を定義します。つまり、本番環境では必須ではないが、開発やテストを行う際に必要なパッケージを指定します。この例では、phpunit/phpunit
パッケージが定義されています。PHPUnitはPHPのユニットテストフレームワークであり、プロジェクトのテストを効率的に実行するために使用されます。^10.2
は、phpunit/phpunit
パッケージのバージョンを10.2以上かつ11.0未満という意味で、Composerは10.2以上で11.0未満の最新バージョンを自動的に解決してインストールします。
これらの設定を持つ composer.json
ファイルをプロジェクトに含めることで、Composerは定義された依存関係を管理し、自動的に必要なパッケージをインストールおよびロードすることができます。
php/Dockerfile
このDockerfileは、Ubuntu 23.04をベースとして、PHPの実行に必要な依存関係をインストールし、Composerをセットアップするためのコマンドを含んでいます。以下は、各行の内容の解説です:
FROM ubuntu:23.04
: Dockerイメージのベースとして、Ubuntu 23.04の公式Dockerイメージを使用します。このイメージを基にして、以降のコマンドが実行されます。RUN apt update && apt upgrade -y
: イメージ内のUbuntuパッケージリストを更新し、インストール可能なアップデートがある場合にそれらを適用します(-yフラグはすべてのプロンプトに対して”yes”を自動的に返すため、対話型プロンプトを回避します)。RUN apt install -y unzip
:unzip
パッケージをインストールします。これはzipアーカイブを解凍するのに必要です。RUN apt install -y php-cli
:php-cli
パッケージをインストールします。これはPHPコマンドラインインターフェース(CLI)の実行に必要です。RUN apt install -y php-json
:php-json
パッケージをインストールします。これはPHPでJSONをサポートするために必要です。RUN apt install -y php-mbstring
:php-mbstring
パッケージをインストールします。これはマルチバイト文字列関数をサポートするために必要です。RUN apt install -y php-xml
:php-xml
パッケージをインストールします。これはPHPのXML関連機能をサポートするために必要です。RUN apt install -y php-pcov
:php-pcov
パッケージをインストールします。これはPHPのコードカバレッジ(Code Coverage)を計測するために必要です。RUN apt install -y php-xdebug
:php-xdebug
パッケージをインストールします。これはPHPのデバッグをサポートするために必要です。RUN apt clean
: インストール時に生成されたキャッシュや一時ファイルを削除してイメージサイズを小さくします。COPY --from=composer /usr/bin/composer /usr/bin/composer
: これは別のDockerイメージ(composer
イメージ)からcomposer
コマンドをコピーしてきて、最終的なイメージ内に配置します。これにより、Composerがイメージ内で利用可能になります。WORKDIR /work
: 作業ディレクトリを/work
に設定します。これは後続のコマンドがこのディレクトリをベースに実行されることを意味します。
これらの手順を実行することで、Dockerイメージ内に必要なPHPの実行環境がセットアップされ、Composerも利用可能な状態になります。
src/Greeter.php
このコードは、PHPのクラス Greeter
を定義しています。Greeter
クラスは、与えられた名前に基づいて挨拶を生成するためのメソッドを持っています。
以下は、コードの詳細な解説です:
<?php declare(strict_types=1);
: これは、スクリプト全体で厳密な型宣言を有効にするための宣言です。strict_types=1
により、引数と返り値の型が厳密にチェックされるようになります。final class Greeter
:Greeter
クラスはfinal
キーワードで修飾されています。これにより、他のクラスがGreeter
を継承することを防ぎます。クラスをfinal
にすると、そのクラス自体は継承できなくなります。public function greet(string $name): string
:greet
メソッドは、パラメータ$name
を受け取り、string
型の値を返すことを宣言しています。: string
はメソッドの返り値の型宣言を示しており、このメソッドは必ず文字列を返すことを示します。return 'Hello, ' . $name . '!';
:greet
メソッドの実装部分です。渡された名前を使用して、「Hello, 名前!」という挨拶の文字列を返します。例えば、$name
が “John” の場合、このメソッドは “Hello, John!” を返します。
このクラスの特徴は、厳密な型宣言と final
キーワードの使用です。厳密な型宣言は、バグを事前に検知しやすくし、より堅牢なコードを作成するのに役立ちます。また、final
キーワードを使用することで、クラスの拡張を制限し、意図せぬ挙動を防ぐことができます。
tests/GreeterTest.php
このコードは、Greeter
クラスのユニットテストを行うためのPHPUnitテストクラス GreeterTest
を定義しています。PHPUnitはPHPのユニットテストフレームワークであり、コードのテストと検証を行うために使用されます。
以下は、テストクラスの詳細な解説です:
<?php declare(strict_types=1);
: これは、スクリプト全体で厳密な型宣言を有効にするための宣言です。テストコードでも型宣言を厳密に行い、意図しないエラーを事前に検知できるようにしています。use PHPUnit\Framework\TestCase;
:PHPUnit\Framework\TestCase
クラスをインポートしています。これはPHPUnitテストクラスのベースクラスであり、PHPUnitの機能を利用できるようにします。final class GreeterTest extends TestCase
:GreeterTest
クラスは、TestCase
クラスを継承しています。これにより、PHPUnitのテスト機能を利用できます。テストクラスはfinal
キーワードで修飾されているため、他のクラスがこのテストクラスを継承することはできません。public function testGreetsWithName(): void
:testGreetsWithName
メソッドは、void
型を返すテストメソッドです。テストメソッドは、メソッド名がtest
で始まることに注意してください。このメソッドでは、Greeter
クラスのgreet
メソッドが適切に動作しているかをテストします。$greeter = new Greeter;
:Greeter
クラスのインスタンス$greeter
を作成しています。テスト対象のクラスであるGreeter
クラスのインスタンスを作成することで、テストを行う準備が整います。$greeting = $greeter->greet('Alice');
:$greeter
インスタンスのgreet
メソッドを'Alice'
という引数で呼び出し、その結果を$greeting
変数に格納しています。これにより、greet
メソッドの振る舞いを検証するためのテストデータを得ます。$this->assertSame('Hello, Alice!', $greeting);
:assertSame
メソッドは、2つの値が同じであることを検証します。このテストでは、$greeting
変数が'Hello, Alice!'
と等しいかどうかをチェックしています。つまり、Greeter
クラスのgreet
メソッドが正しく'Hello, Alice!'
という挨拶の文字列を生成するかを検証しています。
このテストコードは Greeter
クラスの greet
メソッドが期待通りの振る舞いを示しているかを確認するものです。テストは phpunit
コマンドを使って実行され、テストの結果が表示されます。成功すると “OK” と表示され、失敗すると詳細なエラーメッセージとともに失敗の情報が表示されます。
動作確認で使用しているコマンド
このコマンドは、PHPのプロジェクトをDockerコンテナで実行し、PHPUnitを使用してGreeterTest.php
というテストファイルを実行するためのものです。以下は各コマンドの説明です:
cd 19_learn_phpunit
: このコマンドは、ターミナルのカレントディレクトリを19_learn_phpunit
に移動します。おそらく、これはPHPUnitテストのためのプロジェクトディレクトリであると想定されます。docker compose build
: これはDocker Composeを使用して、プロジェクト内のDockerコンテナをビルドします。docker-compose.yml
ファイルに記述された設定に基づいて、必要なコンテナが構築されます。docker compose run -it --rm php-cmd composer install
: これは、Docker Composeを使用してphp-cmd
コンテナを実行し、composer install
コマンドを実行します。これにより、プロジェクトの依存関係がインストールされます。--rm
フラグは、コンテナの実行が終了したら自動的にコンテナを削除するためのものです。docker compose run -it --rm php-cmd composer dumpautoload
: これは、Docker Composeを使用してphp-cmd
コンテナを実行し、composer dumpautoload
コマンドを実行します。これにより、Composerのオートロードを更新して、クラスの自動読み込みが有効になります。docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/GreeterTest.php
: これは、Docker Composeを使用してphp-cmd
コンテナを実行し、PHPUnitを使用してtests/GreeterTest.php
というテストファイルを実行します。これにより、GreeterTest.php
内のテストが実行され、PHPUnitによるテストの結果が表示されます。
上記のコマンドの実行により、PHPプロジェクトのビルドとテストがDockerコンテナ内で行われます。PHPUnitによるテストが成功すると、テスト結果が表示されるでしょう。失敗する場合は、問題のあるテストが特定され、エラーメッセージが表示されます。
おわりに
今日は、PHPUnitの環境構築についてご紹介しました。
本記事でご紹介したソースは、下記のリポジトリにあります。
https://github.com/Gate-Yossi/Ran/releases/tag/v202308.06
何か質問や相談があれば、遠慮なくコメントしてください。また、エンジニア案件についても、いつでも相談にのっていますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント