Простые помощники утверждений в Go

Одна из вещей, которые мне нравятся в Go, – это его стандартная библиотека, которая поставляется с батареями в комплекте. Конечно, некоторые пакеты (например, flag) не такие мощные или эргономичные, как имеющиеся альтернативы, но я обычно готов с этим смириться, чтобы избежать зависимостей.

Тестирование

То же самое относится и к встроенной в Go поддержке тестирования, пакету testing. Давайте рассмотрим типичный тест:

package example

import "testing"

func Add(a, b int) int {
    return a + b
}

func TestAdd(t *testing.T) {
    want := 6
    got := Add(4, 2)

    if got != want {
        t.Errorf("got %v, wanted %v", got, want)
    }
}
Войти в полноэкранный режим Выход из полноэкранного режима

Это не слишком плохо, но становится немного повторяющимся, поэтому люди часто используют внешние библиотеки утверждений, такие как testify. Однако в большинстве своих проектов я стараюсь по возможности избегать внешних зависимостей, потому что не хочу заниматься их обновлением и тому подобной головной болью. Сегодня мне пришло в голову, что дженерики (добавленные в Go 1.18) позволяют легко писать полезные помощники утверждений, не прибегая к помощи библиотек. Вот помощник, который я добавил сегодня в один из своих проектов:

func assertEqual[T comparable](t *testing.T, got, want T) {
    t.Helper()

    if got != want {
        t.Errorf("got %v, wanted %v", got, want)
    }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Это утверждение равенства принимает параметр типа T, который будет удовлетворяться любым типом, удовлетворяющим интерфейсу comparable, определенному в блоке universe. Кроме того, он принимает три позиционных параметра: тестовый пример, а также фактическое и желаемое значения. Метод t.Helper() гарантирует, что о неудачных утверждениях будет сообщено для строки, где используется assertEqual, а не для строки внутри функции-помощника теста.

Вот как теперь выглядит тест:

package example

import "testing"

func Add(a, b int) int {
    return a + b
}

func TestAdd(t *testing.T) {
    want := 6
    got := Add(4, 2)

    assertEqual(t, got, want)

    // or simply
    // assertEqual(t, Add(4, 2), 6)
}
Вход в полноэкранный режим Выход из полноэкранного режима

Это не очень важно для одного теста, но заметно лучше для всего набора тестов.

Резюме

Использование новых дженериков Go позволило мне рефакторизовать и упростить набор тестов умеренно сложного проекта без необходимости добавления внешних зависимостей.

Оцените статью
Procodings.ru
Добавить комментарий