Модульное тестирование

Модульное тестирование, или юнит-тестирование (англ.unit testing)— процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.

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

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

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

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

Причины использования модульного тестирования.

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

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

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

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

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

Когда модульное тестирование не работает

Сложный код - тестирование программного обеспечения— комбинаторная задача. Например, каждое возможное значение булевской переменной потребует двух тестов: один на вариант TRUE, другой— на вариант FALSE. В результате на каждую строку исходного кода потребуется 3-5 строк тестового кода.

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

Результат известен лишь приблизительно - например, в математическом моделировании. Бизнес-приложения зачастую работают с конечными и счётными множествами, научные— с континуальными. Поэтому сложно подобрать тесты для каждой из ветвей программы, сложно сказать, верен ли результат, выдерживается ли точность, итакдалее. А во многих случаях качество моделирования определяется «на глаз», и последний результат записывается как «опорный». Если найдено расхождение, новый результат проверяют вручную и выясняют, какой качественнее: старый или новый.

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

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