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

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

да уж, занял практически всю страницу)))
ну упс ;)
Вот это простыня. Кат не?
При такой частой ошибке разработчикам сайта давно стоило бы автоматически добавлять кат в статью без оного…
… каждый следующий тест зависел от данных предыдущего

Неправильно, дядя Федор.
Я после процитированного текста и бросил читать статью. Подход изначально неверен, к чему под него еще костыли подставлять?
Независимость тестов друг от друга — хорошо.
Зависимость — зло, потому что тест из черного ящика превращается в ящик с внешним контекстом.
Крайне не рекомендую так делать.
То есть, проще заложить простыню внешних данных (сделать несколько Mock-объектов), чтобы протестировать один метод?

А если необходимо протестировать общее поведение объекта?
1. Нужно писать по возможности код, не зависящий от внешних данных. То есть использовать «чистые» функции, которые зависят только от своих аргументов, а не от внешнего контекста. Их очень легко оттестить.
Понятно, что от состояния никуда не деться, но свести его к минимуму можно.

2. Да, закладывать простыню, если по-другому не получается, абстрагировать ее в удобные методы, называть их по-другому и дергать в каждом отдельном тесткейсе. Тогда при случайном удалении/изменении тесткейса или кода у вас свалится ровно то, что должно свалиться, а не вообще все.
Согласен ровно наполовину.

Любой код зависит от внешних данных, передаваемых параметров и т.д.

И да, свести к минимуму зависимость от состояния — можно. Но, протестировать реакции на состояние тоже надо. И данный пример (статья) предлагает возможное решение.

Я предлагаю ИНСТРУМЕНТ, которого, по моему мнению, не хватало.
Как его использовать и использовать ли вообще — дело каждого

ну как задолбаетесь потом искать ошибки, когда вместо одного теста у вас свалится 25, тогда ждем вторую статью — как писать независимые друг от друга тесты :)
в случае с @depends — сваливается только один тест, остальные игнорируются.
Это поведение уже заложено в PHPUnit.
Я только упорядочил тесты с учётом зависимостей.

Что касается статьи, посмотрим.
А получится запустить только один тест, какой-нибудь средний, например?
Изолированость тестов — это суть ли не самый главный принцип в юнит-тестировании.

Они же даже так и называются «юнит» тесты. Т.е тестирование чего-то одного. Какого-то юнита.
А вы сломали идеологию этим, простите, костылем.
Во-первых, нигде в статье не указывалось, что речь идёт исключительно о юнит-тестировании.
PHPUnit — достаточно полноценный инструмент, чтобы проводить и другие виды тестирования.

Во-вторых, я не спорю про изолированность тестов, и не стараюсь сломать эту идеологию!

Но как пример:
надо создать и промодифицировать объект.
1. создать объект — результатом получить идентификатор объекта (object_id)
2. сохраняем object_id
3. передаем object_id в качестве параметра (плюс дополнительные параметры функции)

Если в качестве зависимости поставить на создание объекта, то в конечном итоге, при несоздании объекта следующий тест проигнорируется. Таким образом, и поведение системы не изменится, и будет известно в каком месте тест не проходит.

А дальше — каждый выбирает тот инструмент и решение, которое ему больше подходит (нравится)
После шага 2 куда сохраняется объект? В какое-то персистентное хранилище?
А по каким событиям и когда это хранилище подчищается? Получается, что в tearDown теперь этого делать нельзя.
Персистентное хранилище

И да, в tearDown необходимо использовать флаги для очистки
внутри теста можно указать, когда можно очищать данные
Какой ужас :-S
Т.е. теперь тесты ещё и должны беспокоиться о подготовке правильного окружения сами для себя же.

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

Геморность для поддержки — вопрос спорный.
Один флаг для очистки после выполнения в последнем тесте — куда проще реализовать, чем создавать, наполнять и удалять каждый раз один полноценный объект
Да, видимо всё-таки речь идёт не о модульных, а об интеграционных тестах. Но даже в этом случае принято состояние системы эмулировать напрямую (например, записью нужных данных в базу), а не вызовом последовательности тестов.
Не всегда можно напрямую записать данные в базу

API системы с черным ящиком внутри
В случае с API принято использовать mock-обьекты
Все программисты ленивые. И каждый хочет не писать дополнительный код, а воспользоваться уже готовым. Тем более, что это хорошая практика.

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

Я не говорил о чужих решениях и чужих ошибках
Речь шла о том, чтобы не использовать копию своего кода
Для решения описанных проблем имеет смысл посмотреть в сторону паттернов Object Mother и Test Data Builder. Врочем, тесты — это обычный код, для устранения дублирования (в тестовых методах, фикстур и т. д.) следует применять те же правила, что и в обычном рабочем коде.

А делать зависимые тесты и, тем более, завязывать их на порядок выполнения — это, как уже сказали выше, не самая хорошая затея.
Хорошее противопоставление.

Проблемы начнутся тогда, когда в длинной цепочке тестов, где-то допустим в первой трети цепочки, у тебя будет не учтённы какой-то кейс, а клина вся эта система поймает изза этого неучтённого кейса ближе к концу цепочки. Попробуй найди тогда в чём была причина. Я не спец в тестировании, но это мне кажется очевидным. Это зло.
BDD в общем и Behat в частности быть использованы тобой должны были.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации