Домой Android разработкаОрганизация кода и DevOps Различия Unit и Функционального тестирования

Различия Unit и Функционального тестирования

by dilix
Unit и функциональные тесты

В тестировании ПО есть несколько логических уровней. Бывают unit, функциональные, смоук тесты. Давайте разберем отличия Unit и Функциональных тестов, для чего они нужны и когда используются.

Юнит тесты помогают писать качественный код, быстро работают и создаются. Тем не менее они не гарантируют что вся система работает так как задумано. Такие тесты говорят где проблема конкретно в вашем коде.

Функциональные тесты могут работать сравнительно долго и быть сложными по своей структуре. Главная их цель — убедиться, что код делает то, что было изначально задумано. Такие тесты говорят где проблема в реализации и логике.

(c) https://www.simform.com/unit-testing-vs-functional-testing/

Утрированный пример различия тестов

Предположим, что у нас есть функция, которую хотим протестировать.


un sum(a: Int, b: Int): Int {
    if (a == 2 && b == 2) return 5
    return a + b
}

Unit тесты

Юнит тесты пишутся по методу «белого ящика» — вы смотрите на код, знаете что он делает и почему.

Вопрос, на который мы хотим получить ответ:

Делает ли мой код то, что я написал

@Test
fun `Unit test for edge case`() {
    sum(2, 2) shouldBe 5
}

@Test
fun `Unit test for regular case`() {
    sum(4, 10) shouldBe 14
}

Данные два тесты покрывают все возможные ветки вашего кода. Теперь можно быть уверенными, что код делает именно что, что имел в виду разработчик.

Если кто-нибудь поменяет реализацию методы, то тесты вероятно упадут. Это же будет служить подсказкой, что вы поменяли нечто, во что другой разработчик вложил некий смысл и тестами «зафиксировал» логику работы функции.

Функциональные тесты

Функциональные тесты пишутся по методу «черного ящика» — вы смотрите на сигнатуру и суть метода. Вам все равно как он работает внутри. Единственное что важно — входные параметры и ожидаемый результат.

Вопрос, на который мы хотим получить ответ:

Выполняет ли мой код то, что я от него жду как пользователь?

@Test
fun `Functional test for any number`() {
    for (a in Int.MIN_VALUE..Int.MAX_VALUE) {
        for (b in Int.MIN_VALUE..Int.MAX_VALUE) {
            sum(a, b) shouldBe a + b
        }
    }
}

@Test
fun `Sum of 2 Ints should be positive`() {
    for (a in 0..Int.MAX_VALUE) {
        for (b in 0..Int.MAX_VALUE) {
            sum(a, b) shouldBeGreaterThan 0
        }
    }
}

Данные два теста описывают ожидаемое а не реальное поведение функции. После выполнения тестов автоматически появится как минимум два вопроса:

  • Корректно ли что метод отработает только, когда оба значения в сумме будут меньше чем `Int.MAX_VALUE`? Иначе происходит переполнение.
  • Предполагалось ли, что 2+2=5?

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

Тесты также стоит запускать перед слиянием кода в общую ветку для того, чтобы убедиться, что код прежний код работает как ожидалось. Еще можно прогонять их как шаг сборки при сборке вашего проекта на CI перед отправкой тестировщикам. Однажды видел, что запуск тестов также вешали на git hooks,  но на мой взгляд это излишне, т.к. замедляет работу в целом это стоит делегировать на CI сервер. Важный момент, который стоит учесть, что даже протестированный код в Android может упасть из-за Proguard.

Хочешь обсудить Android разработку?
Заходи к нам Вконтакте, на Facebook и в Телеграм!

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

1 комментарий

shifu 05.10.2022 - 10:05

спасибо

Ответить

Может быть интересно

Этот сайт использует Cookie файлы для улучшения вашего пользовательского взаимодействия. Используя данный сайт вы соглашается с этим. Принять Читать

Политика конфиденциальности и Cookies
%d