Когда вы тестируете элемент или систему элементов, вы делаете это изолированно . Например, чтобы протестировать ViewModel, вам не нужно запускать эмулятор и пользовательский интерфейс, поскольку он не зависит (или не должен) зависеть от платформы Android.
Однако работа испытуемого может зависеть от других. Например, работа ViewModel может зависеть от хранилища данных.
Когда вам необходимо предоставить зависимость тестируемому объекту, обычной практикой является создание тестового двойника (или тестового объекта ). Тестовые двойники — это объекты, которые выглядят и действуют как компоненты вашего приложения, но создаются в вашем тесте для обеспечения определенного поведения или данных. Основные преимущества заключаются в том, что они делают ваши тесты быстрее и проще.
Виды тестовых двойников
Существуют различные типы тестовых двойников:
Фальшивый | Тестовый двойник, имеющий «рабочую» реализацию класса, но реализованную таким образом, что она хороша для тестов, но непригодна для производства. Пример: база данных в памяти. Подделки не требуют создания макета и имеют небольшой вес. Они предпочтительнее . |
---|---|
Насмехаться | Тестовый двойник, который ведет себя так, как вы его запрограммировали, и у которого есть ожидания относительно его взаимодействия. Моки не пройдут тесты, если их взаимодействие не соответствует определенным вами требованиям. Для достижения всех этих целей моки обычно создаются с помощью фреймворка для насмешек . Пример. Убедитесь, что метод в базе данных был вызван ровно один раз. |
Заглушка | Тестовый двойник, который ведет себя так, как вы его запрограммировали, но не имеет ожиданий относительно его взаимодействия. Обычно создается с помощью насмешливой структуры. Подделки предпочтительнее заглушек из-за простоты. |
Дурачок | Тестовый дубль, который передается, но не используется, например, если вам просто нужно предоставить его в качестве параметра. Пример: пустая функция, переданная как обратный вызов щелчка. |
Шпион | Обертка над реальным объектом, которая также отслеживает некоторую дополнительную информацию, похожую на макеты. Их обычно избегают из-за усложнения. Поэтому фальшивки или издевательства предпочтительнее шпионов. |
Тень | Подделка, используемая в Робоэлектрике. |
Пример использования подделки
Предположим, вы хотите выполнить модульное тестирование ViewModel, которая зависит от интерфейса UserRepository
и отображает имя первого пользователя в пользовательском интерфейсе. Вы можете создать поддельный тестовый дубль, реализовав интерфейс и вернув известные данные.
object FakeUserRepository : UserRepository {
fun getUsers() = listOf(UserAlice, UserBob)
}
val const UserAlice = User("Alice")
val const UserBob = User("Bob")
Этот поддельный UserRepository
не должен зависеть от локальных и удаленных источников данных, которые будет использовать производственная версия. Файл находится в тестовом наборе исходного кода и не будет поставляться с рабочим приложением.
Следующий тест проверяет, что ViewModel правильно предоставляет представлению первое имя пользователя.
@Test
fun viewModelA_loadsUsers_showsFirstUser() {
// Given a VM using fake data
val viewModel = ViewModelA(FakeUserRepository) // Kicks off data load on init
// Verify that the exposed data is correct
assertEquals(viewModel.firstUserName, UserAlice.name)
}
Заменить UserRepository
поддельным в модульном тесте легко, поскольку ViewModel создается тестировщиком. Однако замена произвольных элементов в более крупных тестах может оказаться сложной задачей.
Замена компонентов и внедрение зависимостей
Когда тесты не контролируют создание тестируемых систем, замена компонентов для тестовых двойников становится более сложной задачей и требует, чтобы архитектура вашего приложения соответствовала тестируемому дизайну.
Даже большие сквозные тесты могут выиграть от использования двойников тестов, таких как инструментальный тест пользовательского интерфейса, который проходит через весь поток пользователей в вашем приложении. В этом случае вы можете сделать свой тест герметичным . Герметичный тест позволяет избежать всех внешних зависимостей, таких как получение данных из Интернета. Это повышает надежность и производительность.
Вы можете спроектировать свое приложение так, чтобы добиться такой гибкости вручную, но мы рекомендуем использовать среду внедрения зависимостей , например Hilt, для замены компонентов в вашем приложении во время тестирования. См. руководство по тестированию Hilt.
Следующие шаги
На странице «Стратегии тестирования» показано, как можно повысить производительность с помощью различных типов тестов.