Основы тестирования с JUnit в Kotlin: урок в Android Studio

Когда приложение становится крупным, проверять каждый экран вручную становится невыполнимой задачей. На выручку приходят автоматические тесты — небольшие программы, которые запускают фрагменты вашего кода и проверяют, всё ли функционирует корректно. Сегодня на занятии в Android Studio мы рассмотрим основы модульного тестирования на языке Kotlin. В этом уроке для новичков мы покажем, как создать первый тест, запустить его и интерпретировать результаты. Никаких чудес, только практика.


Что такое модульный тест и зачем он нужен

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

Регулярный запуск тестов даёт уверенность, что новые изменения не сломали старую логику. В Android тесты делятся на две большие группы: unit-тесты (проверяют чистую логику, без Android-зависимостей) и instrumented-тесты (запускаются на устройстве или эмуляторе). Начнём с первых — они проще и быстрее.


Создание тестового класса в проекте

Android Studio автоматически создаёт папки для тестов при генерации нового проекта. Они находятся в app/src/test/java/ — именно там живут unit-тесты. Чтобы создать первый тест, откройте эту папку, щёлкните правой кнопкой по имени пакета и выберите New → Kotlin Class/File. Назовите файл, например, CalculatorTest.

Тесты пишут с использованием библиотеки JUnit, которая уже добавлена в проект по умолчанию. Каждый тестовый метод помечается аннотацией @Test, а внутри него размещают проверки с помощью методов assertEquals, assertTrue и подобных.


Пишем первый тест для простого класса

Создадим обычный класс Calculator с одним методом add в основной папке app/src/main/java/. Затем протестируем его. Вот сам класс:

class Calculator {
    fun add(a: Int, b: Int): Int = a + b
}

А вот как выглядит тест для него:

import org.junit.Assert.assertEquals
import org.junit.Test

class CalculatorTest {

    @Test
    fun addition_isCorrect() {
        val calculator = Calculator()
        val sum = calculator.add(2, 3)
        assertEquals(5, sum)
    }
}

Метод assertEquals принимает ожидаемое значение первым аргументом, а фактическое — вторым. Если они не совпадут, тест упадёт и покажет разницу.


Запуск тестов в Android Studio

Чтобы запустить тест, откройте файл CalculatorTest и нажмите на зелёный треугольник рядом с названием класса или метода. Среда выполнит тест и покажет результат в нижней панели Run. Зелёная полоса — все тесты прошли, красная — какой-то упал. При падении студия укажет, какой именно метод не сработал и что пошло не так.

Тесты можно запускать и через терминал командой ./gradlew test. Результаты появятся в папке app/build/reports/tests/ в виде HTML-отчёта, который удобно просматривать в браузере.


Проверка на исключения

Иногда нужно убедиться, что метод выбрасывает ошибку при некорректных данных. Например, деление на ноль должно вызывать ArithmeticException. Для этого используют параметр expected в аннотации @Test или assertThrows.

@Test(expected = ArithmeticException::class)
fun division_byZero_throwsException() {
    val calculator = Calculator()
    calculator.divide(10, 0)
}

Если исключение не возникнет, тест упадёт. Это удобно для проверки защитных механизмов в коде.


Несколько тестовых методов в одном классе

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

@Test
fun addition_withNegativeNumbers_isCorrect() {
    val calculator = Calculator()
    assertEquals(-5, calculator.add(-2, -3))
}

@Test
fun addition_withZero_isCorrect() {
    val calculator = Calculator()
    assertEquals(7, calculator.add(7, 0))
}

Хорошее правило: название теста должно описывать, что именно проверяется. Тогда при падении вы сразу поймёте, какой сценарий сломался.


Полезные советы для начинающих

  • Тестируйте только свой код. Не нужно проверять, правильно ли работает библиотека Retrofit или Room — их авторы уже сделали это за вас.
  • Пишите тесты сразу. Как только дописали метод — напишите тест. Откладывать на потом вредно: через неделю вы забудете детали, и тестировать станет сложнее.
  • Держите тесты быстрыми. Unit-тесты должны выполняться за миллисекунды. Если тест медленный, вероятно, он зависит от сети или базы данных — это уже не unit-тест.

Основные моменты

В ходе этого урока в Android Studio на Kotlin вы освоили основы модульного тестирования. Вы создали тестовый класс, написали несколько тестов с использованием JUnit, запустили их и получили результаты. Теперь ваш код защищён от случайных ошибок, и при внесении изменений вы сразу видите, не возникли ли проблемы в других частях программы. Начните с простого: протестируйте пару методов в своём проекте, и вы заметите, насколько спокойнее становится процесс разработки.