Статьи

Разработка через тестирование с помощью Laravel & Doctrine

Как разработчик PHP, вы можете использовать технику разработки через тестирование (TDD) для разработки своего программного обеспечения путем написания тестов. Обычно TDD делит каждую задачу разработки на отдельные единицы. Затем пишется тест, чтобы убедиться, что устройство ведет себя так, как ожидалось.

Каждый проект, использующий разработку через тестирование, повторяет три простых шага:

  • Напишите тест для следующей функциональности, которую вы хотите добавить.
  • Напишите функциональный код, пока тест не пройдет.
  • Рефакторинг как нового, так и старого кода, чтобы он был хорошо структурирован.

Продолжайте циклически проходить эти три шага, по одному тесту за раз, наращивая функциональность системы. Тестирование поможет вам провести рефакторинг, который позволит вам со временем улучшить свой дизайн и сделает некоторые проблемы проектирования более очевидными.

Тесты, которые содержат небольшие отдельные компоненты, называются модульными тестами . В то время как модульные тесты могут выполняться независимо, если вы тестируете некоторые компоненты, когда они интегрированы с другими компонентами, вы проводите интеграционное тестирование . Третий вид тестирования — тестовые заглушки . Тестовые заглушки позволяют вам тестировать свой код без необходимости совершать реальные вызовы в базу данных.

В настоящее время, поскольку вы можете использовать современный синтаксис PHP IDE, обратная связь не имеет большого значения. Один из важных аспектов вашей разработки — убедиться, что код выполняет то, что вы ожидаете. Поскольку программное обеспечение является сложным (различные компоненты интегрированы друг с другом), было бы трудно реализовать все наши ожидания. Особенно в конце проекта, из-за вашей разработки, проект станет более сложным и, следовательно, более сложным для отладки и тестирования.

TDD проверяет, что код выполняет то, что вы ожидаете. Если что-то пойдет не так, нужно проверить только несколько строк кода. Ошибки легко найти и исправить. В TDD тест фокусируется на поведении, а не на реализации. TDD предоставляет проверенный код, который был протестирован, разработан и закодирован.

PHPUnit является стандартом де-факто для модульного тестирования PHP. По сути, это основа для написания тестов и предоставления инструментов, которые вам понадобятся для запуска тестов и анализа результатов. PHPUnit получает свою структуру и функциональность из SUnit Кента Бека.

Существует несколько различных утверждений, которые могут помочь вам проверить результаты всех видов вызовов в ваших приложениях. Иногда вам нужно быть немного более креативным, чтобы протестировать более сложную функциональность, но утверждения, предоставляемые PHPUnit, покрывают большинство случаев, которые вы хотели бы протестировать. Вот список некоторых из наиболее распространенных, которые вы найдете в своих тестах:

  • AssertTrue : проверьте ввод, чтобы убедиться, что он равен true.
  • AssertFalse : проверьте вход, чтобы убедиться, что он равен ложному значению.
  • AssertEquals : проверить результат по другому входному сигналу на совпадение.
  • AssertArrayHasKey () : сообщает об ошибке, если у массива нет ключа.
  • AssertGreaterThan : проверьте результат, чтобы увидеть, если он больше, чем значение.
  • AssertContains : проверьте, что вход содержит определенное значение.
  • AssertType : проверьте, что переменная имеет определенный тип.
  • AssertNull : проверьте, что переменная равна нулю.
  • AssertFileExists : убедитесь, что файл существует.
  • AssertRegExp : проверить ввод по регулярному выражению.

По умолчанию PHPUnit 4.0 установлен в Laravel, и вы можете запустить следующую команду, чтобы обновить его:

bash composer global require "phpunit/phpunit=5.0.*"

Файл phpunit.xml в корневом каталоге Laravel позволит вам выполнить некоторые настройки. В этом случае, если вы хотите переопределить конфигурацию по умолчанию, вы можете отредактировать файл:

« `XML

./tests/ приложение/

« `

Как видно из приведенного выше кода, я добавил пример конфигурации базы данных (не использованной в статье).

Doctrine — это ORM, который реализует шаблон отображения данных и позволяет четко отделить бизнес-правила приложения от уровня персистентности базы данных. Для настройки Doctrine существует мост, позволяющий сопоставить его с существующей конфигурацией Laravel 5. Чтобы установить Doctrine 2 в нашем проекте Laravel, мы запускаем следующую команду:

bash composer require laravel-doctrine/orm

Как обычно, пакет должен быть добавлен в app/config.php в качестве поставщика услуг:

php LaravelDoctrine\ORM\DoctrineServiceProvider::class,

Псевдоним также должен быть настроен:

php 'EntityManager' => LaravelDoctrine\ORM\Facades\EntityManager::class

Наконец, мы публикуем конфигурацию пакета с:

bash php artisan vendor:publish --tag="config"

Прежде всего, вы должны знать о светильниках . Светильники используются для загрузки контролируемого набора данных в базу данных, которая нам нужна для тестирования. К счастью, в Doctrine 2 есть библиотека, которая поможет вам написать приспособления для Doctrine ORM.

Чтобы установить пакет приспособлений в наше приложение Laravel, нам нужно выполнить следующую команду:

bash composer require --dev doctrine/doctrine-fixtures-bundle

Давайте создадим наш светильник в tests/Fixtures.php :

« `php namespace Test; использовать Doctrine \ Common \ Persistence \ ObjectManager; использовать Doctrine \ Common \ DataFixtures \ FixtureInterface; используйте приложение \ Entity \ Post;

Класс Fixtures реализует FixtureInterface {/ ** * Загрузка записей Post * @param ObjectManager $ manager * @return void * / публичная функция load (ObjectManager $ manager) {$ Post = new Post ([‘title’ => ‘hello world’ , ‘тело’ => ‘это тело’]); $ Manager-> сохраняются (Post $); $ Manager-> заподлицо (); }}

« `

Как видите, ваш класс FixtureInterface должен реализовывать FixtureInterface и должен иметь метод load(ObjectManager $manager) . Doctrine2 — это классы PHP, где вы можете создавать объекты и сохранять их в базе данных. Для автозагрузки наших приборов в Laravel нам нужно изменить composer.json в нашем корне Laravel:

json ... "autoload-dev": { "classmap": [ "tests/TestCase.php", "tests/Fixtures.php" //added here ] }, ...

Затем запустите:

bash composer dump-autoload

Давайте создадим наш тестовый файл в каталоге тестов DoctrineTest.php .

« `php namespace Test; использовать приложение; используйте App \ Entity \ Post; использовать Doctrine \ Common \ DataFixtures \ Executor \ ORMExecutor; использовать Doctrine \ Common \ DataFixtures \ Purger \ ORMPurger; использовать Doctrine \ Common \ DataFixtures \ Loader; использовать App \ Repository \ PostRepo;

класс doctrineTest extends TestCase {private $ em; закрытое хранилище $; приватный загрузчик $; публичная функция setUp () {parent :: setUp (); $ this-> em = App :: make (‘Doctrine \ ORM \ EntityManagerInterface’); $ this-> repository = new PostRepo ($ this-> em); $ this-> executor = new ORMExecutor ($ this-> em, новый ORMPurger); $ this-> loader = new Loader; $ this-> loader-> addFixture (new Fixtures); }

В setUp() я ORMExecutor экземпляр ORMExecutor и Loader. Мы также загружаем класс Fixtures мы только что реализовали.

Не забывайте, что аннотация /** @test */ очень важна, и без этого phpunit будет возвращать No tests found in class ошибке No tests found in class .

Чтобы начать тестирование в корне нашего проекта, просто запустите команду:

bash sudo phpunit

Результат будет:

« `bash PHPUnit 4.6.6 от Себастьяна Бергмана и его авторов.

Конфигурация читается из /var/www/html/laravel/phpunit.xml. Время: 17,06 секунд, Память: 16.00M OK (1 тест, 1 утверждение) « `

Если вы хотите обмениваться объектами между приборами, можно легко добавить ссылку на этот объект по имени, а затем ссылаться на нее, чтобы сформировать отношение. Вот пример:

« `php namespace Test; использовать Doctrine \ Common \ Persistence \ ObjectManager; использовать Doctrine \ Common \ DataFixtures \ FixtureInterface; используйте приложение \ Entity \ Post;

Класс PostFixtures реализует FixtureInterface {/ ** * Загрузка пользовательских приспособлений * * @param ObjectManager $ manager * @return void * / публичная функция load (ObjectManager $ manager) {$ postOne = new Post ([‘title’ => ‘hello’ , ‘тело’ => ‘это тело’]); $ postTwo = new Post ([‘title’ => ‘hello there’, ‘body’ => ‘это body two’]); $ Manager-> сохраняются ($ postOne); $ Manager-> сохраняются ($ postTwo); $ Manager-> заподлицо ();

и фиксация Комментарий:

« `php namespace Test; использовать Doctrine \ Common \ Persistence \ ObjectManager; использовать Doctrine \ Common \ DataFixtures \ FixtureInterface; используйте приложение \ Entity \ Post;

Класс CommentFixtures реализует FixtureInterface {/ ** * Загрузка пользовательских приспособлений * * @param ObjectManager $ manager * @return void * / публичная функция load (ObjectManager $ manager) {$ comment = new Comment ([‘title’ => ‘hello’ , ’email’ => ‘[email protected]’, ‘text’ => ‘хороший пост’]); $ Comment-> setPost ($ this-> getReference ( ‘нового пост’)); // загрузить сохраненную ссылку $ manager-> persist ($ comment); $ Manager-> заподлицо (); // сохранить ссылку на новое сообщение для комментария к записи $ this-> addReference (‘new-post’, $ postOne); }} « `

С помощью двух методов getReference() и setReference() вы можете делиться объектами между приборами.

Если вам важно упорядочить приборы, вы можете легко упорядочить их с getOrder метода getOrder в ваших приборах следующим образом:

php public function getOrder() { return 5; // number in which order to load fixtures }

Обратите внимание, что порядок относится к классу Loader.

Одной из важных особенностей светильников является их способность решать проблемы зависимости. Единственное, что вам нужно добавить, это метод в вашем приборе, как я сделал ниже:

php public function getDependencies() { return array('Test\CommentFixtures'); // fixture classes fixture is dependent on }

Это всего лишь описание тестовой разработки с Laravel 5 и PHPUnit. При тестировании репозиториев неизбежно попадание в базу данных. В этом случае Doctrine крепления важны.