こんにちは。よっしーです(^^)
今日は、PHPUnitで未実装のテストケースを用意する方法についてご紹介します。
前提
この記事は下記の記事をベースにしています。
背景
新しいテストケースクラスの作成に取り組む場合は、次のような空のテストメソッドを作成することから始めたい場合があります。
public function testSomething(): void
{
}
空のテストメソッドの問題点は、失敗することができず、成功したと誤解される可能性があることです。テストが実際に成功したのか、それともまだ実装されていないだけなのかがわかりません。
未完成のテストメソッドで $this->assertTrue(false) をコールしても、テストは失敗したと解釈されてしまうからです。これは、未実装のテストを成功とみなすのと同じくらい間違いです。
テストの成功を緑の光、テストの失敗を赤の光と考えるなら、テストが未完成あるいは未実装であることを示す黄色い光も必要です。
テストメソッドの中で markTestIncomplete() メソッドをコールすることで、 テストを未完成としてマークすることができます。
修正内容
下記のファイルを更新、もしくは、作成します。下記の各セクションに各ファイルの修正内容を記載しています。
new file: 19_learn_phpunit/tests/WorkInProgressTest.php
tests/WorkInProgressTest.php
下記の内容で新規作成します。
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
final class WorkInProgressTest extends TestCase
{
public function testSomething(): void
{
// Optional: Test anything here, if you want.
$this->assertTrue(true, 'This should already work.');
// Stop here and mark this test as incomplete.
$this->markTestIncomplete(
'This test has not been implemented yet.'
);
}
}
動作確認
下記のコマンドを実施します。
docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/WorkInProgressTest.php
下記の結果になれば成功です。
% docker compose run -it --rm php-cmd ./vendor/bin/phpunit tests/WorkInProgressTest.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
I 1 / 1 (100%)
Time: 00:00.073, Memory: 8.00 MB
OK, but there are issues!
Tests: 1, Assertions: 1, Incomplete: 1.
不完全なテストは、PHPUnit コマンドライン テスト ランナーの出力では I で示されます。
解説
tests/WorkInProgressTest.php
このコードは、PHPUnitを使用してテストを行うためのテストケースクラス WorkInProgressTest
が定義されています。
テストケースでは、test
で始まるメソッドを作成します。ここでは、1つのテストメソッドが定義されています。
public function testSomething(): void
: このテストメソッドは、以下のような内容を含んでいます。
$this->assertTrue(true, 'This should already work.');
: この行は、PHPUnitのassertTrue
メソッドを使用して、true
が実際にtrue
と一致することをテストしています。これは通常のテストとして機能し、成功するでしょう。$this->markTestIncomplete('This test has not been implemented yet.');
: この行は、markTestIncomplete
メソッドを呼び出して、このテストを「未完成」とマークしています。このメソッドを呼び出すと、このテストは実行されませんが、テストランナーはテストが「未完成」であることを報告します。これにより、テストが完了していないことを明示的に示すことができます。テストを実装する前に、仮のテストメソッドを作成する場合によく使用されます。
このコードを実行すると、テストランナーはテストを実行し、assertTrue
のテストは成功しますが、markTestIncomplete
により「未完成」であることがレポートされます。テストランナーは、「未完成」のテストがある場合には成功または失敗を報告せず、単に「未完成」として表示します。このようにして、テストが実装されていないことを開発者に伝えることができます。テストの実装が進んでから再度実行すると、通常のテストとして成功するはずです。
markTestIncompleteを使用する理由
markTestIncomplete
メソッドは、PHPUnitによるテスト実行中にテストを「未完成」とマークするためのメソッドです。このメソッドを使用する主な理由は以下の通りです:
- 仮のテストの作成: テスト駆動開発(Test-Driven Development; TDD)などのアプローチで、まだ実装されていない機能やコードに対してテストケースを作成する場合に便利です。このようにして、まだ実装されていない部分のテストを先に書くことができます。テストケースが実際のコードの開発よりも先行して作成されるため、テストが何を期待しているかを開発者に明確に示すことができます。
- プロトタイピング: まだ機能の詳細な実装を行っていない段階で、一部の機能の挙動をテストするために使用されます。プロトタイプ段階では、まだ完全な実装ができていないかもしれませんが、テストを用意しておくことで、要件に基づいてどのような挙動を期待しているかを表現できます。
- テストのスキップ: 特定の条件が満たされない場合に、そのテストを一時的にスキップするために使用されることもあります。たとえば、あるテストが特定の環境でしか実行できない場合や、依存するコンポーネントが利用できない場合などが考えられます。
- 進行中の開発: コードの開発が進行中で、まだ完全な実装ができていない場合に、一部のテストを「未完成」としてマークしておくことができます。これにより、開発者はどの部分がまだ実装されていないかを把握しやすくなります。
markTestIncomplete
メソッドを使用することで、テストケースが未完成であることを明示的に示すことができます。テストランナーは、「未完成」のテストがある場合には成功または失敗を報告せず、単に「未完成」として表示します。これにより、テストの開発者が、まだ実装されていない箇所や要件を把握し、優先順位を付けて開発を進めることが容易になります。
おわりに
今日は、PHPUnitで未実装のテストケースを用意する方法についてご紹介しました。
本記事でご紹介したソースは、下記のリポジトリにあります。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント