こんにちは。やまゆです。
ということで疑問に思ってみました。
Why?
ソースコードディレクトリとテストディレクトリを分けるのが PHP の一般的な習慣です。
/
-> src/
-> Domain/
-> User/
-> UserEntity.php
-> tests/
-> Unit/
-> Domain/
-> User/
-> UserEntityTest.php
ユニットテストはクラス単位で行うことが多いため、このような構成になることがあるでしょう。
そうすると、同じディレクトリ構成が現れることになります。何が DRY か?状態です。
例えば golang は超シンプルです。
/
-> user.go
-> user_test.go
これで go test
すると、自動的にテストファイルを判別してくれます。
/
-> src/
-> Domain/
-> User/
-> UserEntity.php
-> UserEntityTest.php
つまり、これで良くない?という話です。
(もちろん、クラスをまたいだもう少し大きな IntegrationTest などは別途 integrations
等を用意する必要があると思います)
メリット
- ディレクトリに対して DRY を適用できる
- DRY はみんな大好きだと思います。同じことは繰り返したくないです。
- 実装とテストがそばにあるため行き来しやすい
- 実装する時はテストファイルと同時に開いて編集することが多いですよね
- テストがちゃんと書かれているかどうかがわかる
- テスト書き忘れ、レビュー漏れがあると厄介です
デメリット
- ランタイム実装にテスト用のコードが潜り込む危険がある
- 同じ場所にあるので、テストユーザーを作成するメソッドを間違えて本番環境向けの実装で使ってしまうかもしれません
- 対応していないライブラリがあるかもしれない
- PHP の現在のエコシステム的に、ディレクトリを分離する前提のライブラリがあってもおかしくありません
- 同じディレクトリのファイル数が倍増する
- 設計次第ですが、同じドメイン領域に存在するファイルが倍になります。閲覧性に問題が出るかもしれません
ということで、ちゃんと phpunit/psalm/phpstan/php-cs-fixer あたりの著名なライブラリがこの構成でも動くか検証してみました。
結論: いけそう
もちろん上記で出した以外のデメリットがあると思います。
しかし、なんかこっちの方が良いかもしれないな、というのが今日の感触でした。