← Назад к вопросам

Какие использовал пакеты для тестирования?

2.0 Middle🔥 231 комментариев
#Тестирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Использование пакетов для тестирования в Go

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

Стандартные пакеты Go

testing - базовый пакет для модульного тестирования

Основной инструмент, который используется в 95% случаев. Его преимущество - простота и интеграция с инструментарием Go.

// Пример базового юнит-теста
func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"negative numbers", -1, -1, -2},
        {"mixed numbers", -5, 10, 5},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d, expected %d", 
                    tt.a, tt.b, result, tt.expected)
            }
        })
    }
}

testing/quick - для property-based тестирования

Использую для проверки инвариантов и свойств функций через случайные данные:

func TestCommutativeProperty(t *testing.T) {
    f := func(a, b int) bool {
        return Add(a, b) == Add(b, a)
    }
    if err := quick.Check(f, nil); err != nil {
        t.Error(err)
    }
}

httptest - для тестирования HTTP-обработчиков

Незаменимый инструмент при работе с веб-приложениями:

func TestUserHandler(t *testing.T) {
    req := httptest.NewRequest("GET", "/users/123", nil)
    w := httptest.NewRecorder()
    
    handler := UserHandler{}
    handler.ServeHTTP(w, req)
    
    if w.Code != http.StatusOK {
        t.Errorf("Expected status 200, got %d", w.Code)
    }
    
    var user User
    json.Unmarshal(w.Body.Bytes(), &user)
    if user.ID != "123" {
        t.Errorf("Expected user ID 123, got %s", user.ID)
    }
}

Сторонние пакеты и фреймворки

Testify - для улучшения читаемости тестов

Использую два основных компонента:

  • assert и require для более выразительных проверок
  • suite для организации тестов в наборы
func TestCalculate(t *testing.T) {
    assert.Equal(t, 4, Calculate(2, 2), "they should be equal")
    require.NotNil(t, obj, "object should not be nil")
    
    // Использование suite
    suite.Run(t, new(MyTestSuite))
}

Ginkgo и Gomega - для BDD-стиля тестирования

Применяю для сложных интеграционных тестов и end-to-end сценариев:

var _ = Describe("Database Service", func() {
    var db *sql.DB
    var service *DatabaseService
    
    BeforeEach(func() {
        db = setupTestDB()
        service = NewDatabaseService(db)
    })
    
    It("should create a user", func() {
        user, err := service.CreateUser("test@example.com")
        Expect(err).To(BeNil())
        Expect(user.Email).To(Equal("test@example.com"))
    })
})

Mockery или GoMock - для создания моков

Использую для изоляции тестируемого кода от зависимостей:

// Создание мок-интерфейса
type MockStorage struct {
    mock.Mock
}

func (m *MockStorage) Get(id string) (*User, error) {
    args := m.Called(id)
    return args.Get(0).(*User), args.Error(1)
}

// В тесте
func TestServiceWithMock(t *testing.T) {
    mockStorage := new(MockStorage)
    mockStorage.On("Get", "123").Return(&User{ID: "123"}, nil)
    
    service := NewService(mockStorage)
    user, err := service.GetUser("123")
    
    assert.NoError(t, err)
    assert.Equal(t, "123", user.ID)
    mockStorage.AssertExpectations(t)
}

Специализированные инструменты

testify/suite - для тестовых сценариев

Использую для сложных тестов, требующих setup/teardown логики:

type IntegrationSuite struct {
    suite.Suite
    db *sql.DB
}

func (s *IntegrationSuite) SetupTest() {
    s.db = setupTestDatabase()
}

func (s *IntegrationSuite) TearDownTest() {
    s.db.Close()
}

go-sqlmock - для тестирования SQL-запросов

Позволяет проверять SQL-запросы без реальной базы данных:

func TestGetUser(t *testing.T) {
    db, mock, _ := sqlmock.New()
    defer db.Close()
    
    rows := sqlmock.NewRows([]string{"id", "name"}).
        AddRow("1", "John")
    
    mock.ExpectQuery("SELECT (.+) FROM users WHERE id = ?").
        WithArgs("1").
        WillReturnRows(rows)
    
    // Тестирование репозитория
}

goconvey - для визуализации тестов

Использую в больших проектах для наглядного представления результатов тестирования.

Практики использования

В своей работе я придерживаюсь следующих принципов:

  1. Стандартные инструменты в приоритете - минимизирую зависимости
  2. Соответствие инструмента задаче - для юнит-тестов testing, для интеграционных - специализированные фреймворки
  3. Консистентность - в рамках одного проекта стараюсь использовать единый подход
  4. Производительность тестов - выбираю инструменты, не замедляющие выполнение CI/CD

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