SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

PHPカンファレンス実行委員プレゼンツ PHPの最前線

身近なツールで始めるコードリーディング入門~「PHPUnit」の場合

PHPカンファレンス実行委員プレゼンツ PHPの最前線 第2回


  • X ポスト
  • このエントリーをはてなブックマークに追加

 PHPに関する日本最大のカンファレンスである「PHPカンファレンス2024」が2024年12月22日(日)に開催されます。カンファレンス盛り上げ企画として、開催までの5カ月間にわたりPHPの技術記事の連載を企画しました。この記事をお読みの皆さんには、PHPのさまざまな技術に触れながらカンファレンス当日を楽しみにしていただければと思います。 第2回目の今回は、PHPプログラマのための単体テストフレームワーク「PHPUnit」のコードを読んでみましょう。

  • X ポスト
  • このエントリーをはてなブックマークに追加

PHPUnitとは

 テストコードは、他の開発者のための仕様の明文化、バグの早期発見、そしてより美しい設計を実現するための重要なツールです。これにより、開発者は安心してプロダクトコードを改善・変更することができます。ソフトウェア開発において、テストコードを書くことは品質保証の要であり、開発者としての責任でもあります。

 PHPのための単体テストフレームワーク「PHPUnit」は、私たちPHPプログラマのプロダクトコードの品質を向上させるために欠かせないツールです。これはSebastian Bergmann氏によって開発され、オープンソースソフトウェア(OSS)として提供されています。PHPUnitは単体テストの作成から、テストの実行、そして結果の分析までをサポートします。

 PHPUnitのリポジトリはGitHubで公開されており、誰でもそのコードを参照したり、コントリビュートしたりすることができます。PHPUnit 11は2024年2月2日にリリースされており、日々活発に開発・Issueによる議論が進められています。

PHPUnitのコードを読んでみよう

 普段使用しているフレームワークやライブラリのコードを読むことは、内部挙動に対する不安を解消し、適切な設計について理解を深める絶好の機会です。数年前、内部挙動に関連するバグに直面した経験から、フレームワークの内部までしっかりと読み解くことの重要性を知りました。それ以来、コードリーディングの機会を意識的に増やし、理解を深めています。

 今回は、皆さんと一緒に「日常的に使用するライブラリのコードを読み解く」というテーマに取り組みます。「どうしてここはこういう動きをするのだろう?」という疑問を抱くことは、貴重な体験です。

 突然ですが、PHPUnitは、テストが成功すると「.」、失敗すると「F」(Failed)と表示されます(参考:PHPUnitのドキュメント)。

 普段通りテストを回していた私はふと、「これらの記号はどのようなプロセス、どのような内部処理がされて表示されるのだろう」、と疑問に思いました。

 このような小さな疑問は、コードリーディングをする重要なシグナルです。

 今回はPHPUnitのコードを実際に読みながら、「.」や「F」といった記号がどのように生成され、CLIに表示されるまでの過程を探っていきます。このプロセスを通じて、OSSのコードリーディングの一例を示し、どのように読み進めていけば良いかについても触れていきます。

 本記事の説明で用いるPHPUnitのバージョンは11.3.0です。

PHPUnitを動かし「.」「F」を表示させてみよう

 まずは、手元でPHPUnitを動かしてみましょう。プロジェクトを作りComposerを使ってPHPUnitをインストールします。そして以下のような簡単なPHPプログラムとテストコードを書いてみます。

php:src/Hello.php
<?php
declare(strict_types=1);

namespace App;

// src/Hello.php
class Hello
{
    public function hello(string $name): string
    {
        if ($name === '') {
            throw new \RuntimeException('Name cannot be empty.');
        }
        return 'Hello ' . $name . '!!';
    }
}
php:tests/HelloTest.php
<?php
declare(strict_types=1);

namespace AppTest;

use App\Hello;
use PHPUnit\Framework\TestCase;

// tests/HelloTest.php
class HelloTest extends TestCase
{
    public function testHello(): void
    {
        $actual = (new Hello())->hello('asumikam');

        // 成功するテスト
        $this->assertSame('Hello asumikam!!', $actual);
    }

    public function testException(): void
    {
        $this->expectException(\RuntimeException::class);

        (new Hello())->hello('');
    }

    public function testHelloFailed(): void
    {
        $actual = (new Hello())->hello('asumikam');

        // 失敗するテスト
        $this->assertNull($actual);
    }
}

 では、テストを実行してみましょう。

# 「tests/」ディレクトリのテストを回すコマンド
$ vendor/bin/phpunit tests/
PHPUnit 11.3.0 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.21

..F                                                                 3 / 3 (100%)

Time: 00:00.014, Memory: 8.00 MB

There was 1 failure:

1) AppTest\HelloTest::testHelloFailed
Failed asserting that 'Hello asumikam!!' is null.

/my_project/tests/HelloTest.php:31

FAILURES!
Tests: 3, Assertions: 3, Failures: 1.

 テストコードの進捗結果である「.」「.」「F」がCLIに表示されました。

次のページ
どのようにテストが実行されているか

関連リンク

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
PHPカンファレンス実行委員プレゼンツ PHPの最前線連載記事一覧
この記事の著者

asumikam(アスミ)

 株式会社リンケージのWebアプリケーションエンジニア。PHPカンファレンス小田原 実行委員長。 カンファレンスへの参加をきっかけに、日々の学びや失敗談をアウトプットするのが好きになり、ついにはカンファレンス主催まで至る。主にPHP系やアジャイル系のカンファレンスで登壇。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/20106 2024/09/10 17:59

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング