Как стать автором
Обновить

Комментарии 31

По таким простеньким примерам были статьи.
А вот примеров того, как использовать юнит-тесты для функций, которые работают со сложными объектами или с базой данных, например, не видел. А хотелось бы :)
Я планирую серию статей по PHPUnit, сложность будет нарастать, постепенно доберусь и до более серьезных примеров.
Не хочу сглазить, но 95% циклов статей заканчивается основами и остаются лишь в головах авторов :-(
ps: сам практикую тдд уже более 4 лет
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
«Кроме того, использование tdd означает, что надо создать интерфейс ипродумать структуру класса до начала работы и ее изменение в последствии приведет также к тому, что приедтся переписывать и тесты, да?»
нет. как раз наоборот — тесты позволяют гораздо меньше думать об интерфейсах во время непосредственно реализации.
тесты пишутся по мере надобности. появилась надобность в фиче А (а потому как она появилась — ты уже задумался об интерфейсе так или иначе). Напиши тест. Внедри _УЖЕ РАБОТАЮЩИЙ_ код в рабочее окружение. появится надобность в фиче Б — будешь думать. никакого планирования заранее.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Извините, а где тут phpUnit? Здесь я вижу применение exception, для обрабоки ошибок, это НЕ тестирование, это отлов ошибок. Могли бы уже try / catch описать, и как применять разные классы exception, в зависимости от класса, метод которого сгенерировал исключение.
Это перевод первой главы официальной документации по PHPUnit, глава является введением в использование этого framework.
Думаю, автор не использует try / catch, чтобы не вносить ненужное усложнение в пример.

А чем отлов ошибок отличается от тестирования? :)
Извините, не увидел значка «перевод» сразу. Думаю, что введение можно было пропустить, это слишком очевидные решения, print или var_dump используют все начинающие программисты, и с удовольствием от них бы отказались в пользу чего-то более удобного, xdebug или phpUnit к примеру. Про отличия тестирования и отлова ошибок на мой взгляд написал ниже.
«Думаю, что введение можно было пропустить»
позволю не согласиться. очень многие программисты останавливаются на этапе мотивации. из разряда «зачем писать дополнительный код». как раз тут и получаем эволюцию тестов от ручных к автоматическим (наколеночным, но какая разница) и понимаем их профит.
Дык, вроде ж не для отлова ошибок, а именно для тестирования. Потому что вся функциональная часть кода в блоке 1.1 и к try-catch не имеет отношения.
Правда этот метод тестирования из тех, что будет выполняться и на продакшне тоже, чего быть не должно, но в принципе тут на пальцах показано, как самому себе сделать автоматическое тестирование.
Прочитайте Топик, посвященный phpUnit в netBeans.

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

Тестирование же применять для отлова нестандартных вариантов работы приложения или семантических ошибок кода. Таких ошибок не должно быть в production, кроме того их обработка через exception приведет к усложнению кода (комменты и phpUnit тесты вместе с ними можно свернуть в IDE, чтобы не мешали чтению кода) и т.д.
О, а давайте еще поговорим о том, что такое программирование?
Немного успел поработать, как с PHPUnit, так и SimpleTest. В первом (в отличие от второго) меня крайне расстроило отсутсвие втроенной поддержки генерации HTML отчтётов. Конечно, можно использовать сторонние доработки или фокусы типа

ob_start();
PHPUnit_TextUI_TestRunner::run(self::suite(), array(
    'xmlLogfile' => $reportPath
));
ob_end_clean();

$report = Report::generate($reportPath);


но это на мой взгляд не очень удобно.
Что мне больше всего нравится в PHPUnit, так это его отчеты о покрытии тестами. В Simpletest есть что-либо подобное?
Не совсем понял, о чём вы. В roadmap'е на версию 1.9 у них числится «code coverage», если речь об этом.
Да, я именно о нем. У всех свои недостатки — code coverage в simpletest доступен только через сторонний spike phpcoverage (насколько я понял из их сайта сейчас, не обновлявшийся аж с 2008 года), а в phpunit как вы заметили, нет автогенерации html-отчетов.
Правда, лично мне html-отчеты не нужны, запускаю тесты в основном из консоли и IDE.
Заметил интересную тенденцию на Хабре, когда мне нужно поресерчить на определенную тему, статья на эту тему тут же появляется на главной. НЛО и особенно автору спасибо!)
Да-да, тоже очень часто замечал такую «контекстную рекламу» :) Это не только с Хабром так.
А ещё есть проект по коллективному переводу мануала: translated.by/you/phpunit-manual-3-3/
Какой-то непонятный сайт, пытался найти перевод, лазил-лазил пр содержанию, так ничего и не нашел.
На практике использовать assertTrue как показано выше не всегда удобно.
Лучше делать так (массив оставил только для соответствия примеру):

$result = $true;
$fixture = array();
$result = $result && (some condition);
$fixture[] = 'element';
$result = $result && (some condition);
assertTrue($result);

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

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

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

1. Очень странно, починив один тест не прогнать сразу же все тесты еще раз, и ждать билда раз в сутки (Кстати, у вас правда такая большая система, что собирается 5-6 часов? Мб стоит гонять тесты чаще?)

2. Тесты должны быть понятными. Их должно быть просто читать. Должно быть понятно где сломалось. Если в тесте делается пара десятков проверок и делается их конъюнкция то с ходу понять какое условие не прошло не ясно. Не говоря уже о том, что код теста усложняется и создаются условия для появления ошибок в самих тестах.
«Имхо это плохая рекомендация». Думаю, что именно для юнит тестов да, плохая! Если программист запускает тесты после написания кода, то да — Вы правы. Но в моем случае — это лучшая рекомендация, т.к. у нас тесты пускаются тест тимом после сборки.

1. Нет. Система очень большая. Собирается билд от получаса (для некоторых осей еще больше). Без полной сборки всех компонент использовать отдельные компоненты просто нереально, хотя было очень большое желание и попытки (зависимостей очень много, на юниксах особенно). Ставится билд тоже немало времени. На Федоре по 3 часа иногда уходит.

2. Тесты должны быть понятными. — 100%, так и есть
2.1. Их должно быть просто читать. — 100%, так и есть
2.2. Должно быть понятно где сломалось. — 100% и это реальная проблема, т.к. не все тесты удовлетворяют этому условию.
2.3. Если в тесте делается пара десятков проверок и делается их конъюнкция то с ходу понять какое условие не прошло не ясно. — да, но для этого есть п. 2.2. Сходу можно понять, если делать хороший лог и стек трейс теста выводить с шагами.
2.4. Не говоря уже о том, что код теста усложняется и создаются условия для появления ошибок в самих тестах. — да, у нас даже баги на тесты пишут. Даже в приведенном в этой статье случае, можно сделать баги, так что этот критерий не показателен. Продукт ооочень большой. А еще у нас есть коде ревью внутри тест тима, без которого пп. 2.1. и 2.2. были бы трудно достижимыми.

Я думаю от задач надо отталкиваться. Я описал свой опыт :) Кому-то он конечно не подойдет.
Как заметили ниже в тесте тоже можно сделать баг :) И я его сделал! Верный вариант такой:

$result = $true;
$fixture = array();
$result = (some condition) && $result;
$fixture[] = 'element';
$result = (some condition) && $result;
assertTrue($result);
Под автоматическими тестами обычно подразумеваются функциональные тесты, а xUnit используется для написания модульных тестов. Модульные тесты, в свою очередь, являются основополагающей частью разработки на основе тестирования (TDD) и их основной задачей не является тестирование кода. Более того, они обычно пишутся еще до того, как появляется какой-либо код.
Кстати, вот здесь очень много полезной информации, в частности по модульному и функциональному тестированию, причем на русском языке.
то что вы тут написали можно элементарно сделать с помошью ассерт-ов, прям по ходу разработки, малейшее изменение и сразу видно где вылез бок, при заливке на лив, в худшем случае отключить асерты, в лучшем вырезать
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации