Библиотека фронт-контроллера PHP с поддержкой модульного тестирования - PullRequest
12 голосов
/ 08 июня 2011

Я ищу (маленькую) библиотеку, которая поможет мне безошибочно реализовать фронт-контроллер для моего проекта pet * и отправлять запросы в классы с одним контроллером. Фронт-контроллер / диспетчер и классы контроллера должны быть полностью единообразными без отправки HTTP-запросов.

Требования

  • PSR-0 совместимый
  • устанавливается через собственный канал PEAR
  • поддержка модульного тестирования:
    • проверка правильности отправки заголовков HTTP
    • ловит выходные данные для проверки в модульных тестах
    • желательно вспомогательные методы PHPUnit для проверки вывода (для разных типов вывода, т. Е. HTML, XML, JSON)
    • позволяет устанавливать входящие заголовки HTTP, параметры GET и POST и файлы cookie без фактического выполнения запросов HTTP
  • должен быть пригоден для использования автономно - без абстракции db, шаблонов и так, чтобы все фреймворки обеспечивали

Фон

SemanticScuttle, приложение, которое должно получить надлежащую поддержку "C", является существующим работающим приложением. Библиотека должна сливаться с ней и работать с существующей структурой и классами. Я не буду переписывать его так, чтобы он соответствовал конкретной требуемой структуре каталогов.

В приложении уже есть юнит-тесты, но на основе HTTP-запросов, которые делают их медленными. Кроме того, текущий старый способ иметь несколько десятков файлов .php в каталоге www не является наиболее управляемым решением, поэтому необходимо вводить надлежащие классы контроллеров. Всего будет около 20-30 контроллеров.

Предыдущий опыт

В целом, я был очень доволен Zend Framework для некоторых предыдущих проектов, но у него есть несколько недостатков:

  • не подлежит установке в Pear, поэтому я не могу использовать его в качестве зависимости в моих приложениях для установки в Pear *
  • доступно только для одной полной загрузки, поэтому мне нужно вручную извлечь из нее необходимые биты - для каждого отдельного обновления ZF.
  • Хотя для контроллеров ZF поддерживается модульное тестирование, в нем отсутствуют некоторые дополнительные функциональные возможности, такие как утверждения для json, код состояния HTTP и проверки типов содержимого.

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

Чего я не хочу

В StackOverflow есть миллион вопросов «что такое лучший фреймворк PHP» ( 1 , 2 , 3 , 4 , 5 ), но я не ищу тех, а для специфической библиотеки, которая помогает с контроллерами. Если это часть модульной структуры, хорошо.

Я также знаю веб-сайт сравнения фреймворков PHP , но он не помогает ответить на мой вопрос, так как мои требования там не указаны.

И я знаю, что могу построить все это самостоятельно и изобрести еще одну микрорамку. Но почему? Их уже так много, и нужно просто иметь все, что мне нужно.

Смежные вопросы

Ответы [ 7 ]

7 голосов
/ 19 июня 2011

Хорошо зная Symfony2, я могу заверить вас, что определенно возможно использовать его только для «C» в MVC. Модели и шаблоны полностью бесплатны и обычно выполняются из контроллеров в любом случае, поэтому, если вы не вызываете Doctrine или Twig специально, вы можете делать то, что хотите.

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

Это позволяет для некоторых вещей, таких как этот пример , тестировать контактную форму, которая отправляет электронное письмо , где весь HTTP-запрос выполняется, поскольку структура написана так, чтобы разрешать несколько запросов на процесс и имеет нет глобального состояния, это работает очень хорошо и не требует работы http-сервера или чего-либо еще. Как вы можете видеть, я делаю утверждения и по коду статуса HTTP ответа, и смог захватить электронную почту, не отправляя ее, поскольку в тестовой конфигурации отправка электронной почты отключена в стандартном дистрибутиве Symfony2.

При этом вы также можете просто использовать классы Request и Response из компонента HttpFoundation Symfony2. Это должно позволить вам протестировать ваш код, но IMO вы не получите столько хороших функций, сколько могли бы, если бы использовали всю инфраструктуру. Конечно, это только мое пристрастное мнение;)

4 голосов
/ 17 июня 2011

Если вы знакомы с Symfony (а я думаю, что вы), вы должны проверить silex На их веб-сайте это то, что они говорят об этом: микрофрейм обеспечивает смелость для создания простых однофайловых приложений.,Silex стремится быть:

  • Кратким: Silex предоставляет интуитивно понятный и лаконичный API, который интересно использовать.
  • Расширяемый: Silex имеет систему расширений, основанную на микро-контейнере Pimpleэто делает его еще проще связать в сторонних библиотеках.
  • Тестируемый: Silex использует HttpKernel Symfony2, который абстрагирует запрос и ответ.Это позволяет очень легко тестировать приложения и сам фреймворк.Он также уважает спецификацию HTTP и поощряет ее правильное использование.
4 голосов
/ 14 июня 2011

Я бы рекомендовал скачать компонент маршрутизации Symfony 2: https://github.com/symfony/Routing

Документация находится здесь: http://symfony.com/doc/current/book/routing.html

Возможно, он не удовлетворяет всем вашим требованиям, но он самый близкий.

1 голос
/ 07 июля 2011

Я бы добавил Net_URL_Mapper , хотя он не имеет утверждений.Вот почему ты это исключил?

Еще одна довольно интересная вещь - silex .Это также идет с тестами контроллера.Я бы использовал это над Symfony2.Но это мое личное предпочтение.

0 голосов
/ 16 июля 2011

Seldaek: WebTestCase - не совсем правильная вещь - он предназначен для тестирования представления напрямую, а контроллера или модели - только косвенно.

Случайный тестовый блок для контроллера вызовет контроллер, что, вероятно, даст емуфиктивный объект для движка шаблонов (например, фиктивный объект Smarty), затем проверьте значения, которые были назначены этому объекту для отображения: например, если вы вызвали контроллер для / country / south-sudan, вы можете проверить, что шаблонпеременная $ континент была установлена ​​на «Африка».В большинстве случаев такого рода модульное тестирование не будет включать рендеринг шаблонов.

0 голосов
/ 17 июня 2011

Вы можете взглянуть на http://ezcomponents.org/ ведьма становится apache zeta

Есть три способа сделать компоненты eZ доступными для вашей среды PHP, пожалуйста, прочитайте всю эту статью передПродолжаем с практической части:

Use PEAR Installer for convenient installation via command line
Download eZ components packaged in an archive
Get the latest sources from SVN

Я еще не взялся за это, но выглядит как хорошее решение ...

0 голосов
/ 09 июня 2011

Довольно понятный список желаний.Я думаю, что мы все ненавидим это в тестировании, когда сталкиваемся с зависимостями, которые делают тестирование бесполезным.Тесты должны быть простыми и короткими, и многое из того, что нужно решить до и после выполнения каждого теста, может быть обременительным.

Из описания вашего вопроса кажется, что вы довольно точно знаете, что ищете.

Моя первая реакция будет то, что вы используете PHPUnit для этого.Он не отвечает всем вашим требованиям, но это база, на которой вы можете строить.Он очень расходный и гибкий, однако он не поддерживает PSR-0, но имеет собственный автозагрузчик, так что, вероятно, это не так сложно.

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

Я чувствую запах, вероятно, обоих.Если код вашего приложения нелегко тестировать, то такой среды тестирования, как PHPUnit, не так много.Так, например, если ваши контроллеры не используют объект запроса с интерфейсом, не так просто внедрить какой-либо запрос, который был вызван не запросом HTTP, а вашими тестами.Поскольку HTTP чаще всего является точкой входа в веб-приложение, здесь стоит абстрагироваться от тестов.Существуют некоторые предложения помимо конкретных фреймворков: Fig / Http .Однако это всего лишь указатель.

Похожий сценарий с базой данных, который вы даете: если код вашего приложения зависит от базы данных, то и ваши тесты тоже будут.Если вы не хотите постоянно тестировать свою базу данных, вам нужно, чтобы ваши контроллеры могли работать без конкретной базы данных.Это сравнимо с HTTP-запросами.

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

Как и в каждом собственном коде, довольно сложно найти что-то, что соответствует собственному дизайну.Лучшее предложение, которое я могу дать, - расширить PHPUnit, добавив в него те наборы и ограничения, которые вам необходимы для вашего приложения , в то время как вы используете поддержку автоматических тестов для рефакторинга вашего приложения в соответствии с вашими потребностями.test.

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

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

Имейте в виду, что если не существует то, что вам нужно, вам нужно написать его самостоятельно.Однако, если вы можете поделиться (частично) работой с другими, вы чаще всего получаете выгоду, чем делая все в одиночку.Это точка для существующего фреймворка, будь то для тестирования или приложения.

Так что если на данный момент еще нет такого контроллера / MVC, который бы поддерживал простое модульное тестирование из коробки, которое соответствует вашим потребностям,вмешиваться и развивать один TDD-мудрый.Если все сделано правильно, это может точно соответствовать вашим требованиям.Однако я думаю, что вы не одиноки с этой проблемой.Так что не очень конкретный ответ, но я могу только сказать, что я получил очень хороший опыт работы с PHPUnit и его расширяемостью.Это включает в себя выходные тесты, которые вы упоминаете в своем вопросе.

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

Популярный фреймворк - даже с плохим дизайном - имеет большой плюс в том, что компоненты, как правило, лучше тестируются при использовании. Обычно это помогает в течение первых лет вашего приложения, пока из-за проблем с дизайном в фреймворке вам не придется переписывать всю базу кода (вероятно).

Поскольку контроллеры часто сортируются в середине всего, это может привести к сценарию, в котором вы склонны тестировать все приложение, в то время как вы хотите тестировать только контроллеры. Поэтому вам следует подумать о дизайне и роли контроллеров и их месте в общем приложении, о том, что вы действительно хотите протестировать с вашими контроллерами, чтобы вы могли действительно сделать их тестируемыми в соответствии с вашими потребностями. Если вам не нужно тестировать базу данных, вам не нужно тестировать модели. Таким образом, вы можете смоделировать модель, возвращающую случайные данные, чтобы довести ее до крайности. Но если вы хотите проверить правильность обработки HTTP, то, вероятно, сначала необходим модуль, который абстрагирует обработку HTTP. Каждый контроллер, полагающийся на это, не понадобится для тестирования (теоретически), поскольку обработка HTTP уже была протестирована. Это также вопрос уровня абстракции. Не существует общего решения, это только то, что фреймворки могут что-то предложить, но тогда вы будете привязаны к тем парадигмам, которые ожидает фреймворк. AFAIK-тестирование в php становится все более популярным, но это не значит, что существующие фреймворки имеют хорошую поддержку. Я знаю из Zend Framework, что они работают над этим, чтобы улучшить ситуацию еще дольше. Так что, вероятно, стоит взглянуть на последние разработки в более популярных фреймворках, и к чему это приведет.

И для самых конкретных вещей, вы должны всегда тестировать самостоятельно.

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

Вероятно, более компонентный подход Symfony 2 лучше соответствует вашим потребностям, чем то, что вы испытали в Zend Framework. Тем не менее, я не могу предложить вам что-то конкретное, поскольку потребности сильно различаются в дизайне приложения. То, что быстрое и надежное решение для одного приложения является бременем для другого. См. Контроллер страниц .

...