Какие инструменты и подходы используются для тестирования в Go?

Ответ

В Go существует мощная встроенная экосистема для тестирования, дополненная популярными сторонними библиотеками.

1. Основа: Стандартная библиотека testing

Это основной инструмент для написания тестов. Он поддерживает:

  • Unit-тесты: Функции вида func TestXxx(t *testing.T). Запускаются командой go test.
  • Бенчмарки: Функции вида func BenchmarkXxx(b *testing.B) для измерения производительности.
  • Примеры: Функции вида func ExampleXxx() для документации и проверки вывода.
// Файл my_func_test.go
package my_package

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}

2. Тестирование HTTP

Стандартный пакет net/http/httptest предоставляет утилиты для тестирования HTTP-обработчиков без запуска реального сервера.

req := httptest.NewRequest("GET", "/", nil)
rr := httptest.NewRecorder()
handler := http.HandlerFunc(MyHandler)

handler.ServeHTTP(rr, req)

// Проверяем статус код и тело ответа
if status := rr.Code; status != http.StatusOK {
    t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
}

3. Популярные сторонние библиотеки

  • testify/assert и testify/require: Предоставляют богатый набор функций-утверждений (assertions), делая тесты более читаемыми и лаконичными. require прерывает тест при первой ошибке, assert — продолжает выполнение.

    import (
        "testing"
        "github.com/stretchr/testify/assert"
    )
    
    func TestSomething(t *testing.T) {
        assert.Equal(t, 123, 123, "они должны быть равны")
    }
  • gomock и testify/mock: Инструменты для создания моков (mock objects). gomock генерирует моки из интерфейсов, а testify/mock позволяет создавать их вручную. Моки необходимы для изоляции тестируемого компонента от его зависимостей (например, базы данных или внешнего API).

4. Интеграционное тестирование

  • testcontainers-go: Библиотека для управления жизненным циклом Docker-контейнеров прямо из тестов. Идеально подходит для интеграционных тестов, требующих реальных зависимостей, таких как PostgreSQL, Redis или Kafka.