Модульное тестирование
Модульное тестирование, или юнит-тестирование (англ. unit testing) — процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы.
Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.
Содержание
[убрать]Преимущества[править | править вики-текст]
Цель модульного тестирования — изолировать отдельные части программы и показать, что по отдельности эти части работоспособны.
Этот тип тестирования обычно выполняется программистами.
Поощрение изменений[править | править вики-текст]
Модульное тестирование позже позволяет программистам проводить рефакторинг, будучи уверенными, что модуль по-прежнему работает корректно (регрессионное тестирование). Это поощряет программистов к изменениям кода, поскольку достаточно легко проверить, что код работает и после изменений.
Упрощение интеграции[править | править вики-текст]
Модульное тестирование помогает устранить сомнения по поводу отдельных модулей и может быть использовано для подхода к тестированию «снизу вверх»: сначала тестируя отдельные части программы, а затем программу в целом.
Документирование кода[править | править вики-текст]
Модульные тесты можно рассматривать как «живой документ» для тестируемого класса. Клиенты, которые не знают, как использовать данный класс, могут использовать юнит-тест в качестве примера.
Отделение интерфейса от реализации[править | править вики-текст]
Поскольку некоторые классы могут использовать другие классы, тестирование отдельного класса часто распространяется на связанные с ним. Например, класс пользуется базой данных; в ходе написания теста программист обнаруживает, что тесту приходится взаимодействовать с базой. Это ошибка, поскольку тест не должен выходить за границу класса. В результате разработчик абстрагируется от соединения с базой данных и реализует этот интерфейс, используя свой собственный mock-объект. Это приводит к менее связанному коду, минимизируя зависимости в системе.
Когда модульное тестирование не работает[править | править вики-текст]
Сложный код[править | править вики-текст]
Тестирование программного обеспечения — комбинаторная задача. Например, каждое возможное значение булевской переменной потребует двух тестов: один на вариант TRUE, другой — на вариант FALSE. В результате на каждую строку исходного кода потребуется 3−5 строк тестового кода.
Как и любая технология тестирования, модульное тестирование не позволяет отловить все ошибки программы. В самом деле, это следует из практической невозможности трассировки всех возможных путей выполнения программы, за исключением простейших случаев.
Результат известен лишь приблизительно[править | править вики-текст]
Например, в математическом моделировании. Бизнес-приложения зачастую работают с конечными и счётными множествами, научные — с континуальными.[1] Поэтому сложно подобрать тесты для каждой из ветвей программы, сложно сказать, верен ли результат, выдерживается ли точность, и т. д. А во многих случаях качество моделирования определяется «на глаз», и последний результат записывается как «опорный». Если найдено расхождение, новый результат проверяют вручную и выясняют, какой качественнее: старый или новый.
Ошибки интеграции и производительности[править | править вики-текст]
Кроме того, происходит тестирование каждого из модулей по отдельности. Это означает, что ошибки интеграции, системного уровня, функций, исполняемых в нескольких модулях, не будут определены. Кроме того, данная технология бесполезна для проведения тестов на производительность. Таким образом, модульное тестирование более эффективно при использовании в сочетании с другими методиками тестирования.
При общей низкой культуре программирования[править | править вики-текст]
Для получения выгоды от модульного тестирования требуется строго следовать технологии тестирования на всём протяжении процесса разработки программного обеспечения. Нужно хранить не только записи обо всех проведённых тестах, но и обо всех изменениях исходного кода во всех модулях. С этой целью следует использовать систему контроля версий ПО. Таким образом, если более поздняя версия ПО не проходит тест, который был успешно пройден ранее, будет несложным сверить варианты исходного кода и устранить ошибку. Также необходимо убедиться в неизменном отслеживании и анализе неудачных тестов. Игнорирование этого требования приведёт к лавинообразному увеличению неудачных тестовых результатов.
Приложения модульного тестирования[править | править вики-текст]
Экстремальное программирование[править | править вики-текст]
Экстремальное программирование предполагает как один из постулатов использование инструментов автоматического модульного тестирования. Этот инструментарий может быть создан либо третьей стороной (например, Boost.Test), либо группой разработчиков данного приложения.
В экстремальном программировании используются модульные тесты для разработки через тестирование. Для этого разработчик до написания кода пишет тесты, отражающие требования к модулю. Очевидно, ни один из этих тестов до написания кода работать не должен. Дальнейший процесс сводится к написанию кратчайшего кода, удовлетворяющего данному набору тестов.
Техника модульного тестирования[править | править вики-текст]
Инструментарий[править | править вики-текст]
Для большинства популярных языков программирования высокого уровня существуют инструменты и библиотеки модульного тестирования. Некоторые из них:
- Для Java и Groovy
- JUnit JUnit.org
- TestNG testNG.org
- JavaTESK UniTESK.ru
- Spock (написан на Groovy)
- Для C
- CUnit cunit
- CTESK UniTESK.ru
- cfix cfix
- API Sanity Autotest — для динамических C/C++ библиотек в Unix-подобных ОС.
- Unity unity — для встраиваемых приложений
- MICRO_UNIT MICRO_UNIT — небольшой набор макросов с примерами использования.
- Для Ruby
- Для Objective-C
- OCUnit [3]
- Для C++
- Для .NET
- DUnit [12] — для Delphi
- EUnit [13] — Erlang
- Для Perl
- Для PHP
- Для Python
- vbUnit [24] — Visual Basic
- utPLSQL [25] — PL/SQL
- Для T-SQL
- Для ActionScript 2.0 — язык сценариев, используемый виртуальной машиной Adobe Flash Player версии 7 и 8
- Для ActionScript 3.0 — скриптовый язык, используемый виртуальной машиной Adobe Flash Player версии 9 и выше
- Для JavaScript
- Mocha (тестовый фреймворк) [32]
- Chai ("assertion library", используется совместно с тестовым framework'ом) [33]
- Sinon.JS (библиотека для создания mock'ов, stub'ов, spy'ев, используется совместо с тестовым framework'ом) [34]
- Karma runner (от создателей Angular.JS, "test runner" - организует среду выполнения тестов) [35]
- QUnit (от создателей jQuery) [36]
- JsUnit (больше не поддерживается создателями) [37]
- Jasmine (рекомендован создателями jsUnit) [38]
- D.O.H [39]
Поддержка на уровне языка[править | править вики-текст]
Некоторые языки имеют поддержку модульного тестирования на уровне синтаксиса. Это избавляет от необходимости выбирать, к какому фреймворку привязываться, и позволяет упростить перенос кода в другие проекты.
Пример таких языков:
Пример кода на языке D
class ABC { this() { val = 2; } private int val; public func() { val *= 2; } } unittest { ABC a; a.func(); assert( a.val > 0 && a.val < 555 ); // можно обратиться к приватной переменной внутри модуля }
Примеры[править | править вики-текст]
Java
public class TestAdder { public void testSum() { Adder adder = new AdderImpl(); // can it add positive numbers? assert(adder.add(1, 1) == 2); assert(adder.add(1, 2) == 3); assert(adder.add(2, 2) == 4); // is zero neutral? assert(adder.add(0, 0) == 0); // can it add negative numbers? assert(adder.add(-1, -2) == -3); // can it add a positive and a negative? assert(adder.add(-1, 1) == 0); // how about larger numbers? assert(adder.add(1234, 988) == 2222); } }
Примечания[править | править вики-текст]
См. также[править | править вики-текст]
Ссылки[править | править вики-текст]
- Сайты и ресурсы
- Тестирование программного обеспечения: модульные тесты — коллекция статей на сайте OpenQuality.ru (рус.)
- The Art Of Unit Testing (англ.)
- Статьи
- Модульное тестирование: 2+2 = 4? (рус.)
- Модульное тестирование. Зачем, как и кто (рус.)
- The evolution of Unit Testing Syntax and Semantics (англ.)
- Unit Testing Guidelines from GeoSoft (англ.)
Для улучшения этой статьи по информационным технологиям желательно?:
|