自動ロード ( http://www.php-fig.org/psr/psr-0/ ) と PHPunit テスト ( https://phpunit.de/manual/current/en/organizing-tests.html )にはルールがあります。個別に実装するのは簡単ですが、それらを組み合わせるのは簡単ではありません。
テストを整理するためのPHPUnitのベストプラクティスのトピックも読みましたが、答えを適用することは私には明らかではありません。私自身のプロジェクトを書いているときに、おそらくコード構成に同じ起源を持ついくつかの問題がありました。本当に簡単な例のレシピがあればいいのにと思います。したがって、私は自分の質問をかなり大きくします。
サンプルプロジェクト
PHPUnit、SVN、および Doxygen をサポートしているため、私はNetBeans IDE 7.4を使用しています (ただし、その IDE を使用した経験はありません)。
プロジェクトのプロパティは
- プロジェクト フォルダー: C:\xampp\htdocs\myapps\PhpProject1
- ソースフォルダー: C:\xampp\htdocs\myapps\PhpProject1
- テスト フォルダー: C:\xampp\htdocs\myapps\PhpProject1\tests
最初の問題があります。NetBeans は、ミラーの src/tests 構造を最初からブロックします。Source Folderの [ Browse ] ボタンはありません。Test フォルダはSource フォルダとは異なる必要があります。
プロジェクトの外にある PHAR ファイルから PHPUnit と skelgen を使用します。(ツール->オプション->PHP/PHPUnit )
- PHPUnit スクリプト: C:\xampp\phar\phpunit.phar
- スケルトン ジェネレーター スクリプト: C:\xampp\phar\phpunit-skelgen-1.2.1.phar
プロジェクトディレクトリに次のファイル構造があります
index.php
src/
Client.php
srcAutoload.php
MyPack/
Foo/
Bar.php
Quu/
Baz.php
以来src
、名前空間ではありません
- ファイル
src/MyPack/Foo/Bar.php
にはクラスが含まれていますMyPack\Foo\Bar
- ファイル
src/MyPack/Quu/Baz.php
にはクラスが含まれていますMyPack\Qoo\Baz
- ファイル
src/Client.php
にはクラスが含まれていますClient
srcAutoload.php
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.mdからの変更された PSR-0 自動ロード実装が含まれています。違いは、実行前require()
に PSR-0 ファイル名の前にsrc/
$fileName = 'src' . DIRECTORY_SEPARATOR . $fileName;
テスト生成とオートロードの問題
とクラスにツール/テストの作成(コンテキストメニューから)を使用しましたが、最終的に次の構造になりますBar
Baz
index.php
src/
Client.php
srcAutoload.php
MyPack/
Foo/
Bar.php
Quu/
Baz.php
tests/
src/
BarTest.php
BazTest.php
MyPack/
Foo/
Quu/
それは間違いなくミラー対称ではありません。さらに、生成されたテストは、テストしているクラスをロードする方法を知りません。
Fatal error: Class 'MyPack\Foo\Bar' not found in C:\xampp\htdocs\myapps\PhpProject1\tests\src\BarTest.php on line 20
オートロードの私の回避策
前述のように、テスト ランナーにはプロジェクトとは異なる作業ディレクトリがあります。したがって、テスト用のオートローダーは別の完全なファイル名を作成する必要があります。PSR-0 オートローダーを複製し、名前を付けて保存し、tests/srcAutoloadFromTests.php
別のプレフィックスを追加しました
/// after PSR-0 implementation code
/// I have PSR-0 $fileName
/* Escaping from tests subfolder by "../" prefix*/
$fromTests = '..' . DIRECTORY_SEPARATOR;
/* Prefixing full filename with "src/" */
$fileName = $fromTests . 'src' . DIRECTORY_SEPARATOR . $fileName;
if (is_file($fileName)) {
require $fileName;
}
その後、Use Bootstrap (Project Properties->Testing/PHPUnit ) を追加しました。ファイルtests/bootstrap.php
に含まれるもの:
require_once 'srcAutoloadFromTests.php';
このソリューションにより、PHPUnit はテストを実行しますが、私には見苦しく見えます。
より具体的な質問
ミラーリングsrc/
がtests/
オートロードに役立たないのはなぜですか?
正しいフォルダーを作成してファイルを移動することにより、ミラーリングされた構造を手動で作成しました。
index.php
src/
Client.php
srcAutoload.php
MyPack/
Foo/
Bar.php
Quu/
Baz.php
tests/
bootstrap.php
srcAutoloadFromTests.php
MyPack/
Foo/
BarTest.php
Quu/
BazTest.php
https://phpunit.de/manual/current/en/organizing-tests.html によると、PHPUnit は test ディレクトリを再帰的にトラバースすることで、テストを自動的に検出して実行できます。私にはうまくいきません。my がないsrcAutoloadFromTests.php
と、以前のミラー化されていない構造と同じエラーが発生します。
Fatal error: Class 'MyPack\Foo\Bar' not found in C:\xampp\htdocs\myapps\PhpProject1_1\tests\MyPack\Foo\BarTest.php on line 20
自動読み込みコードの重複について
NetBeans ではソース フォルダーをテスト フォルダーとして使用できないため、同じクラスに対して 2 つのオートローダーが必要です。それが良い習慣かどうかはわかりません。
オートロードは、同じプロジェクトで作業している他のプログラマーを悩ませるべきではありません。もっと一般的なものを探します。
また、将来的にはサードパーティのコードを使用できます。彼らのオートローダーも複製する必要がありますか?
src/
およびtests/
フォルダは最上位にする必要がありますvendor/
私はしばらく前にオートローディングのルールを学んでいます。src/
PSR-0 は PSR-4 に従って非推奨としてマークされており、パスの途中にtests/
配置する必要があることがわかりました。
ただし、サードパーティのコードを最上位vendor/
フォルダー内に配置する慣行があります。src/
とtests/
フォルダを同じレベルに配置しないでください。
src/
… my code
tests/
… my tests
vendor/
… third-party code
これにより、構造全体がよりPSR-0スタイルになります。
NetBeans での PHPUnit のヒントなし
BazTest および BarTest コードを記述している間、NetBeans IDE は PHPUnit メソッドをヒントしませんが、両方のクラスが拡張されています。\PHPUnit_Framework_TestCase
namespace MyPack\Foo;
class BarTest extends \PHPUnit_Framework_TestCase { /* ... */ }
PHAR の PHPUnit を使っているからでしょうか。
例を引用することで、私の質問がより明確になったことを願っています。読んでくれてありがとう、私は良いアドバイスを探しています