Котлин корутины. Часть 3. Тестирование корутин через поведение

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

Библиотека

Недавно была запущена библиотека kotlinx-coroutines-test, которая предоставляет множество утилит для упрощения тестирования сопрограмм на Android. Библиотека на момент подготовки урока имела статус @ExperimentalCoroutinesApi и может измениться до окончательного выпуска.

Библиотека предоставляет возможность установить Dispatchers.Main для запуска тестов вне устройства, а также диспетчер тестирования, который позволяет тестовому коду контролировать выполнение корутин.

Он предлагает вам возможность:

Автоматический переход времени для обычных функций приостановки
Явно контролировать время для тестирования нескольких корутин
Немедленно выполнить тела запуска или асинхронные блоки кода
Приостановка, ручное прохождение и перезапуск выполнения корутин в тесте
Сообщение о невыполненных исключениях как об ошибках теста
Чтобы узнать больше, прочитайте документацию для kotlinx-coroutines-test.

Поскольку библиотека в настоящее время помечена как экспериментальная, эта статья покажет вам, как писать тесты с использованием стабильных API, пока она не станет стабильной.

В конце этого раздела вы можете найти тестовый код, переписанный с помощью kotlinx-coroutines-test.

Просмотрите существующий тест

Откройте MainViewModelTest.kt в папке androidTest.

Перед каждым тестом происходят две вещи:

  1. Правило — это способ запуска кода до и после выполнения теста в JUnit. InstantTaskExecutorRule — это правило JUnit, которое настраивает LiveData для немедленной публикации в основном потоке во время выполнения теста.
  2. Во время настройки setup() теста поле subject  инициализируется новой MainViewModel.

После этой настройки теста определяется один тест:

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

Этот тест зависит только от общедоступного API ViewModel: когда вызывается onMainViewClicked, «Hello, from threads!»  будет отправлен в снэк-бар.

Мы не изменили общедоступный API, вызов метода все еще обновляет снэк-бар, поэтому изменение реализации на корутины не нарушит тест.

Запустите существующий тест

  1. Щелкните правой кнопкой мыши имя класса MainViewModelTest в вашем редакторе, чтобы открыть контекстное меню.
  2. В контекстном меню выберите execute.pngRun ‘MainViewModelTest’
  3. Для будущих запусков вы можете выбрать эту тестовую конфигурацию в конфигурациях рядом с кнопкой execute.png на панели инструментов.

По умолчанию конфигурация будет называться MainViewModelTest.

При запуске теста вы получите ошибку подтверждения, если вы выполнили предыдущее упражнение

Обновление не пройдено, чтобы пройти тест

Этот тест не пройден, потому что мы изменили поведение нашего метода. Вместо того, чтобы сказать «Hello, from threads!» он говорит «Hello, from coroutines!»

Обновите тест до нового поведения, изменив утверждение.

При повторном запуске теста с помощью execute.png на панели инструментов тест пройдёт

Протестировав только общедоступный API, мы смогли изменить наш тест с фонового потока на корутину без каких-либо изменений в структуре нашего теста.

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

Как насчет этой задержки?

Этот тест все еще имеет одну серьезную проблему. Требуется целая секунда, чтобы выполнить! Это связано с тем, что вызов delay (1_000) жестко закодирован в onMainViewClicked.

Тесты должны выполняться как можно быстрее, и этот может определенно выполняться быстрее. TestCoroutineDispatcher, предоставляемый kotlinx-coroutines-test, позволяет вам контролировать «виртуальное время» и вызывать функцию с задержкой в ​​одну секунду, фактически не ожидая ни секунды.

Вот вышеописанный тест, переписанный для использования экспериментального TestCoroutineDispatcher.

Продолжение:

Котлин корутины. Часть 4. Переход callback API на корутины

 

 

Добавить комментарий