Должен ли я написать модульный тест для всего? - PullRequest
20 голосов
/ 05 февраля 2009

Мне интересно, должен ли я написать модульный тест для всего. Есть некоторые классы, очень сложно написать модульный тест. Например, я пишу какую-то программу для обработки звука. Класс для записи звука с микрофона и класс для воспроизведения звука на динамик. Как я могу написать модульный тест для этих классов? Я не могу получить вывод и ввод этих классов, поэтому почти невозможно их протестировать? Единственный тест, который я могу сделать, - это скучный тест для геттера и сеттера. Итак, вопрос в том, что является ориентиром для написания юнит-теста? И как мне справиться с этими классами, которые сложно проверить?

Ответы [ 13 ]

38 голосов
/ 05 февраля 2009

Используйте модульное тестирование там, где это имеет смысл - не стремитесь к 100% охвату. Главное правило - думать , а не применять догму или лень.

Сказав это: если у вас есть классы, которые, естественно, сложно протестировать, постарайтесь уменьшить их количество. Изолируйте непроверяемый код и разделите его API на интерфейс. Затем проверьте логику, в которой использует этот API для макета или заглушки.

14 голосов
/ 05 февраля 2009

Я пишу только юнит-тесты, когда знаю, что это экономит мое время. Когда я начал юнит-тестирование, это был лишь небольшой процент классов (эти ужасные ejb's !!). Сегодня я тестирую почти все и экономлю общее время разработки на каждой вещи, которую я делаю . Если бы был эффективный способ тестирования пользовательского ввода через микрофон, я бы тоже это сделал. Но, насколько я знаю, это невозможно, чтобы сэкономить время.

Так что я думаю, что вы должны юнит-тестировать все, что есть в вашей текущей "возможности тестирования". Вы должны попытаться расширить эту возможность, но чрезмерное использование действительно посылает сигналы о неправильных приоритетах; По всей вероятности, есть какой-то другой тест, который заслуживает вашего внимания больше. (Технически я заражен тестом , но не TDD заражен )

Закон убывающей отдачи применяется к юнит-тестированию так же, как и к любому другому тестированию; Ваша окупаемость за последние 5% очень низкая, а стоимость высокая.

4 голосов
/ 05 февраля 2009

Одно правило, которое я использую для принятия решения о том, следует ли разрабатывать модульные тесты: если ваш класс (или любой другой модуль) будет выпущен «в дикую природу», тогда вам определенно следует подумать о написании модульных тестов.

Под «дикой природой» я подразумеваю: как только ваш код окажется в ситуации, когда вы не можете предсказать или контролировать, как вещи будут взаимодействовать с ним. Поэтому классы, предоставляемые через API, или классы, открытые для пользовательского ввода, вероятно, должны быть проверены модулем.

Лично я думаю, что написание юнит-тестов для всего , вероятно, будет пустой тратой вашего времени. Это действительно сложный вопрос, который необходимо учитывать:

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

Тогда всегда есть:

  • Когда заканчивается срок выполнения проекта?
  • Сколько человеческих сил вы посвятили созданию тестов?
  • Являются ли ваши требования конкретными и подробными, или класс все еще меняется довольно часто?

Что касается сложных занятий, возможно, прочитайте немного о нечетком тестировании .

2 голосов
/ 05 февраля 2009

Короткий ответ: нет, но тогда это касается всего в программировании, когда вы спрашиваете: «Должен ли я Х за все?»

Чем дольше ответ, тем лучше подумайте, что вы и делаете. Почему вы не можете издеваться над входом в класс звукозаписи? Почему бы не сделать запись в режиме обхода с микрофона, чтобы загрузить звук из файла и сделать вывод в файл вместо динамика. Тест мог сравнить результат вывода с известным правильным результатом.

Подробнее о философской стороне см. this .

1 голос
/ 26 марта 2013

Я проверяю большинство вещей.

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

Хотя я не тестирую реализацию. Я хочу иметь возможность изменять реализацию без изменения моих тестов.

Я использовал TDD, может быть, год или два, так что, возможно, я повзрослею и перестану. Пока что я все еще учусь и думаю, что не пишу достаточно тестов.

1 голос
/ 05 февраля 2009

Дешевый ответ: Проверьте все, что может сломаться

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

1 голос
/ 05 февраля 2009

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

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

Два совета:

  • Не проверять компилятор (например, getter и setter)
  • Проверьте все, что может сломаться
1 голос
/ 05 февраля 2009

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

В вашем случае я предлагаю следовать идее Стива Роу , чтобы написать тест, который настраивает динамик и микрофон, и использовать кабель обратной связи для проверки кода настройки оборудования плюс API, который позволяет испускайте данные через динамик и считывайте данные с микрофона.

Это юнит-тест, но не автоматический. Переместите его в независимый набор тестов, который не работает с другими автоматическими тестами. Если вы хотите автоматизировать его, настройте второй компьютер с правильной конфигурацией (плюс шлейф) и выполните тест удаленно.

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

1 голос
/ 05 февраля 2009

Другой пример: если вы разрабатываете игровой движок, вы хотите проверить свои теневые и другие функции, но вы должны подтвердить это визуально - это ничего не может сделать классический UnitTest.

Ваш случай: Поскольку ваше приложение становится все более сложным, всегда становится больно нажимать на ваш пользовательский интерфейс для проверки всех ваших функций.

Я бы написал «интерактивный TestSuite», в котором различные фиктивные диалоги (настроенные для каждого тестового случая) показаны только с теми функциями, которые вам нужны для тестирования. Как только вы закроете диалог, вам будет предложено, если поведение было ожидаемым. Но я не уверен, есть ли доступные решения, которые могли бы помочь здесь.

1 голос
/ 05 февраля 2009

Чтобы ответить на ваш конкретный вопрос, используйте петлевой кабель. Подключите громкоговоритель к микрофонному входу. Напишите тест, который воспроизводится на громкоговоритель и захватывает его с микрофона и проверяет, что то же самое, что вы играли, было записано. Я предлагаю использовать простой синусоидальный сигнал, чтобы БПФ сообщало вам, захватили ли вы то же самое.

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

...