Что такое модульное тестирование?

Я видел много вопросов, спрашивающих "как" на unit test на определенном языке, но не спрашивая "что", "почему" и "когда".

  • Что это такое?
  • Что он делает для меня?
  • Почему я должен использовать его?
  • Когда я должен использовать его (также когда нет)?
  • Каковы некоторые распространенные ошибки и неправильные представления.

Ответ 1

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

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

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

Еще один способ взглянуть на модульное тестирование - это то, что вы сначала пишете тесты. Это называется Test-Driven Development (TDD для краткости). TDD дает дополнительные преимущества:

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

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

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


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

Ответ 2

Я не согласен с Дэном (хотя лучшим выбором может быть просто не отвечать), но...

Модульное тестирование - это процесс написания кода для проверки поведения и функциональности вашей системы.

Очевидно, тесты улучшают качество вашего кода, но это просто поверхностное преимущество модульного тестирования. Реальные преимущества заключаются в следующем:

  • Упростите изменение технической реализации, убедившись, что вы не изменяете поведение (рефакторинг). Правильно проверенный модулем код может быть агрессивно реорганизован/очищен с небольшим шансом сломать что-либо, не заметив его.
  • Предоставьте разработчикам уверенность в добавлении поведения или исправлении.
  • Документируйте свой код
  • Укажите области вашего кода, которые тесно связаны. Это трудно для unit test кода, который тесно связан с
  • Предоставьте средства для использования вашего API и поискайте трудности на раннем этапе.
  • Указывает методы и классы, которые не очень сплочены

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

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

Самая большая ошибка заключается в том, что разработчики тестируют слишком большую единицу или считают метод единицей. Это особенно верно, если вы не понимаете Inversion of Control - в этом случае ваши юнит-тесты всегда будут проходить комплексное тестирование интеграции, unit test должен проверять индивидуальное поведение - и большинство методов имеют много типов поведения.

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

Ответ 3

Основное отличие модульного тестирования, в отличие от "просто открытия нового проекта и проверки этого конкретного кода", заключается в том, что он автоматизирован, следовательно, повторяется.

Если вы проверите свой код вручную, это может убедить вас, что код работает отлично - в его текущем состоянии. Но как насчет недели спустя, когда вы сделали небольшую модификацию? Вы готовы повторно протестировать его вручную, когда что-нибудь изменится в вашем коде? Скорее всего, нет: - (

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

Это основное преимущество модульных тестов для ручного тестирования. Но подождите, есть еще:

  • модульные тесты резко сокращают цикл обратной связи разработки: с отдельным отделом тестирования может потребоваться несколько недель, чтобы вы знали, что в вашем коде есть ошибка, и к этому времени вы уже забыли большую часть контекст, поэтому вам может потребоваться время, чтобы найти и исправить ошибку; OTOH с модульными тестами, цикл обратной связи измеряется в секундах, а процесс исправления ошибок обычно выполняется по строкам "oh sh * t, я забыл проверить это условие здесь": -)
  • модуль эффективно анализирует документ (ваше понимание) поведения вашего кода
  • модульное тестирование заставляет вас переоценить ваши варианты дизайна, что приводит к более простому, более чистому дизайну

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

Ответ 4

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

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

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

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

Ответ 5

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

  • TDD НЕ означает запись в два раза количества кода. Тестовый код обычно довольно быстрый и безболезненный для записи и является ключевой частью вашего процесса проектирования и критически.

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

  • Тесты и код работают вместе для достижения лучшего кода. Ваш код может быть плохой/багги. Ваш ТЕСТ может быть плохой/багги. В TDD вы полагаетесь на вероятность того, что BOTH будет плохой/багги довольно низкой. Часто это тест, который нуждается в исправлении, но который все еще является хорошим результатом.

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

  • В том же ключе эти типы дизайнеров могут ПОСМОТРЕТЬ, над чем они работают. Они могут бродить по перерыву сока/сигареты/iphone и возвращаться к монитору, который сразу же дает им визуальный сигнал о том, где они попали. TDD дает нам нечто подобное. Легче видеть, где мы оказались, когда жизнь вмешивается...

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

  • TDD помогает во всех видах удивительных путей вниз по линии. Хорошие модульные тесты могут помочь документировать то, что что-то должно делать, они могут помочь вам перенести код из одного проекта в другой и дать вам необоснованное чувство превосходства над коллегами, не тестирующими:)

Эта презентация является отличным введением во все тесты доброты доброты.

Ответ 6

Я хотел бы порекомендовать книгу XUnit Testing Patterns от Gerard Meszaros. Он большой, но является отличным ресурсом для модульного тестирования. Вот ссылка на его веб-сайт, где он обсуждает основы модульного тестирования. http://xunitpatterns.com/XUnitBasics.html

Ответ 7

Это мое занятие. Я бы сказал, что модульное тестирование - это практика написания тестов программного обеспечения, чтобы убедиться, что ваше реальное программное обеспечение делает то, что оно предназначено. Это началось с jUnit в мире Java и стало лучшей практикой в ​​PHP, а также с SimpleTest и phpUnit. Это основная практика Extreme Programming и помогает вам быть уверенным в том, что ваше программное обеспечение по-прежнему работает по назначению после редактирования. Если у вас есть достаточный охват тестирования, вы можете выполнить основной рефакторинг, исправление ошибок или быстро добавить функции с гораздо меньшим страхом перед другими проблемами.

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

Тестирование модулей обычно связано с разработкой OO. Основная идея заключается в создании script, который настраивает среду для вашего кода, а затем выполняет ее; вы пишете утверждения, указываете предполагаемый вывод, который вы должны получить, а затем выполните свой тест script с использованием структуры, такой как упомянутые выше.

Структура проведет все тесты против вашего кода, а затем сообщит о успехе или неудаче каждого теста. По умолчанию phpUnit запускается из командной строки Linux, хотя для него доступны HTTP-интерфейсы. SimpleTest основан на веб-интерфейсах по своей природе и намного легче запускать и запускать IMO. В сочетании с xDebug phpUnit может предоставить вам автоматическую статистику для покрытия кода, которые некоторые люди считают очень полезными.

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

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

Ответ 8

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

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

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

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

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

Для тестирования доступа к данным я пытаюсь написать тесты, которые либо не меняются, либо очищаются после себя.

Модульные тесты arent будут способны решить все требования к тестированию. Они смогут сэкономить время разработки и проверить основные части приложения.

Ответ 9

LibrarIES, такие как NUnit, xUnit или JUnit являются обязательными, если вы хотите разрабатывать свои проекты, используя TDD, популяризированный Кентом Бек:

Вы можете прочитать Введение в Test Driven Development (TDD) или книгу Кента Бек Разработка, основанная на тестах: на примере.

Затем, если вы хотите, чтобы ваши тесты охватывали "хорошую" часть вашего кода, вы можете использовать программное обеспечение, например NCover, JCover, PartCover или без разницы. Они расскажут вам процент покрытия вашего кода. В зависимости от того, насколько вы хорошо разбираетесь в TDD, вы узнаете, хорошо ли вы это сделали:)

Ответ 10

Используйте Testivus. Все, что вам нужно знать, находится прямо там:)

Ответ 11

Тестирование модулей касается написания кода, который проверяет ваш код приложения.

Единичная часть имени - это намерение тестировать небольшие единицы кода (один метод, например) за раз.

xUnit поможет вам в этом тестировании - это рамки, которые помогают в этом. Часть из них - автоматические тестовые бегуны, которые сообщают вам, какой тест терпит неудачу и какие из них проходят.

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

У вас может быть тест, чтобы проверить, что было выбрано ожидаемое исключение, без необходимости писать весь блок catch try.

Ответ 12

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

xUnit, NUnit, mbUnit и т.д. - это инструменты, которые помогут вам в написании тестов.

Ответ 13

Я думаю, что вы не понимаете, что инфраструктура модульного тестирования, такая как NUnit (и тому подобное), поможет вам в автоматизации тестов малого и среднего размера. Обычно вы можете запускать тесты в графическом интерфейсе (например, в случае NUnit), просто нажав кнопку, а затем - надеюсь - видеть, что индикатор выполнения остается зеленым. Если он становится красным, структура показывает, какой тест завершился неудачно, и что именно пошло не так. В обычном unit test, вы часто используете утверждения, например. Assert.AreEqual(expectedValue, actualValue, "some description") - поэтому, если два значения не равны, вы увидите сообщение об ошибке "некоторое описание: ожидаемое <expectedValue> , но оно было <actualValue> ".

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

Ответ 14

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

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

Таким образом, unit test будет использовать функциональность, включенную в "функцию", которую вы тестируете, без побочных эффектов обновления базы данных.

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

В unit test вы просто хотите проверить правильность расчета стандартного отклонения. В тесте интеграции вы хотите протестировать расчет стандартного отклонения и извлечение базы данных.

Ответ 15

Test Driven Development используется как термин Unit Test. В качестве старого таймера я упомянул более общее его определение.

Unit Test также означает тестирование одного компонента в более крупной системе. Этот единственный компонент может быть dll, exe, библиотекой классов и т.д. Это может быть даже одна система в многосистемном приложении. Таким образом, в конечном итоге Unit Test заканчивается тестированием того, что вы хотите назвать одной частью более крупной системы.

Затем вы переходите к интегрированному или системному тестированию, проверяя, как все компоненты работают вместе.

Ответ 16

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

Ответ 17

Я отправился на презентацию об модульном тестировании на FoxForward 2007, и мне было сказано, что unit test ничего не работает с данными. В конце концов, если вы тестируете данные в реальном времени, результаты непредсказуемы, и если вы не тестируете данные в реальном времени, вы фактически не проверяете код, который вы написали. К сожалению, большинство кодировок я делаю в эти дни.: -)

В последнее время я делал снимок в TDD, когда писал программу для сохранения и восстановления настроек. Во-первых, я подтвердил, что могу создать объект хранения. Затем, чтобы у меня был метод, который мне нужно было вызвать. Тогда я мог бы это назвать. Тогда, чтобы я мог передать ему параметры. Затем, чтобы я мог передать ему конкретные параметры. И так далее, пока я наконец не подтвердил, что он сохранит указанный параметр, позвольте мне изменить его, а затем восстановить его для нескольких разных синтаксисов.

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

Ответ 18

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

Как мы можем выполнить модульное тестирование?

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

Сейчас у нас более 40%, и нам удалось отобрать большинство низко висящих фруктов.

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

Ответ 19

Это объясняет, почему вы должны выполнять модульное тестирование.


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

Тестирование устройств: минуты спустя будут экономить часы спустя - Эрик Манн - https://www.youtube.com/watch?v=_UmmaPe8Bzc

JS Unit Testing (очень хорошо) - https://www.youtube.com/watch?v=-IYqgx8JxlU

Запись тестового JavaScript - https://www.youtube.com/watch?v=OzjogCFO4Zo


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

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


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

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


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

Кроме того, вам не нужно unit test код, если вы этого не хотите, но он окупается, так как ваша база проектов/кодов начинает расти, так как увеличивается вероятность появления ошибок.

Ответ 20

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