SlideShare a Scribd company logo
1 of 16
Ошибки начинающих TDD-практиков
Начнем с того, что большинство разработчиков неправильно понимает идею TDD. Можно
выделить три способа применения модульных тестов разработчиками:

• Традиционный – когда разработка ведется полностью через тесты,
  один тест за раз, при этом активно применяется рефакторинг.
  Первоначальная реализация рабочего кода обычно является
  нарочно упрощенной, конечный дизайн кода получается
  последовательно и только исходя из появления новых тестов. Это и
  есть TDD.
• Активный – отличается от традиционного тем, что разработчик
  сначала обдумывает дизайн рабочего кода, а затем начинает
  целенаправленно идти к этому дизайну через тесты. (test-first
  development).
• Приемочный - вместо того, чтобы писать небольшие тесты,
  разработчик пишет сразу конечный тест, который реализует
  конечную функциональность. Далее он продумывает дизайн
  реализации, и всю несуществующую функциональность забивает
  мок-объектами, стараясь запустить тесты как можно раньше. После
  этого постепенно убирает мок-объекты, заменяя их реальными
  классами. Это скорей приемочные тесты.
Запахи тестового кода
• Медленные тесты
• Хрупкие тесты
• Сложный тест или тест-«спагетти»
• «Эхо в горах»
• Набор тестов не срабатывает без подключения к сети
• Чрезмерное доверие мокам
• Недостаточное доверие мокам
Медленные тесты
Один из самых очевидных признаков загнивания проекта. Кратко описать идею можно так -
требуется слишком много времени для выполнения теста. Когда вы разрабатываете
приложение, то должны иметь возможность выполнять весь набор тестов (TestSuite)
неограниченное количество раз и не должны ждать тесты слишком долго. Почему это так важно:


• Медленные тесты запускаются реже, из-за этого снижается отдача
  от тестов, ошибки находятся позднее, их исправление занимает
  много времени. Вы должны иметь возможность проверить все
  приложение при малейшем подозрении, что текущие изменения
  могут оказать влияние на другие части приложения.
• Медленные тесты - это признак плохой изоляции тестируемого
  класса от других классов. Здесь может быть 2 причины: 1) или
  разработчик не умеет пользоваться продвинутыми методиками
  тестирования, такими как моки и стабы, 2) или же архитектура
  приложения не позволяет этими техниками пользоваться, что
  говорит о больших зависимостях между компонентами архитектуры.
  Во втором случае - это признак загнивающего проекта.
Хрупкие тесты
Этот запах часто является отговоркой новичков, почему они не пишут тесты. Якобы тесты
слишком часто ломаются при изменении кода, поэтому они значительно увеличивают нагрузку
на разработчика. Существует несколько причин появления этого запаха:

• Чаще всего причиной этому становятся медленные тесты. Если
  полный набор выполнять долго, то разработчики начинают выби-
  рать, когда и как часто запускать полный набор, а все остальное
  время будут запускать тесты только для того кода, над которым они
  работают в текущий момент. Запускайте тесты чаще и они ломаться
  будут реже!
• Другая причина - неправильное тестирование. Тест «знает»
  слишком много деталей тестируемого кода, из-за этого при малей-
  ших изменениях в тестируемом коде тесты ломаются. Приходится
  править и тесты, и тестируемый код. Относиться к этому можно
  двояко - 1) если вы меняете поведение класса, то изменение в
  тестах прогнозируемы, 2) а вот если вы проводите рефакторинг кода
  без изменения функциональности, а тесты постоянно ломаются -
  значит есть повод подумать, как переделать тесты.
• Еще одна причина - это дизайн системы, который не позволяет
  писать изолированные тесты. В этом случае тесты дают понять, что
  код требует рефакторинга.
Сложный тест или тест-"спагетти"
Данная проблема часто возникает у разработчиков, которым не терпится протестировать
некоторую функциональность досконально, исчерпывающе проверяя всевозможные внутренние
состояния. Есть несколько причин появления этого запаха:

• Тесты должны как можно меньше опираться на внутреннее
  состояние тестируемой сущности и скорее относится к ней, как к
  некоторому черному ящику. Тем самым разработчик
  гарантированно огораживает себя от трудности дальнейшей
  поддержки и модификации тестов при рефакторинге кода.
• Тесты должны тестировать модули именно так, как это будет
  делать остальной код в реальном приложении. Нет
  необходимости тестировать все мыслимые комбинации, если класс
  никогда не будет таким образом использован. Помните принцип
  YAGNI (You Aren't Gonna Need It) и цените свое время.
• Эта проблема часто возникает из-за неправильного внутреннего
  дизайна разрабатываемой функциональности и является
  первым звонком для переработки(рефакторинга) как
  разрабатываемого, так и тестового кода.
"Эхо в горах"
Если вы тестируете что-либо в одном месте и только в этом месте, тогда одна внесенная
логическая ошибка в тестируемый код должна приводить к поломке только в одной части
набора тестов. Причины появления эха:


• Ваш набор тестов содержит большой набор дублирующих
  друг друга проверок. При разработке тестов нужно четко
  представлять, что же именно вы тестируете, и избегать подобных
  дублирующих проверок, чтобы не создавать себе дополнитель-
  ной работы. Помните основной принцип прагматичного
  программиста Don't repeat yourself - DRY.
• Еще одна причина - это дизайн системы. Если дублирующих
  проверок избежать не удается, тогда стоим задуматься о
  рефакторинге дизайна системы, которую вы тестируете.
Набор тестов не срабатывает без
подключения к сети
Большинство приложений уровня предприятия требуют подключения к внешним приложениям
для различных целей. Это могут быть платежные системы, серверы аутентификации и т.д. В
идеале модульные тесты должны работать с консольном режиме, без web-сервера и базы
данных (не обязательно), без дополнительных библиотек и проч. Там, где это можно и
целесообразно, нужно использовать моки и заглушки. Причины:


• Вы очевидно вышли за границы модульного тестирования и
  приблизились к системному тестированию. Такие тесты должны
  быть перенесены в приемочные тесты и исключены из набора
  модульных тестов. Это подтолкнет вас к выделению классов,
  которые взаимодействуют с внешними ресурсами, снижению
  зависимостей от этих классов, использованию заглушек и моков.
• Слабое использование моков и заглушек.
Чрезмерное доверие мокам
Если вы окружили свой тестируемый код плотным кольцом моков и заглушек, то есть риск
забыть про реальное применение класса и снова попасть в ловушку. Лежащие в основе
использования моков предпосылки заключаются в том, что они действуют во многом именно
так, как действовали бы реальные объекты. Очень часто мы сталкиваемся с ситуацией, когда
весь набор модульных тестов низкого уровня срабатывает, а приемочные тесты - нет. Причина
ошибок часто заключается в том, что тесты были изолированны моками, поведение которых
уже более не соответствует реальному поведению классов, которые они заменяют. Решение:


• Аккуратно использовать моки, только там, где это уместно.
• Обязательно иметь в наличии функциональные тесты или
  модульные тесты высших уровней, которые реализованы без
  использования моков и заглушек. Путь эти тесты будут не такими
  подробными и быстрыми, зато они помогут отловить те ошибки,
  которые остались незамеченными при модульном тестировании.
Недостаточное доверие мокам
Очевидно, что это противоположная сторона предыдущего запаха. Если вы чаще предпочитаете
использовать реальные классы в тестах, где тестируемый класс зависит от других классов, то
это прямой путь в тестовый ад с раздутыми, медленными и хрупкими тестами, которые часто
ломаются, медленно работают и которые очень трудно писать и понимать. Признак:


• Большой и сложный метод setUp().
• В конце концов, если один тест проверяет, что база может
  вернуть набор A по запросу B, разве мы не может
  предположить, что она сделает то же самое в десяти других
  тестах вашего тестового набора, которые зависят все от того же
  запроса B?
• Но, Правильное использование моков зависит от опыта
  разработчика и сложившейся ситуации. Необходимо слушать свой
  код, как тестируемый, так и тестовый, для того, чтобы не попадать ни
  в одну их этих ловушек.
Преимущества модульного тестирова-
ния или почему нужно тестировать код
• Тесты предотвращают появление ошибок в новом
    коде
•   Тесты позволяют рефакторить код без риска его
    сломать
•   Тесты могут использоваться в качестве
    документации
•   Тесты улучшают дизайн кода
•   Тесты способствуют повышению квалификации
    разработчиков
•   Тесты ускоряют процесс разработки
Тесты предотвращают появление
ошибок в новом коде
• Тесты являются сами ранними клиентами кода и
  позволяют выявлять многие ошибки сразу.
• Тесты заставляют разработчика идти мелкими
  шагами и более пристально уделять внимание
  коду, который он пишет. Если разработчик
  чрезмерно ускоряется - то шанс нарваться на красную
  полоску значительно повышается.
• Тесты позволяют убедиться в работоспособности
  кода на самых ранних этапах разработки, когда
  другие части системы еще не готовы.

В результате ошибки выявляются и исправляются в самом начале разработки, а количество
ненайденных багов в новом коде сокращается   .
Тесты позволяют рефакторить код без
риска его сломать
• При внесении изменений в хорошо протестированный
  код, риск появления новых ошибок значительно ниже.
  Если новая функциональность приводит к
  ошибкам, тесты, если они конечно есть, сразу же это
  покажут. При работе с кодом, на который нет
  тестов, ошибку можно обнаружить спустя значительное
  время, когда с кодом работать будет намного сложнее.
• Хорошо протестированный код легко переносит
  рефакторинг. Уверенность в том, что изменения не
  сломают существующую функциональность, придает
  уверенность разработчикам и увеличивает эффективность
  их работы. Если существующий код хорошо покрыт
  тестами, разработчики будут чувствовать себя намного
  свободнее при внесении архитектурных решений, которые
  призваны улучшить дизайн кода.
Тесты могут использоваться в качестве
документации
• Хороший код расскажет о том, как он работает, лучше
  любой документации. Документация и комментарии в
  коде могут устаревать. Это может сбивать с толку
  разработчиков, изучающих код. А документация, в отличие
  от тестов, не может сказать, что она устарела.
• Когда программисты изучают API, они обычно ищут
  примеры кода. Тесты являются хорошими примерами в
  этом смысле, так как они показывают как можно
  использовать классы, через какой API, какие у классов
  есть зависимости и т.д.
• Стоит также отметить, что тест может играть роль ТЗ.
  Вы пишете функциональный тест на компонент и отдаете
  этот тест человеку, который должен будет сделать
  реализацию. Когда тест сработает - задание может
  считаться выполненным, и его дополнительно проверять не
  нужно.
Тесты улучшают дизайн кода
• Тесты заставляют вас делать свой код более
  приспособленным для тестирования. Например, отказываться
  от глобальных переменных, одиночек (singletons), делать классы
  менее связанными и легкими для использования. Сильно
  связанный код или код, который требует сложной инициализации,
  будет значительно труднее протестировать.
• При добавлении новой функциональности или
  рефактиринге, тесты заставляют подумать о том, что именно
  должен делать код. Начиная с теста, вы сразу же видите
  клиентский код. В результате получается чистый и простой
  дизайн, который делает именно то, что нужно и ничего лишнего.
• Модульное тестирование способствует формированию
  четких и небольших интерфейсов. Каждый класс будет
  выполнять определенную роль, как правило небольшую. Как
  следствие, зависимости между классами будут снижаться, а
  зацепление повышаться.
Тесты способствуют повышению
квалификации разработчиков
• Тесты заставляют разработчика по-другому
  посмотреть на наследование и делегирование, чаще
  применять шаблоны проектирования, искать
  оптимальные пути организации кода. Как следствие, вы
  будете более интенсивно использовать шаблоны
  проектирования.
• По мере роста опыта в TDD вы самостоятельно
  придете к пониманию сути таких базовых принципов
  ООП как «инверсия зависимостей», «отделение
  интерфейсов», «открытие-закрытие».
• Автоматизированное тестирование, в отличие от
  ручного, заставляет разработчика глубже «копать» код.
  Ему становятся понятными многие решения, примененные
  к коду. При этом разработка через тестирование обычно
  ведется в парах, поэтому такие знания распространяются
  быстрее.
Тесты ускоряют процесс разработки

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

More Related Content

What's hot

DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...Dakiry
 
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QAFest
 
Evelina Tananaeva
 Evelina Tananaeva Evelina Tananaeva
Evelina TananaevaAlexei Lupan
 
Автотесты и образ мышления
Автотесты и образ мышленияАвтотесты и образ мышления
Автотесты и образ мышленияAndrei Zubov
 
JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1sgdread
 
Документация тестировщика - Александр Трибушный
Документация тестировщика - Александр ТрибушныйДокументация тестировщика - Александр Трибушный
Документация тестировщика - Александр ТрибушныйDataArt
 
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...Dev_Party
 
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?QAFest
 
Severity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеSeverity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеDeutsche Post
 
Марина Широчкина - Тестирование
Марина Широчкина - ТестированиеМарина Широчкина - Тестирование
Марина Широчкина - ТестированиеYandex
 
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокTatyanazaxarova
 
юнит тестирование Fork
юнит тестирование Forkюнит тестирование Fork
юнит тестирование ForkSergey Oreshkov
 
Марина Широчкина: Тестирование
Марина Широчкина: ТестированиеМарина Широчкина: Тестирование
Марина Широчкина: ТестированиеYandex
 
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Mail.ru Group
 
ковалев нестандатное нт
ковалев    нестандатное нтковалев    нестандатное нт
ковалев нестандатное нтAlexei Lupan
 
евгения фирсова нерелизное тестирование
евгения фирсова   нерелизное тестированиеевгения фирсова   нерелизное тестирование
евгения фирсова нерелизное тестированиеAlexei Lupan
 
Марина Широчкина — «Тестирование»
Марина Широчкина — «Тестирование»Марина Широчкина — «Тестирование»
Марина Широчкина — «Тестирование»Yandex
 

What's hot (20)

DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
DaKiRY_BAQ2016_QADay_Круглий стіл: "Чи помре ручне тестування з часом" Учасни...
 
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
QA Fest 2014. Алексей Лупан. Не тест-кейсы красят тестировщика, а...
 
Evelina Tananaeva
 Evelina Tananaeva Evelina Tananaeva
Evelina Tananaeva
 
Автотесты и образ мышления
Автотесты и образ мышленияАвтотесты и образ мышления
Автотесты и образ мышления
 
JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1JavaTalks.Unit Testing.Part 1
JavaTalks.Unit Testing.Part 1
 
Документация тестировщика - Александр Трибушный
Документация тестировщика - Александр ТрибушныйДокументация тестировщика - Александр Трибушный
Документация тестировщика - Александр Трибушный
 
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...
Андрей Валдуев, Playrix — Основы тестирования и примеры использования базовых...
 
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?
QA Fest 2016. Алексей Виноградов. Цель тестирования. А на самом деле?
 
Severity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятноеSeverity и Priority для неначинающих: очевидное и невероятное
Severity и Priority для неначинающих: очевидное и невероятное
 
Exploratory testing
Exploratory testingExploratory testing
Exploratory testing
 
Марина Широчкина - Тестирование
Марина Широчкина - ТестированиеМарина Широчкина - Тестирование
Марина Широчкина - Тестирование
 
Урок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибокУрок 7. Проблемы выявления 64-битных ошибок
Урок 7. Проблемы выявления 64-битных ошибок
 
юнит тестирование Fork
юнит тестирование Forkюнит тестирование Fork
юнит тестирование Fork
 
Марина Широчкина: Тестирование
Марина Широчкина: ТестированиеМарина Широчкина: Тестирование
Марина Широчкина: Тестирование
 
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
Наталья Чуфырина, Mail.Ru Group, «Как создать команду по автоматизации тестир...
 
Tdd
TddTdd
Tdd
 
ковалев нестандатное нт
ковалев    нестандатное нтковалев    нестандатное нт
ковалев нестандатное нт
 
евгения фирсова нерелизное тестирование
евгения фирсова   нерелизное тестированиеевгения фирсова   нерелизное тестирование
евгения фирсова нерелизное тестирование
 
Марина Широчкина — «Тестирование»
Марина Широчкина — «Тестирование»Марина Широчкина — «Тестирование»
Марина Широчкина — «Тестирование»
 
Как работать с legacy проектом, которому больше10 лет? |Денис Воскобойник
Как работать с legacy проектом, которому больше10 лет? |Денис ВоскобойникКак работать с legacy проектом, которому больше10 лет? |Денис Воскобойник
Как работать с legacy проектом, которому больше10 лет? |Денис Воскобойник
 

Viewers also liked

Автоматическое тестирование и с чем его едят
Автоматическое тестирование и с чем его едятАвтоматическое тестирование и с чем его едят
Автоматическое тестирование и с чем его едятMarina Peregud
 
Разработка через тестирование (TDD и BDD)
Разработка через тестирование (TDD и BDD)Разработка через тестирование (TDD и BDD)
Разработка через тестирование (TDD и BDD)Vyacheslav Lyalkin
 
Behavior Driven Development
Behavior Driven DevelopmentBehavior Driven Development
Behavior Driven DevelopmentAlexey Tigarev
 
Автоматизированное тестирование веб приложений
Автоматизированное тестирование веб приложенийАвтоматизированное тестирование веб приложений
Автоматизированное тестирование веб приложенийAlexander Byndyu
 
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...Промышленный подход к автоматизации тестирования или Keyword-driven testing в...
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...SQALab
 
Компонентное тестирование. Что это за зверь и с чем его едят?
Компонентное тестирование. Что это за зверь и с чем его едят?Компонентное тестирование. Что это за зверь и с чем его едят?
Компонентное тестирование. Что это за зверь и с чем его едят?SQALab
 
Bdd by Dmitri Aizenberg
Bdd by Dmitri AizenbergBdd by Dmitri Aizenberg
Bdd by Dmitri AizenbergAlex Tumanoff
 
“Обезьянье тестирование” в мобильных проектах
“Обезьянье тестирование” в мобильных проектах“Обезьянье тестирование” в мобильных проектах
“Обезьянье тестирование” в мобильных проектахautomated-testing.info
 
Keyword Driven Testing
Keyword Driven TestingKeyword Driven Testing
Keyword Driven TestingMaveryx
 
Проблемы автоматизации крупных проектов: TestComplete
Проблемы автоматизации крупных проектов: TestCompleteПроблемы автоматизации крупных проектов: TestComplete
Проблемы автоматизации крупных проектов: TestCompleteautomated-testing.info
 
Data Driven Testing
Data Driven TestingData Driven Testing
Data Driven TestingMaveryx
 

Viewers also liked (14)

Автоматическое тестирование и с чем его едят
Автоматическое тестирование и с чем его едятАвтоматическое тестирование и с чем его едят
Автоматическое тестирование и с чем его едят
 
Разработка через тестирование (TDD и BDD)
Разработка через тестирование (TDD и BDD)Разработка через тестирование (TDD и BDD)
Разработка через тестирование (TDD и BDD)
 
Behavior Driven Development
Behavior Driven DevelopmentBehavior Driven Development
Behavior Driven Development
 
Автоматизированное тестирование веб приложений
Автоматизированное тестирование веб приложенийАвтоматизированное тестирование веб приложений
Автоматизированное тестирование веб приложений
 
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...Промышленный подход к автоматизации тестирования или Keyword-driven testing в...
Промышленный подход к автоматизации тестирования или Keyword-driven testing в...
 
Компонентное тестирование. Что это за зверь и с чем его едят?
Компонентное тестирование. Что это за зверь и с чем его едят?Компонентное тестирование. Что это за зверь и с чем его едят?
Компонентное тестирование. Что это за зверь и с чем его едят?
 
Cистемы автоматической сборки проектов (Полина Фоминых)
Cистемы автоматической сборки проектов (Полина Фоминых)Cистемы автоматической сборки проектов (Полина Фоминых)
Cистемы автоматической сборки проектов (Полина Фоминых)
 
Bdd by Dmitri Aizenberg
Bdd by Dmitri AizenbergBdd by Dmitri Aizenberg
Bdd by Dmitri Aizenberg
 
“Обезьянье тестирование” в мобильных проектах
“Обезьянье тестирование” в мобильных проектах“Обезьянье тестирование” в мобильных проектах
“Обезьянье тестирование” в мобильных проектах
 
Keyword Driven Testing
Keyword Driven TestingKeyword Driven Testing
Keyword Driven Testing
 
Проблемы автоматизации крупных проектов: TestComplete
Проблемы автоматизации крупных проектов: TestCompleteПроблемы автоматизации крупных проектов: TestComplete
Проблемы автоматизации крупных проектов: TestComplete
 
Keyword driven testing
Keyword driven testingKeyword driven testing
Keyword driven testing
 
Data Driven Testing
Data Driven TestingData Driven Testing
Data Driven Testing
 
The Dangers of Cucumber
The Dangers of CucumberThe Dangers of Cucumber
The Dangers of Cucumber
 

Similar to Ошибки начинающих Tdd практиков, плюсы применения

Continious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileContinious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileKairat Yussupov
 
Проблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийПроблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийTatyanazaxarova
 
Mva stf module 2 - rus
Mva stf module 2 - rusMva stf module 2 - rus
Mva stf module 2 - rusMaxim Shaptala
 
Виталий Стрелюк
Виталий СтрелюкВиталий Стрелюк
Виталий СтрелюкSQALab
 
Sef Streluk Agile
Sef Streluk AgileSef Streluk Agile
Sef Streluk Agilesef2009
 
Постановка процесса тестирования в Agile
Постановка процесса тестирования в AgileПостановка процесса тестирования в Agile
Постановка процесса тестирования в AgileSQALab
 
Как принести пользу разработке и упростить себе жизнь?
Как принести пользу разработке и упростить себе жизнь?Как принести пользу разработке и упростить себе жизнь?
Как принести пользу разработке и упростить себе жизнь?SQALab
 
Тестирование весна 2013 лекция 5
Тестирование весна 2013 лекция 5Тестирование весна 2013 лекция 5
Тестирование весна 2013 лекция 5Technopark
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in netAlex Tumanoff
 
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17OdessaFrontend
 
Как сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileКак сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileAlexey Krivitsky
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsAnton Vidishchev
 
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Tatyanazaxarova
 
Mva stf module 6 - rus
Mva stf module 6 - rusMva stf module 6 - rus
Mva stf module 6 - rusMaxim Shaptala
 
Как тестируют в гугле - обзор книги
Как тестируют в гугле - обзор книгиКак тестируют в гугле - обзор книги
Как тестируют в гугле - обзор книгиkosyakov
 
организация и проведение тестирования
организация и проведение тестированияорганизация и проведение тестирования
организация и проведение тестированияIgor Pozumentov
 
Регулярное использование статического анализа кода в командной разработке
Регулярное использование статического анализа кода в командной разработкеРегулярное использование статического анализа кода в командной разработке
Регулярное использование статического анализа кода в командной разработкеTatyanazaxarova
 
Automation from the trenches
Automation from the trenchesAutomation from the trenches
Automation from the trenchesGleb Rybalko
 
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0AlexeyParhomenko
 

Similar to Ошибки начинающих Tdd практиков, плюсы применения (20)

Continious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-AgileContinious integration-Automated Testing-Solid-Agile
Continious integration-Automated Testing-Solid-Agile
 
Проблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложенийПроблемы тестирования 64-битных приложений
Проблемы тестирования 64-битных приложений
 
Mva stf module 2 - rus
Mva stf module 2 - rusMva stf module 2 - rus
Mva stf module 2 - rus
 
Виталий Стрелюк
Виталий СтрелюкВиталий Стрелюк
Виталий Стрелюк
 
Sef Streluk Agile
Sef Streluk AgileSef Streluk Agile
Sef Streluk Agile
 
Постановка процесса тестирования в Agile
Постановка процесса тестирования в AgileПостановка процесса тестирования в Agile
Постановка процесса тестирования в Agile
 
Как принести пользу разработке и упростить себе жизнь?
Как принести пользу разработке и упростить себе жизнь?Как принести пользу разработке и упростить себе жизнь?
Как принести пользу разработке и упростить себе жизнь?
 
Тестирование весна 2013 лекция 5
Тестирование весна 2013 лекция 5Тестирование весна 2013 лекция 5
Тестирование весна 2013 лекция 5
 
Test driven development in net
Test driven development in netTest driven development in net
Test driven development in net
 
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17
Частые ошибки при разработке фронтенда | Odessa Frontend Meetup #17
 
Как сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с AgileКак сделать наши проекты немного более управляемыми с Agile
Как сделать наши проекты немного более управляемыми с Agile
 
Test Driven Development in .NET Applications
Test Driven Development in .NET ApplicationsTest Driven Development in .NET Applications
Test Driven Development in .NET Applications
 
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
Поиск ловушек в Си/Си++ коде при переносе приложений под 64-битную версию Win...
 
Automation from the trenches
Automation from the trenchesAutomation from the trenches
Automation from the trenches
 
Mva stf module 6 - rus
Mva stf module 6 - rusMva stf module 6 - rus
Mva stf module 6 - rus
 
Как тестируют в гугле - обзор книги
Как тестируют в гугле - обзор книгиКак тестируют в гугле - обзор книги
Как тестируют в гугле - обзор книги
 
организация и проведение тестирования
организация и проведение тестированияорганизация и проведение тестирования
организация и проведение тестирования
 
Регулярное использование статического анализа кода в командной разработке
Регулярное использование статического анализа кода в командной разработкеРегулярное использование статического анализа кода в командной разработке
Регулярное использование статического анализа кода в командной разработке
 
Automation from the trenches
Automation from the trenchesAutomation from the trenches
Automation from the trenches
 
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
Рефакторинг и второе рождение проекта на примере Zend Framework 2.0
 

Ошибки начинающих Tdd практиков, плюсы применения

  • 1. Ошибки начинающих TDD-практиков Начнем с того, что большинство разработчиков неправильно понимает идею TDD. Можно выделить три способа применения модульных тестов разработчиками: • Традиционный – когда разработка ведется полностью через тесты, один тест за раз, при этом активно применяется рефакторинг. Первоначальная реализация рабочего кода обычно является нарочно упрощенной, конечный дизайн кода получается последовательно и только исходя из появления новых тестов. Это и есть TDD. • Активный – отличается от традиционного тем, что разработчик сначала обдумывает дизайн рабочего кода, а затем начинает целенаправленно идти к этому дизайну через тесты. (test-first development). • Приемочный - вместо того, чтобы писать небольшие тесты, разработчик пишет сразу конечный тест, который реализует конечную функциональность. Далее он продумывает дизайн реализации, и всю несуществующую функциональность забивает мок-объектами, стараясь запустить тесты как можно раньше. После этого постепенно убирает мок-объекты, заменяя их реальными классами. Это скорей приемочные тесты.
  • 2. Запахи тестового кода • Медленные тесты • Хрупкие тесты • Сложный тест или тест-«спагетти» • «Эхо в горах» • Набор тестов не срабатывает без подключения к сети • Чрезмерное доверие мокам • Недостаточное доверие мокам
  • 3. Медленные тесты Один из самых очевидных признаков загнивания проекта. Кратко описать идею можно так - требуется слишком много времени для выполнения теста. Когда вы разрабатываете приложение, то должны иметь возможность выполнять весь набор тестов (TestSuite) неограниченное количество раз и не должны ждать тесты слишком долго. Почему это так важно: • Медленные тесты запускаются реже, из-за этого снижается отдача от тестов, ошибки находятся позднее, их исправление занимает много времени. Вы должны иметь возможность проверить все приложение при малейшем подозрении, что текущие изменения могут оказать влияние на другие части приложения. • Медленные тесты - это признак плохой изоляции тестируемого класса от других классов. Здесь может быть 2 причины: 1) или разработчик не умеет пользоваться продвинутыми методиками тестирования, такими как моки и стабы, 2) или же архитектура приложения не позволяет этими техниками пользоваться, что говорит о больших зависимостях между компонентами архитектуры. Во втором случае - это признак загнивающего проекта.
  • 4. Хрупкие тесты Этот запах часто является отговоркой новичков, почему они не пишут тесты. Якобы тесты слишком часто ломаются при изменении кода, поэтому они значительно увеличивают нагрузку на разработчика. Существует несколько причин появления этого запаха: • Чаще всего причиной этому становятся медленные тесты. Если полный набор выполнять долго, то разработчики начинают выби- рать, когда и как часто запускать полный набор, а все остальное время будут запускать тесты только для того кода, над которым они работают в текущий момент. Запускайте тесты чаще и они ломаться будут реже! • Другая причина - неправильное тестирование. Тест «знает» слишком много деталей тестируемого кода, из-за этого при малей- ших изменениях в тестируемом коде тесты ломаются. Приходится править и тесты, и тестируемый код. Относиться к этому можно двояко - 1) если вы меняете поведение класса, то изменение в тестах прогнозируемы, 2) а вот если вы проводите рефакторинг кода без изменения функциональности, а тесты постоянно ломаются - значит есть повод подумать, как переделать тесты. • Еще одна причина - это дизайн системы, который не позволяет писать изолированные тесты. В этом случае тесты дают понять, что код требует рефакторинга.
  • 5. Сложный тест или тест-"спагетти" Данная проблема часто возникает у разработчиков, которым не терпится протестировать некоторую функциональность досконально, исчерпывающе проверяя всевозможные внутренние состояния. Есть несколько причин появления этого запаха: • Тесты должны как можно меньше опираться на внутреннее состояние тестируемой сущности и скорее относится к ней, как к некоторому черному ящику. Тем самым разработчик гарантированно огораживает себя от трудности дальнейшей поддержки и модификации тестов при рефакторинге кода. • Тесты должны тестировать модули именно так, как это будет делать остальной код в реальном приложении. Нет необходимости тестировать все мыслимые комбинации, если класс никогда не будет таким образом использован. Помните принцип YAGNI (You Aren't Gonna Need It) и цените свое время. • Эта проблема часто возникает из-за неправильного внутреннего дизайна разрабатываемой функциональности и является первым звонком для переработки(рефакторинга) как разрабатываемого, так и тестового кода.
  • 6. "Эхо в горах" Если вы тестируете что-либо в одном месте и только в этом месте, тогда одна внесенная логическая ошибка в тестируемый код должна приводить к поломке только в одной части набора тестов. Причины появления эха: • Ваш набор тестов содержит большой набор дублирующих друг друга проверок. При разработке тестов нужно четко представлять, что же именно вы тестируете, и избегать подобных дублирующих проверок, чтобы не создавать себе дополнитель- ной работы. Помните основной принцип прагматичного программиста Don't repeat yourself - DRY. • Еще одна причина - это дизайн системы. Если дублирующих проверок избежать не удается, тогда стоим задуматься о рефакторинге дизайна системы, которую вы тестируете.
  • 7. Набор тестов не срабатывает без подключения к сети Большинство приложений уровня предприятия требуют подключения к внешним приложениям для различных целей. Это могут быть платежные системы, серверы аутентификации и т.д. В идеале модульные тесты должны работать с консольном режиме, без web-сервера и базы данных (не обязательно), без дополнительных библиотек и проч. Там, где это можно и целесообразно, нужно использовать моки и заглушки. Причины: • Вы очевидно вышли за границы модульного тестирования и приблизились к системному тестированию. Такие тесты должны быть перенесены в приемочные тесты и исключены из набора модульных тестов. Это подтолкнет вас к выделению классов, которые взаимодействуют с внешними ресурсами, снижению зависимостей от этих классов, использованию заглушек и моков. • Слабое использование моков и заглушек.
  • 8. Чрезмерное доверие мокам Если вы окружили свой тестируемый код плотным кольцом моков и заглушек, то есть риск забыть про реальное применение класса и снова попасть в ловушку. Лежащие в основе использования моков предпосылки заключаются в том, что они действуют во многом именно так, как действовали бы реальные объекты. Очень часто мы сталкиваемся с ситуацией, когда весь набор модульных тестов низкого уровня срабатывает, а приемочные тесты - нет. Причина ошибок часто заключается в том, что тесты были изолированны моками, поведение которых уже более не соответствует реальному поведению классов, которые они заменяют. Решение: • Аккуратно использовать моки, только там, где это уместно. • Обязательно иметь в наличии функциональные тесты или модульные тесты высших уровней, которые реализованы без использования моков и заглушек. Путь эти тесты будут не такими подробными и быстрыми, зато они помогут отловить те ошибки, которые остались незамеченными при модульном тестировании.
  • 9. Недостаточное доверие мокам Очевидно, что это противоположная сторона предыдущего запаха. Если вы чаще предпочитаете использовать реальные классы в тестах, где тестируемый класс зависит от других классов, то это прямой путь в тестовый ад с раздутыми, медленными и хрупкими тестами, которые часто ломаются, медленно работают и которые очень трудно писать и понимать. Признак: • Большой и сложный метод setUp(). • В конце концов, если один тест проверяет, что база может вернуть набор A по запросу B, разве мы не может предположить, что она сделает то же самое в десяти других тестах вашего тестового набора, которые зависят все от того же запроса B? • Но, Правильное использование моков зависит от опыта разработчика и сложившейся ситуации. Необходимо слушать свой код, как тестируемый, так и тестовый, для того, чтобы не попадать ни в одну их этих ловушек.
  • 10. Преимущества модульного тестирова- ния или почему нужно тестировать код • Тесты предотвращают появление ошибок в новом коде • Тесты позволяют рефакторить код без риска его сломать • Тесты могут использоваться в качестве документации • Тесты улучшают дизайн кода • Тесты способствуют повышению квалификации разработчиков • Тесты ускоряют процесс разработки
  • 11. Тесты предотвращают появление ошибок в новом коде • Тесты являются сами ранними клиентами кода и позволяют выявлять многие ошибки сразу. • Тесты заставляют разработчика идти мелкими шагами и более пристально уделять внимание коду, который он пишет. Если разработчик чрезмерно ускоряется - то шанс нарваться на красную полоску значительно повышается. • Тесты позволяют убедиться в работоспособности кода на самых ранних этапах разработки, когда другие части системы еще не готовы. В результате ошибки выявляются и исправляются в самом начале разработки, а количество ненайденных багов в новом коде сокращается .
  • 12. Тесты позволяют рефакторить код без риска его сломать • При внесении изменений в хорошо протестированный код, риск появления новых ошибок значительно ниже. Если новая функциональность приводит к ошибкам, тесты, если они конечно есть, сразу же это покажут. При работе с кодом, на который нет тестов, ошибку можно обнаружить спустя значительное время, когда с кодом работать будет намного сложнее. • Хорошо протестированный код легко переносит рефакторинг. Уверенность в том, что изменения не сломают существующую функциональность, придает уверенность разработчикам и увеличивает эффективность их работы. Если существующий код хорошо покрыт тестами, разработчики будут чувствовать себя намного свободнее при внесении архитектурных решений, которые призваны улучшить дизайн кода.
  • 13. Тесты могут использоваться в качестве документации • Хороший код расскажет о том, как он работает, лучше любой документации. Документация и комментарии в коде могут устаревать. Это может сбивать с толку разработчиков, изучающих код. А документация, в отличие от тестов, не может сказать, что она устарела. • Когда программисты изучают API, они обычно ищут примеры кода. Тесты являются хорошими примерами в этом смысле, так как они показывают как можно использовать классы, через какой API, какие у классов есть зависимости и т.д. • Стоит также отметить, что тест может играть роль ТЗ. Вы пишете функциональный тест на компонент и отдаете этот тест человеку, который должен будет сделать реализацию. Когда тест сработает - задание может считаться выполненным, и его дополнительно проверять не нужно.
  • 14. Тесты улучшают дизайн кода • Тесты заставляют вас делать свой код более приспособленным для тестирования. Например, отказываться от глобальных переменных, одиночек (singletons), делать классы менее связанными и легкими для использования. Сильно связанный код или код, который требует сложной инициализации, будет значительно труднее протестировать. • При добавлении новой функциональности или рефактиринге, тесты заставляют подумать о том, что именно должен делать код. Начиная с теста, вы сразу же видите клиентский код. В результате получается чистый и простой дизайн, который делает именно то, что нужно и ничего лишнего. • Модульное тестирование способствует формированию четких и небольших интерфейсов. Каждый класс будет выполнять определенную роль, как правило небольшую. Как следствие, зависимости между классами будут снижаться, а зацепление повышаться.
  • 15. Тесты способствуют повышению квалификации разработчиков • Тесты заставляют разработчика по-другому посмотреть на наследование и делегирование, чаще применять шаблоны проектирования, искать оптимальные пути организации кода. Как следствие, вы будете более интенсивно использовать шаблоны проектирования. • По мере роста опыта в TDD вы самостоятельно придете к пониманию сути таких базовых принципов ООП как «инверсия зависимостей», «отделение интерфейсов», «открытие-закрытие». • Автоматизированное тестирование, в отличие от ручного, заставляет разработчика глубже «копать» код. Ему становятся понятными многие решения, примененные к коду. При этом разработка через тестирование обычно ведется в парах, поэтому такие знания распространяются быстрее.
  • 16. Тесты ускоряют процесс разработки • Тесты защищают от ошибок. Поэтому время, затрачиваемое на отладку, снижается многократно. • Тесты позволяют различным группам разработчиков легко действовать параллельно, не ожидая результатов труда друг друга. • Тесты сокращают количество кода, необходимого для удовлетворения требованиям клиента. • Уверенность в том, что все работает как надо после изменений, позволяет выпускать версии продукта горазда раньше и чаще. Немаловажен и тот факт, что автоматизированное тестирование сокращает по продолжительности бета-тестирование.