🗂

PHP でもアーキテクチャテストしたい!

2022/12/15に公開

BABYJOB で私たちが開発している保活サービス「えんさがそっ♪」ではアーキテクチャテストを導入し、アーキテクチャの品質担保を行っています。

アーキテクチャテストとは?

  • アプリケーションを構成するクラスの依存関係や、アプリケーション固有の実装ルールをコードとして表現し、自動テストすること
  • 自動化により、一定の強制力をもってアーキテクチャの設計品質を担保し続けることができる

なぜアーキテクチャテストが必要か?

  • アーキテクチャはソフトウェアの構造についての "ガイドライン" (ルール、取り決め)であるがゆえ、壊れやすい
  • アーキテクチャに関する知識の属人化・暗黙知化により、コードレビューで問題が発見されづらい

PHP でアーキテクチャテストする方法

アーキテクチャテスト・フレームワーク

PHP では下記のようなアーキテクチャテスト・フレームワークが存在し、これらを活用します。

→ この記事では phpat を使ったアーキテクチャテストを紹介します!

phpat とは

  • みんな大好き PHPStan の拡張として実装されたアーキテクチャテスト・フレームワーク
  • メソッドチェーンを利用した DSL によりアーキテクチャテストをコードとして実装できる
  • クラス同士の依存関係のテストに加えて、クラスが期待するインターフェイスを implements しているか、というような実装ルールもチェックできる
  • 「禁止」を意味するアーキテクチャテストが実装しやすい

アーキテクチャテストの具体例

    /**
     * オニオンアーキテクチャー(依存関係を逆転したレイヤードアーキテクチャー)では、
     * すべてのクラス(ただし、インフラストラクチャ自身を除く)は「インフラストラクチャ」に依存しない。
     */
    public function testAnyClassShouldNotDependOnInfrastructure(): Rule
    {
        return PHPat::rule()
            ->classes(Selector::namespace('App'))
            ->excluding(
                Selector::namespace('App\Infrastructure')
            )
            ->shouldNotDependOn()
            ->classes(Selector::namespace('App\Infrastructure'));
    }
    /**
     * オニオンアーキテクチャー(依存関係を逆転したレイヤードアーキテクチャー)では、
     * 「ドメイン」は他のレイヤー(ただし、ドメイン自身を除く)に依存しない。
     */
    public function testDomainShouldNotDependOnOtherLayer(): Rule
    {
        return PHPat::rule()
            ->classes(Selector::namespace('App\Domain'))
            ->shouldNotDependOn()
            ->classes(Selector::namespace('App'))
            ->excluding(
                Selector::namespace('App\Domain')
            );
    }
    /**
     * 「ドメイン」は特定の Web アプリケーションフレームワークに依存しない。
     */
    public function testDomainShouldNotDependOnFramework(): Rule
    {
        return PHPat::rule()
            ->classes(Selector::namespace('App\Domain'))
            ->shouldNotDependOn()
            ->classes(Selector::namespace('Illuminate'));
    }

最後に

  • PHP_CodeSniffer や PHPMD, PHPStan などの静的解析ツールやユニットテストと同様、アーキテクチャテストもプロジェクト初期から組み込んでおくと、アーキテクチャの品質に対して安心感を担保しながら開発を進めることが出来るため、とてもオススメです 🏅
  • また、プロジェクトの途中からアーキテクチャテストを導入する場合も、phpat の場合は PHPStan のベースラインの仕組みで既存のエラーを一旦許容しながら導入できるため、プロジェクトの途中からでもアーキテクチャの問題点の発見、リファクタリングに活用できます

参考

アーキテクチャテストについての記事

アーキテクチャテストについての登壇資料

BABYJOB テックブログ

Discussion