Мне интересно, должен ли я писать unit test для всего. Есть несколько классов, которые очень трудно написать unit test. Например, я пишу какую-то программу для обработки аудио. Класс для записи звука с микрофона и класса для воспроизведения звука в динамик, как я могу написать unit test для этих классов? Я не могу получить выход и ввод этих классов, поэтому их практически невозможно проверить? Единственный тест, который я могу сделать, - это геттер и сеттер, те скучные тесты. Итак, вопрос в том, что такое руководство для написания unit test? И как я должен справляться с этими классами, трудно проверить?
Должен ли я писать unit test для всего?
Ответ 1
Используйте модульное тестирование, где это имеет смысл, - не нацелитесь на 100% -ный охват. Главное правило - подумать, а не применять догму или лень.
Сказав это: если у вас есть классы, которые, естественно, трудно тестировать, попробуйте уменьшить, сколько им нужно делать. Изолируйте непроверяемый код и разделите его API на интерфейс. Затем проверьте логику, которая использует этот API для макета или заглушки.
Ответ 2
Я пишу только модульные тесты, где я знаю, это экономит мне время. Когда я начинал модульное тестирование, это был лишь небольшой процент от классов (эти ужасные ejb!). Сегодня я тестирую почти все, и я сохраняю общее время разработки на каждой моей работе. Если бы был эффективный способ тестирования ввода пользователем через микрофон, я бы тоже это сделал. Но, насколько я знаю, это невозможно, так как это экономит мне время.
Итак, я думаю, вы должны unit test все, что находится в вашей текущей "возможности тестирования". Вы должны попытаться растянуть эту возможность, но перенасыщение действительно посылает сигналы неправильных приоритетов; По всей видимости, есть еще один тест, который заслуживает вашего внимания больше. (Технически я тестирую заражение, но не заражен TDD)
Закон убывающей доходности применяется к единичному тестированию, как и любое другое тестирование; ваша окупаемость на последние 5% очень низкая, а стоимость высокая.
Ответ 3
Одно правило, которое я использую для принятия решения о том, следует ли разрабатывать модульные тесты: если ваш класс (или что-то другое) будет выпущен "в дикую природу", то вам обязательно стоит рассмотреть возможность написания модульных тестов.
Под "в дикой природе" я имею в виду: как только ваш код будет в ситуации, когда вы не можете предсказать или контролировать, как будут взаимодействовать с ним. Таким образом, классы, открытые через API, или классы, подверженные пользовательскому вводу, вероятно, должны быть проверены на единицу.
Лично я считаю, что написание единичных тестов для всего, скорее всего, будет пустой тратой времени. Это действительно сложная проблема, когда вам нужно подумать:
- Насколько сложным является класс? Младшие простые классы могут не стоить тестировать.
- Насколько критичен класс? Код, работающий в банкомате, мы надеемся, что будет проверен модуль.
- Сколько у вас контроля над тем, как используется класс?
Тогда всегда:
- Когда истекает срок действия проекта?
- Сколько человек-власти вы посвятили созданию тестов?
- Являются ли ваши требования конкретными и подробными, или класс все еще меняется довольно часто?
Что касается сложных классов, возможно, немного читаем о fuzz testing.
Ответ 4
Короткий ответ: "Нет", но потом все идет программированием, когда вы спрашиваете: "Должен ли я X для всего?"
Более длинный ответ - вы должны хотя бы рассмотреть его, что вы делаете. Почему вы не можете издеваться над входом в класс звукозаписи? Почему бы не включить запись байпаса класса из микрофона, чтобы загрузить аудио из файла и вывести выход в файл вместо динамика. Тест мог сравнить результат вывода с известным правильным результатом.
Подробнее о философской стороне см. this.
Ответ 5
Чтобы ответить на ваш конкретный вопрос, используйте кабель обратной связи. Подключите громкоговоритель к микрофону. Напишите тест, который отображает динамик и захватывает микрофон, и проверяет, что то же самое, что вы играли, было захвачено. Мое предложение состоит в том, чтобы использовать простой синусовый тон, чтобы БПФ мог сказать вам, если вы захватили то же самое.
Ответ на более общий вопрос: да, вы должны unit test все, что можете. Это создает наследие позже, поэтому изменения по дороге можно сделать с душевным спокойствием. Это гарантирует, что ваш код работает так, как ожидалось. Он также документирует предполагаемое использование интерфейсов. Наконец, он улучшает стиль кодирования. Обычно что-то трудное для unit test также плохо спроектировано. Написание для проверки означает запись для лучшего дизайна.
Ответ 6
Другой пример: если вы разрабатываете игровой движок, вы хотите проверить свои функции затенения и другие функции, но вы должны подтвердить его визуально - что ни один классический UnitTest не может решить.
Ваш случай: по мере того, как ваше приложение становится более сложным, становится болезненным всегда щелкнуть ваш пользовательский интерфейс, чтобы проверить все ваши функции.
Я бы написал "интерактивный TestSuite", где показаны различные фиктивные диалоги (настроенные для каждого тестового случая), только с функциями, которые необходимо проверить. Как только вы закроете диалоговое окно, вам будет предложено, ожидалось ли поведение. Но я не уверен, есть ли доступные решения, которые могут помочь здесь.
Ответ 7
Возможно, вы захотите проверить мою серию "Тестирование невозможного" в своем блоге для некоторых идей, как тестировать.
В вашем случае я предлагаю следовать идее Steve Rowe, чтобы написать тест, который устанавливает динамик и микрофон и использует кабель обратной связи для тестирования оборудования установочный код плюс API, который позволяет передавать данные через динамик и считывать данные с микрофона.
Это unit test, но не автоматическое. Переместите его в независимый набор тестов, который не запускается с другими автоматическими тестами. Если вы хотите его автоматизировать, настройте второй ПК с правильной конфигурацией (плюс кабель обратной связи) и дистанционно выполните тест.
После этого вы уверены, что настройка аппаратного обеспечения работает, вы можете отправлять и получать аудио. Это позволяет тестировать классы обработки данных независимо от оборудования. Используйте макеты, чтобы имитировать динамик и микрофон.
Ответ 8
Код, который захватывает и воспроизводит звук, не может быть проверен на единицу (хотя вы можете проверить, что метод захвата возвращает ошибку при вызове, когда класс не привязан к ресурсу).
Однако, если вы просто не записываете захваченный звук на диск, код, который вызывает ваши классы захвата и воспроизведения, безусловно, может.
Два совета:
- Не тестируйте компилятор (например, getter и setter)
- Проверьте все, что может сломаться
Ответ 9
Дешевый ответ: Проверить все, что может сломаться
В конечном счете, хотя вам нужно понять ценность бизнеса в тестах, которые вы пишете - не отличается от любых других усилий, которые вы тратите, на любую другую кодовую базу, которую вы обязуетесь поддерживать.
Ответ 10
Я тестирую большинство вещей.
Всякий раз, когда я пишу тесты, я также рассматриваю тесты как документацию или инструкции о том, как мой код должен использоваться, для меня и других, чтобы читать в будущем.
Я не тестирую реализацию. Я хочу иметь возможность изменять реализацию, не изменяя мои тесты.
Я использовал TDD, возможно, год или два, поэтому, возможно, я созрею и остановлюсь. Пока что я все еще участвую и думаю, что я не пишу достаточно тестов.
Ответ 11
Если вы столкнулись с трудностями при настройке определенной области кода для тестирования, возможно, стоит исследовать насмешливую структуру, например jMock, или EasyMock.
Ответ 12
Я стараюсь писать тесты как можно больше. Не только доказать, что что-то работает, но и сделать его очевидным для кого-то еще, когда они неизбежно нарушают его позже.
У меня был метод длиной 1 строка. В подобных местах в моем приложении я написал модульные тесты, но, находясь в спешке, я подумал, что это не может провалиться. Я ошибся, это не сработало: -)
Дополнительным преимуществом написания модульных тестов является не только проверка вашего кода, но и тот, кто никогда не видел ваш код раньше, может прочитать тесты и понять, как ваш код должен работать с учетом конкретных сценариев... как спецификация.
Ответ 13
Проектирование тестов - это приобретенное умение - чем больше вы проверяете, тем лучше вы его получите. Некоторые вещи трудно тестировать, но если вы думаете об этом в течение нескольких минут, вы часто можете найти способ.
Тесты могут быть беспорядочными - например, программа java может запускать интерпретатор или даже оболочку, такую как bash, которая, в свою очередь, запускает серию unix-фильтров, которые, как вы надеетесь, выведут идентичные двоичные файлы. Не волнуйтесь - качество тестового кода не должно превышать код готового продукта.