Есть правила для автозагрузки ( http://www.php-fig.org/psr/psr-0/ ) и тестирование PHPunit ( https://phpunit.de/manual/current/en/organizing-tests.html ). Отдельно они просты в реализации, но объединять их нет.
Я также прочитал тему PHPUnit лучшие практики для организации тестов но применение ответа не очевидно для меня. При написании собственного проекта у меня было несколько проблем, которые, вероятно, имеют одинаковое происхождение в организации кода. Я хотел бы иметь рецепты для простого примера. Поэтому я делаю свой вопрос довольно большим.
я использую IDE NetBeans 7.4 потому что он поддерживает PHPUnit, SVN и Doxygen (но мне не хватает опыта использования этой IDE).
проект свойства являются
Есть первая проблема. NetBeans блокирует зеркальную структуру src / tests с самого начала. Здесь нет Просматривать кнопка для Исходная папка. Тестовая папка должен отличаться от Исходная папка.
Я использую PHPUnit и skelgen из файлов PHAR, расположенных вне проекта.
(Tools-> Options-> PHP / PHPUnit)
У меня есть следующая структура файла в каталоге проекта
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
содержит модифицированную реализацию автозагрузки PSR-0 из https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md . Разница в том, что перед тем, как делать 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;
}
После этого я добавил Используйте Bootstrap (проект Свойства-> Тестирование / 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. У меня не работает. Без моего 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 не позволяет использовать исходную папку в качестве тестовой папки, у меня должно быть два автозагрузчика для одного и того же класса. Я не уверен, что это хорошая практика.
Автозагрузка не должна беспокоить других программистов, работающих над тем же проектом. Я ищу что-то большее общий.
К тому же в будущем я мог бы использовать сторонний код. Нужно ли дублировать их автозагрузчикам?
src/
а также tests/
папки должны быть на высшем уровне как vendor/
Я изучал правила автозагрузки некоторое время назад. Теперь я узнаю, что PSR-0 помечен как устаревший. Согласно PSR-4 src/
а также tests/
должны быть размещены где-то в середине пути.
Но есть практика ставить сторонний код внутри верхнего уровня vendor/
папка. Не должен src/
а также tests/
папки должны быть размещены на одном уровне.
src/
… my code
tests/
… my tests
vendor/
… third-party code
что делает всю структуру более Стиль PSR-0.
При написании кода BazTest и BarTest IDE NetBeans не намекает на методы PHPUnit
хотя оба класса расширяются \PHPUnit_Framework_TestCase
namespace MyPack\Foo;
class BarTest extends \PHPUnit_Framework_TestCase { /* ... */ }
Это потому, что я использую PHPUnit от PHAR?
Надеюсь, приведение примера сделало мои вопросы более понятными. Спасибо за чтение, и я ищу хорошие советы
Человек, что за большой вопрос. 🙂
Хорошо, давайте рассмотрим некоторые вопросы.
PHPUnit Skelgen проверяет неверный путь
Это определенно не зеркально симметрично
Правда. Это странная (и я думаю, нерешенная) проблема с skelgen.
Просто переместите созданные * тестовые файлы в правильные папки.
Тот же вопрос здесь: PHPUnit, Netbeans и Symfony2 и неправильное расположение тестов
Структура папок для вашего проекта
Да, это структура папок для работы:
src/
… my code
tests/
… my tests
vendor/
… third-party code
самозарядные вопрос:
(Без Composer): ваш автозагрузчик живет где-то в src
,
Во время загрузки вашего приложения вы требуете его, после этого автозагрузка настроена для src
папка. Все занятия в src
папка с этого момента автоматически загружается.
Теперь перейдем к тестам: во время тестовой начальной загрузки вы включаете автозагрузчик из src
и добавить src
а также test
, Это делает все классы в src
а также tests
autoloadable.
(с Composer): эта проблема не возникает, если вы работаете с Composer.
В Composer есть разделы require и require-dev для определения зависимостей вендора.
Автозагрузка генерируется автоматически, вы просто включаете файл автозагрузки Composer и выполняете (одно включение во время начальной загрузки src и одно включение во время тестовой надстройки). Если проект установлен с зависимостями разработки, они будут частью автозагрузки, в противном случае они не появятся.
Нет подсказки PHPUnit в NetBeans
Да, PHAR не анализируется и не извлекается, поэтому Netbeans не будет знать имена классов PHPUnit.
Решение 1: Извлеките ФАР.
Решение 2. Добавьте PHP с именами классов в качестве псевдонимов для руководства Netbeans. Я не знаю, есть ли кто-то рядом. Но это довольно распространенная проблема, высока вероятность того, что кто-то уже создал ее.
Решение 3: Позвольте мне снова предложить Composer: просто включите phpunit в качестве зависимости require-dev в ваш проект. Путь поставщика сканируется Netbeans, и имена классов разрешаются.
Ответ Йенса А. Коха был очень полезным. Но я хотел бы написать так, как это работает для меня.
Написание и запуск тестов PHPUnit для проекта PHP в среде IDE NetBeans 7.4.
Структура проекта
composer.json
index.php
src/
Client.php
MyPack/
Foo/
Bar.php
где
src/Client.php
содержит класс, определенный в глобальном пространстве именsrc/MyPack/Foo/Bar.php
содержит класс, определенный в MyPack\Foo
Пространство именcomposer.json
объявляет требования, то есть PHPUnit, PHPUnit Skeleton Generator и автозагрузчики для классов, определенных в src/
а также tests/
каталогиcomposer.json
{
"name": "vendor/php-project-with-tests",
"autoload": {
"psr-4": {
"": ["src/", "tests/"]
}
},
"require": {},
"require-dev": {
"phpunit/phpunit": "4.7.7",
"phpunit/phpunit-skeleton-generator": "2.0.1"}
}
Сообщите NetBeans, где содержится PHPUnit. Я использую файлы PHAR, загруженные с https://phar.phpunit.de/
tests
каталог внутри каталога проекта и использовать его в качестве тестовой папкиЭто достигает двух целей:
— сгенерировать автозагрузчик, чтобы позволить тестовым классам использовать классы src
— добавить библиотеку PHPUnit в проект для намеков
Файл начальной загрузки выполняется перед тестами. Для этого проекта vendor / autoload.php достаточно.
Тестовые классы помещены в неправильный путь
Я могу переместить их вручную
Тесты проводятся в любом случае.
PHPUnit версий 4.8.0 и 4.8.6 не работает. Я получаю сообщение
unrecognized option --run
Поэтому я должен использовать PHPUnit 4.7.7
PHPUnit Skeleton Generator 2.0.1 не может генерировать тесты. Я получаю сообщение
[InvalidArgumentException]
Commans «MyPack \ Foo \ Bar» не определен
Поэтому я должен использовать PHPUnit Skeleton Generator 1.2.1