Почему PHPUnit настаивает на том, чтобы делать все ОО-способом?
Вопрос
Рискуя быть запятнанным...какое преимущество имеет принудительное выполнение вызовов методов, а не функций, в контексте, где контекст является неявным?
Учитывая, что синтаксис PHP настолько уродлив для вызова методов, зачем создателям PHPUnit навязывать его использование?
Если бы фреймворк установил глобальный объект "currentTestCase", а затем прозрачно связал неудачные утверждения с этим объектом, мы могли бы писать:
assertEquals("blah", $text);
в отличие от эквивалентного, но подробного:
$this->assertEquals("blah", $text);
Что именно мы получаем, используя OO в этом контексте?
Пожалуйста, просвети меня.
Решение
Потому что PHPUnit является производным от xUnit, и вот как xUnit ( единица измерения ) делает это.
Почему xUnit делает это именно так?Я рад, что вы спросили.Первоначальная причина, как указывает Роберт, заключается в том, что xUnit происходит из Smalltalk и был популяризирован JUnit на Java.Оба языка - "ОО или ничего", так что у них не было выбора.
Это не значит, что нет других преимуществ.Тесты OO могут быть унаследованы.Это означает, что если вы хотите протестировать подкласс, вы можете запустить все родительские тесты и просто переопределить несколько методов тестирования для измененного вами поведения.Это дает вам отличное покрытие подклассов без необходимости дублировать тестовый код.
Его легко добавлять и переопределять методы assert в PHPUnit.Просто подкласс PHPUnit_Framework_TestCase
, напишите свой собственный assert
методы и ваши тестовые классы наследуются от вашего нового подкласса.Вы также можете написать default (по умолчанию) setup
и teardown
методы.
Наконец, это гарантирует, что методы тестовой платформы не будут конфликтовать с тем, что они тестируют.Если тестовый фреймворк просто загрузил свои функции в тест, и вы хотели протестировать что-то, что имело setup
способ...что ж, у тебя неприятности.
Тем не менее, я слышу твою боль.Большой тестовый фреймворк может быть раздражающим, громоздким и хрупким.Perl не использует стиль xUnit, он использует процедурный стиль с короткими именами тестовых функций.Видишь Тест::Подробнее для примера.За кулисами он делает именно то, что вы предложили, есть одноэлементный тестовый экземпляр object, который используют все функции.Существует также гибридная процедурная функция assert с модулем OO test methods, которая называется Тест::Класс что делает лучшее из обоих миров.
Учитывая, что синтаксис PHP настолько уродлив для вызова методов
Я предполагаю, что тебе не нравится ->
.Я предлагаю вам научиться жить с этим.OO PHP намного приятнее, чем альтернатива.
Другие советы
Одна из веских причин заключается в том, что assertXXX
поскольку имя метода имеет высокий риск конфликта имен.
Другой вариант заключается в том, что он является производным от xUnit ( единица измерения ) семейство, которое обычно имеет дело с объектно-ориентированными языками - изначально Smalltalk.Это облегчает общение с вашими "братьями и сестрами", напримерJava и Ruby.
Это не прямой ответ, но начиная с PHPUnit 3.5, вам не нужно писать $this->
больше.PHPUnit 3.5 добавил библиотеку функций для утверждений, которые вы должны включить
require_once 'PHPUnit/Framework/Assert/Functions.php';
Тогда вы можете сделать
assertEquals('foo', $bar);
Смотрите запись в блоге Себастьяна Бергманна об этом
Наличие тестовых примеров в методах класса экономит работу PHPUnit.Из-за отсутствия встроенного интеллекта PHPUnit не смог найти или обработать чисто тестовые функции.Только необходимость распознавать сообщения -> assert *() - в простой логической цепочке - снова экономит логику обработки (для PHPUnit, а не для автора тестового примера).Это вся синтаксическая соль, которая экономит накладные расходы с точки зрения PHPUnit / SimpleTest.
Не было бы технической проблемой перехватить сообщения об ошибках / предупреждения, исключения или распознать собственный оператор PHPs assert().Это делается не потому, что сложный API выглядит более предприимчивым.