Комментарии 30
Хабрака-а-ат!
Вот это простыня. Кат не?
… каждый следующий тест зависел от данных предыдущего
Неправильно, дядя Федор.
Независимость тестов друг от друга — хорошо.
Зависимость — зло, потому что тест из черного ящика превращается в ящик с внешним контекстом.
Крайне не рекомендую так делать.
Зависимость — зло, потому что тест из черного ящика превращается в ящик с внешним контекстом.
Крайне не рекомендую так делать.
То есть, проще заложить простыню внешних данных (сделать несколько Mock-объектов), чтобы протестировать один метод?
А если необходимо протестировать общее поведение объекта?
А если необходимо протестировать общее поведение объекта?
1. Нужно писать по возможности код, не зависящий от внешних данных. То есть использовать «чистые» функции, которые зависят только от своих аргументов, а не от внешнего контекста. Их очень легко оттестить.
Понятно, что от состояния никуда не деться, но свести его к минимуму можно.
2. Да, закладывать простыню, если по-другому не получается, абстрагировать ее в удобные методы, называть их по-другому и дергать в каждом отдельном тесткейсе. Тогда при случайном удалении/изменении тесткейса или кода у вас свалится ровно то, что должно свалиться, а не вообще все.
Понятно, что от состояния никуда не деться, но свести его к минимуму можно.
2. Да, закладывать простыню, если по-другому не получается, абстрагировать ее в удобные методы, называть их по-другому и дергать в каждом отдельном тесткейсе. Тогда при случайном удалении/изменении тесткейса или кода у вас свалится ровно то, что должно свалиться, а не вообще все.
Согласен ровно наполовину.
Любой код зависит от внешних данных, передаваемых параметров и т.д.
И да, свести к минимуму зависимость от состояния — можно. Но, протестировать реакции на состояние тоже надо. И данный пример (статья) предлагает возможное решение.
Я предлагаю ИНСТРУМЕНТ, которого, по моему мнению, не хватало.
Как его использовать и использовать ли вообще — дело каждого
Любой код зависит от внешних данных, передаваемых параметров и т.д.
И да, свести к минимуму зависимость от состояния — можно. Но, протестировать реакции на состояние тоже надо. И данный пример (статья) предлагает возможное решение.
Я предлагаю ИНСТРУМЕНТ, которого, по моему мнению, не хватало.
Как его использовать и использовать ли вообще — дело каждого
ну как задолбаетесь потом искать ошибки, когда вместо одного теста у вас свалится 25, тогда ждем вторую статью — как писать независимые друг от друга тесты :)
Изолированость тестов — это суть ли не самый главный принцип в юнит-тестировании.
Они же даже так и называются «юнит» тесты. Т.е тестирование чего-то одного. Какого-то юнита.
А вы сломали идеологию этим, простите, костылем.
Они же даже так и называются «юнит» тесты. Т.е тестирование чего-то одного. Какого-то юнита.
А вы сломали идеологию этим, простите, костылем.
Во-первых, нигде в статье не указывалось, что речь идёт исключительно о юнит-тестировании.
PHPUnit — достаточно полноценный инструмент, чтобы проводить и другие виды тестирования.
Во-вторых, я не спорю про изолированность тестов, и не стараюсь сломать эту идеологию!
Но как пример:
надо создать и промодифицировать объект.
1. создать объект — результатом получить идентификатор объекта (object_id)
2. сохраняем object_id
3. передаем object_id в качестве параметра (плюс дополнительные параметры функции)
Если в качестве зависимости поставить на создание объекта, то в конечном итоге, при несоздании объекта следующий тест проигнорируется. Таким образом, и поведение системы не изменится, и будет известно в каком месте тест не проходит.
А дальше — каждый выбирает тот инструмент и решение, которое ему больше подходит (нравится)
PHPUnit — достаточно полноценный инструмент, чтобы проводить и другие виды тестирования.
Во-вторых, я не спорю про изолированность тестов, и не стараюсь сломать эту идеологию!
Но как пример:
надо создать и промодифицировать объект.
1. создать объект — результатом получить идентификатор объекта (object_id)
2. сохраняем object_id
3. передаем object_id в качестве параметра (плюс дополнительные параметры функции)
Если в качестве зависимости поставить на создание объекта, то в конечном итоге, при несоздании объекта следующий тест проигнорируется. Таким образом, и поведение системы не изменится, и будет известно в каком месте тест не проходит.
А дальше — каждый выбирает тот инструмент и решение, которое ему больше подходит (нравится)
После шага 2 куда сохраняется объект? В какое-то персистентное хранилище?
А по каким событиям и когда это хранилище подчищается? Получается, что в tearDown теперь этого делать нельзя.
А по каким событиям и когда это хранилище подчищается? Получается, что в tearDown теперь этого делать нельзя.
Персистентное хранилище
И да, в tearDown необходимо использовать флаги для очистки
внутри теста можно указать, когда можно очищать данные
И да, в tearDown необходимо использовать флаги для очистки
внутри теста можно указать, когда можно очищать данные
Какой ужас :-S
Т.е. теперь тесты ещё и должны беспокоиться о подготовке правильного окружения сами для себя же.
Подозреваю, что эта обязанность, наравне со строгим порядком выполнения сделает их жутко хрупкими и геморными для поддержки.
Т.е. теперь тесты ещё и должны беспокоиться о подготовке правильного окружения сами для себя же.
Подозреваю, что эта обязанность, наравне со строгим порядком выполнения сделает их жутко хрупкими и геморными для поддержки.
Да, видимо всё-таки речь идёт не о модульных, а об интеграционных тестах. Но даже в этом случае принято состояние системы эмулировать напрямую (например, записью нужных данных в базу), а не вызовом последовательности тестов.
Все программисты ленивые. И каждый хочет не писать дополнительный код, а воспользоваться уже готовым. Тем более, что это хорошая практика.
Спорное утверждение. Пользуясь готовыми чужими решениями рискуешь нарваться на чужие ошибки, которые, как правило, муторнее исправлять… Если решение сложное, а времени нет, тогда да, но это скорее исключение чем правило для _хорошего программиста_.
Для решения описанных проблем имеет смысл посмотреть в сторону паттернов Object Mother и Test Data Builder. Врочем, тесты — это обычный код, для устранения дублирования (в тестовых методах, фикстур и т. д.) следует применять те же правила, что и в обычном рабочем коде.
А делать зависимые тесты и, тем более, завязывать их на порядок выполнения — это, как уже сказали выше, не самая хорошая затея.
А делать зависимые тесты и, тем более, завязывать их на порядок выполнения — это, как уже сказали выше, не самая хорошая затея.
Проблемы начнутся тогда, когда в длинной цепочке тестов, где-то допустим в первой трети цепочки, у тебя будет не учтённы какой-то кейс, а клина вся эта система поймает изза этого неучтённого кейса ближе к концу цепочки. Попробуй найди тогда в чём была причина. Я не спец в тестировании, но это мне кажется очевидным. Это зло.
BDD в общем и Behat в частности быть использованы тобой должны были.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
PHPUnit && ordered tests