Сценарии, в которых автоматическое тестирование не помогает - PullRequest
2 голосов
/ 24 января 2009

В каких ситуациях модульное тестирование, TDD и т. П. Доставляют больше хлопот, чем стоят?

Вот некоторые вещи, которые я придумал:

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

Какие еще случаи?

Ответы [ 7 ]

3 голосов
/ 24 января 2009

Я считаю, что ваши первые два пункта не верны.

  • Создание тестовых данных может быть проблемой (на самом деле, это обычно основная часть написания юнит-тестов), но это просто то, что вы должны принять, а не повод отказываться от юнит-тестов. И это не может быть невозможным, иначе как бы вы узнали, что ваше приложение работает правильно?
  • Модульные тесты запускают код для проверки его правильности - я не вижу проблемы.

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

Ситуация, когда модульное тестирование может быть неприменимо, возникает, когда вы сталкиваетесь с существующим приложением, которое не было разработано с учетом тестируемости или даже модульности ( Большой шарик грязи Антишаблон). Но даже тогда, если вы знаете, что вам придется поддерживать и расширять этого зверя в течение значительного периода времени, почти всегда можно и полезно найти способ автоматического тестирования по крайней мере некоторых частей приложения. Никто не говорит, что вам нужно написать набор тестов, который обеспечивает 100% покрытие кода, прежде чем делать что-либо еще.

1 голос
/ 24 января 2009

Я не уверен, что это когда-либо бесполезно . В некоторых случаях это может быть более сложным, и вы можете не использовать его - например, в случае визуального макета вашего пользовательского интерфейса. Также могут быть случаи, когда это напрасная трата усилий - например, модульное тестирование сгенерированного дизайнером кода или не написанных вами фреймворков. Генерация данных не должна быть препятствием для юнит-тестирования. Ваши тесты должны быть достаточно маленькими и хорошо сфокусированными, чтобы вам обычно не требовалось генерировать полный набор данных для какого-либо одного теста, поэтому в этих ситуациях имитация является очень полезной техникой. Если я буду издеваться над одними и теми же вещами снова и снова, я иногда объединю их в поддельный класс базы данных, на который могут положиться все тесты.

Ни модульное тестирование, ни запуск вашего кода не проверит его правильность. Модульное тестирование может помочь устранить ошибки, особенно с TDD, и убедиться, что найденные ошибки исправлены. Если вам нужно убедиться, что ваш код корректен, вам придется применять различные логические методы, чтобы доказать правильность. Они выходят за рамки модульного тестирования.

0 голосов
/ 24 января 2009

Я думаю, что Майкл довольно хорошо подвел итог: «вещи, которые на самом деле не могут быть формально определены». Оказывается, есть много вещей, которые нельзя указать формально. Юзабилити является одним из примеров (хотя, решив, какое поведение можно использовать, вы можете и должны, конечно, проверить это поведение!). Как это ни парадоксально, многие задачи сокращения чисел не могут быть формально определены: например, прогноз погоды. Цель состоит в том, чтобы предсказать погоду завтрашнего дня, но это не формальная спецификация. Таким образом, вы можете либо проверить, что используемые вами алгоритмы выполняют то, что они должны делать (вычисление средних значений, инвертирование матриц, вещи, которые могут быть формально определены), но тогда ваша программа прогноза погоды может пройти все тесты и все равно ошибаться в 90% случаев. , Или вы можете использовать много исторических данных, чтобы проверить, дает ли алгоритм хорошие прогнозы, но это опасно, потому что он может легко привести к алгоритму, который точен только для исторических данных, которые вы использовали, а не в целом. И это, вероятно, будет означать, что ваши юнит-тесты занимают часы или дни. Что еще хуже, ваш алгоритм может иметь параметры, которые нужно «настроить», например, для используемых измерительных инструментов, и оптимальные параметры могут не совпадать для каждого алгоритма, поэтому модульным тестам потребуется ручное взаимодействие для нахождения хороших параметров. Возможно в теории, но, вероятно, не очень полезно. Я предполагаю, что те же аргументы применимы к OCR, ICR, многим задачам обработки сигналов, распознаванию лиц (и многим другим задачам обработки изображений), типичным инструментам фотошопа, таким как «удаление красных глаз», или алгоритмам ранжирования в поисковых системах (просто назвать несколько примеров ).

0 голосов
/ 24 января 2009
* When generating test data is tricky: Sometimes, being able to come up with valid, non trivial test data is a challenge in itself.

Когда вам нужно, чтобы система находилась «в контексте» с «полным набором данных», тогда вы выполняете не модульное тестирование. Это тестирование, но вы сильно напрягаете «юнит». Для этого вам нужно иметь меньшие тесты. Сложнее всего с TDD получить ваш код в такой форме, что вы можете протестировать его в малом размере. Это ценно, но не просто. Если вы выполните тест после (что не является TDD), то избежать вашей ситуации практически невозможно.

Так что, когда вы хотите протестировать что-то большее, чем единица (то есть метод класса), вы захотите использовать что-то вроде UAT или тому подобное. Но в этом сценарии вам все еще нужны тесты для отдельных функций, как если бы вы практиковали TDD.

* When the only practical way of verifying correctness of the code is to run it.

Но код - это , запущенный в модульном тесте. Вы имеете в виду, когда он работает в контексте или что-то еще?

* When you're testing visual elements of the design.

Я думал, что это то, к чему твой второй пункт пули, но я думаю, нет. Трудно и часто не выгодно пытаться проверить макет в UT. Такие тесты хрупки.

Так что может быть нецелесообразно использовать UT для выполнения больших подсистемных тестов или проверки макета экрана при некоторых обстоятельствах. Но даже если это так, это невероятно ценно для 90% вашей работы, которая остается.

0 голосов
/ 24 января 2009

Я твердо верю в вдумчивые испытания; тем не менее, я считаю, что модульное тестирование и TDD являются большей частью пустой тратой времени.

С эмпирической точки зрения:

  1. Нет эмпирических данных, свидетельствующих о более высоком качестве кода.
  2. Нет эмпирических данных, свидетельствующих о более высокой производительности.
  3. Нет эмпирических данных, свидетельствующих об экономии средств.
  4. Существуют «истории», представленные псевдонаучным способом, которые предполагают, что TDD полезен, но нет контрольных групп и нет реальных метрик.

Преимущества TDD:

  1. Евангелисты, которые «знают» TDD, извлекают выгоду, продвигая свой опыт.
  2. Преимущество групп программного обеспечения, которые продают / продвигают инструменты модульного тестирования.
  3. Модульное тестирование может иметь некоторые преимущества, если ваши разработчики не высокого уровня.

    • Юнит-тестирование обнаруживает только самые очевидные ошибки
    • Если разработчик постоянно находит ошибки в модульном тестировании, я бы их заменил.
    • Если бы я поручил разработку в аутсорсинг в Бангалоре, я бы внедрил модульное тестирование. В противном случае, я продолжу работать с сильными разработчиками - эти парни намного более экономически эффективны в долгосрочной перспективе.

Субъективный анализ:

  1. Если вы слушаете аргументы сторонников TDD, вы можете легко заменить TDD молитвой, и обоснованность рассуждений не изменится ...
  2. Модульные тесты - это код - вы удваиваете / удваиваете размер своей кодовой базы ... Возможно, это время лучше потратить на анализ вашего кода.
  3. Высококачественное программное обеспечение исходит от наличия антагонистических / совместных команд. Тот же объект, который пишет код, не занимается бизнес-тестированием кода - это должна быть работа аналитика QA.
  4. Высококачественное и экономичное программное обеспечение основано на следующих принципах проектирования - SOLID / GRASP / GoF
  5. После рассмотрения модульного тестирования и TDD, я хотел бы привести аналогию с реальным миром ... это похоже на запуск контрольного списка с такими элементами, как:
    • проверка вдыхаемого воздуха
    • проверка выдыхаемого воздуха
    • проверка левой ноги вперед
    • проверка правой ноги вперед
    • проверка моргания глаз
    • вставка жевательной резинки
    • проверка закрытой пасти
    • проверка открытого рта
    • итерация до проверки ласточки ...
    • Да, на самом деле вы можете найти проблему, но вы никогда не найдете ничего важного, не потратив огромных усилий на ее кодирование.
  6. Иевус сказал мне, что TDD - ложный бог.
0 голосов
/ 24 января 2009

Просто несколько случайных мыслей по этому поводу:

  1. Я предполагаю, что у Microsoft нет Юнит-тест для разных способов выключение компьютера. Может быть сделано с виртуалами, но это наверное не стоит
  2. Для производителей оборудования: обеспечение работы драйверов для другого оборудования возможно тоже сделано вручную (привет там nvidia, ты сломал мою карточку gfx ;))
  3. Запуск однократных скриптов оболочки. Просто настройте их, пока они не будут работать

Но все же это угловые случаи. Я также думаю, что они почти всегда возможны и в долгосрочной перспективе обычно окупают вас больше, чем вы вложили вначале.

0 голосов
/ 24 января 2009

Я бы не сказал, что бывают случаи, когда автоматическое тестирование бесполезно.

Конечно, есть такие, где это менее полезно. Я не думаю, что создание данных о приборах является одним из них. Есть инструменты, которые могут помочь, например factory_girl (по крайней мере в Ruby). На самом деле, если ваша модель настолько сложна, что вам нужно создать дюжину объектов со всевозможными ассоциациями, я считаю, что запах кода и, возможно, модель не так лаконична, как могла бы.

Тем не менее, есть пара случаев, когда недостатки могут перевешивать преимущества. Я написал код на днях, который разветвляет внешний процесс. Меня не волнует вывод, меня не волнует код возврата, мне даже все равно, сработал ли он правильно, он полностью запущен и забыт, и другой процесс сработает, если что-то не сработает, позже.

В этом случае я не стал писать какие-либо тесты, потому что выгода не стоила времени на установку фиктивной внешней программы для проверки моих аргументов и т. Д., И т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...