1. Что такое «модульное тестирование»?
Модульное/компонентное тестирование (unit testing) - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.
Модульные тесты можно условно поделить на две группы:
-
тесты состояния (state based), проверяющие что вызываемый метод объекта отработал корректно, проверяя состояние тестируемого объекта после вызова метода.
-
тесты взаимодействия (interaction tests), в которых тестируемый объект производит манипуляции с другими объектами. Применяются, когда требуется удостовериться, что тестируемый объект корректно взаимодействует с другими объектами.
2. Что такое «интеграционное тестирование»?
Интеграционное тестирование (integration testing) — это тестирование, проверяющие работоспособность двух или более модулей системы в совокупности — то есть нескольких объектов как единого блока. В тестах взаимодействия же тестируется конкретный, определенный объект и то, как именно он взаимодействует с внешними зависимостями.
3. Чем интеграционное тестирование отличается от модульного?
С технологической точки зрения интеграционное тестирование является количественным развитием модульного, поскольку так же, как и модульное тестирование, оперирует интерфейсами модулей и подсистем и требует создания тестового окружения, включая заглушки на месте отсутствующих модулей. Основная разница между модульным и интеграционным тестированием состоит в целях, то есть в типах обнаруживаемых дефектов, которые, в свою очередь, определяют стратегию выбора входных данных и методов анализа.
Допустим, есть класс, который при определенных условиях взаимодействует с web-сервисом через зависимый объект. И нам надо проверить, что определенный метод зависимого объекта действительно вызывается. Если в качестве зависимого класса передать:
реальный класс, работающий с web-сервисом, то это будет интеграционное тестирование.
заглушку, то это будет тестирование состояния.
шпиона, а в конце теста проверить, что определенный метод зависимого объекта действительно был вызван, то это будет тест взаимодействия.
4. Какие существуют виды тестовых объектов?
пустышка (dummy) - объект, который обычно передается в тестируемый класс в качестве параметра, но не имеет поведения: с ним ничего не происходит и никакие его методы не вызываются.
Примером dummy-объектов являются new object(), null, «Ignored String» и т.д.
фальшивка (fake object) применяется в основном для ускорения запуска ресурсоёмких тестов и является заменой тяжеловесного внешнего зависимого объекта его легковесной реализацией.
Основные примеры — эмулятор базы данных (fake database) или фальшивый web-сервис.
заглушка (test stub) используется для получения данных из внешней зависимости, подменяя её. При этом заглушка игнорирует все данные, поступающие из тестируемого объекта, возвращая заранее определённый результат.
Тестируемый объект использует чтение из конфигурационного файла? Тогда передаем ему заглушку
ConfigFileStub
возвращающую тестовые строки конфигурации без обращения к файловой системе.
шпион (test spy) - разновидность заглушки, которая умеет протоколировать сделанные к ней обращения из тестируемой системы, чтобы проверить их правильность в конце теста. При этом фиксируется количество, состав и содержание параметров вызовов.
Если существует необходимость проверки, что определённый метод тестируемого класса вызывался ровно 1 раз, то шпион - именно то, что нам нужно.
фикция (mock object) похож на шпиона, но обладает расширенной функциональностью, заранее заданными поведением и реакцией на вызовы.
5. Чем stub отличается от mock?
stub используется как заглушка сервисов, методов, классов и т.д. с заранее запрограммированным ответом на вызовы.
mock использует подмену результатов вызова, проверяет сам факт взаимодействия, протоколирует и контролирует его.
6. Что такое «фикстуры»?
Фикстуры (fixtures) - состояние среды тестирования, которое требуется для успешного выполнения теста. Основная задача фикстур заключается в подготовке тестового окружения с заранее фиксированным/известным состоянием, чтобы гарантировать повторяемость процесса тестирования.
7. Какие аннотации фикстур существуют в JUnit?
-
@BeforeClass
- определяет код, который должен единожды выполниться перед запуском набора тестовых методов. -
@AfterClass
- код, выполняемый один раз после исполнения набора тестовых методов. -
@Before
- определяет код, который должен выполняться каждый раз перд запуском любого тестовым методом. -
@After
- код, выполняемый каждый раз после исполнения любого тестового метода.
8. Для чего в JUnit используется аннотация @Ignore
?
@Ignore
указывает JUnit на необходимость пропустить данный тестовый метод.