2009-02-05 2 views
20

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

ответ

36

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

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

+1

+1: Откажитесь от оборудования с помощью симулятора и используйте его. –

+30

Я пробовал насмехаться над управлением и компанией. Он работал нормально, пока банк не начал подпрыгивать от моего MockPaychecks.Я вышел и попытался объяснить, что я провожу TDD как силу социальных изменений, но они назвали безопасность. Глупые банкиры. – ddaa

0

Если вы столкнулись с трудностями при настройке определенной области кода для тестирования, возможно, стоит исследовать насмешливую структуру, например jMock, или EasyMock.

2

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

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

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

1

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

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

13

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

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

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

4

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

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

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

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

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

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

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

1

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

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

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

+0

Хорошо, неудачный пример и выбор слов. Но на самом деле это было не мое. –

+0

Для тестирования диалогов см. В моем блоге: http://darkviews.wordpress.com/2008/11/11/testing-the-impossible-user-dialogs/ –

1

Возможно, вы захотите проверить мою серию «Тестирование невозможного» в своем блоге для некоторых идей, как протестировать.

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

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

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

+0

Не могли бы вы разместить ссылку на свой блог? – finnw

+0

http://darkviews.wordpress.com/tag/tdd/ Есть несколько связанных должностей, которые вы будете испытывать под тегом. –

1

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

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

Два куска советы:

  • Не тестируются компилятор (например, добытчик и сеттеры)
  • Тест все, что могло бы нарушить
0

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

У меня был метод, который был длиной 1 строка. В подобных местах в моем приложении я написал модульные тесты, но, находясь в спешке, я подумал, что это не может провалиться. Я был неправ, это не сработало :-)

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

+1

Кажется, сайт изменился с тех пор, как я опубликовал этот ответ. Я изменил свой ответ, спасибо, что потратил время на рассмотрение моих ответов :) –

1

Дешевый ответ: Test everything that could possibly break

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

0

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

Испытания могут быть грязными - например, программа java может запускать интерпретатор или даже оболочку, такую ​​как bash, которая, в свою очередь, запускает серию unix-фильтров, которые, как вы надеетесь, будут выводить идентичные двоичные файлы. Не волнуйтесь - качество тестового кода не должно превышать код готового продукта.

1

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

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

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

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

Смежные вопросы