«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Основное модульное тестирование API Go: создавайте код с уверенностью

Основное модульное тестирование API Go: создавайте код с уверенностью

Опубликовано 8 ноября 2024 г.
Просматривать:159

Essential Unit Testing for Go APIs – Build Code with Confidence

Разрабатывая этот API, мы рассмотрели аутентификацию, ведение журналов, докеризацию и многое другое. Но есть одна вещь, которую мы еще не обсудили — это тестирование! Если вы хотите, чтобы ваш API был готов к использованию, крайне важно добавить надежные модульные тесты. В этом посте мы рассмотрим основы модульного тестирования в Go, чтобы вы могли раньше выявлять ошибки и создавать высококачественный код.

Почему модульное тестирование?

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

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

Готовы начать? Давайте погрузимся! ?


Шаг 1. Настройка базового теста

Среда тестирования Go проста и интегрирована прямо в язык. Вы можете создать тестовый файл, назвав его суффиксом _test.go. Начнем с тестирования простой функции в main.go:

// main.go
package main

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

Теперь создайте файл с именем main_test.go и добавьте следующий код:

// main_test.go
package main

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)
    }
}

Как это работает:

  1. Тестовая функция: любая тестовая функция в Go должна начинаться с Test и принимать параметр *testing.T.
  2. Утверждение: мы проверяем, соответствует ли результат нашим ожиданиям. Если это не так, мы регистрируем ошибку, используя t.Errorf.

Чтобы запустить тест, просто используйте:

go test

Если все работает, вы увидите сообщение «ОК». ?


Шаг 2. Тестирование обработчиков HTTP

Теперь давайте напишем тест для одного из наших обработчиков HTTP. Мы воспользуемся пакетом Go httptest для создания имитации устройства записи HTTP-запросов и ответов.

// main_test.go
package main

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestGetBooksHandler(t *testing.T) {
    req, err := http.NewRequest("GET", "/books", nil)
    if err != nil {
        t.Fatal(err)
    }

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(getBooks)

    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)
    }
}

Объяснение:

  1. httptest.NewRequest: создает новый HTTP-запрос. Это имитирует запрос к вашей конечной точке /books.
  2. httptest.NewRecorder: имитирует HTTP-ответ. Мы проверим это позже, чтобы увидеть, соответствует ли это нашим ожиданиям.
  3. ServeHTTP: вызывает наш обработчик getBooks с фиктивным запросом и устройством записи.

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


Шаг 3. Запуск тестов с покрытием

Go имеет встроенный способ проверки покрытия тестами. Чтобы узнать, какой процент вашего кода покрыт тестами, вы можете запустить:

go test -cover

Для более подробного охвата создайте отчет в формате HTML:

go test -coverprofile=coverage.out
go tool cover -html=coverage.out

Откройте сгенерированный HTML-файл, чтобы увидеть, какие части вашего кода охвачены. Это отличный способ узнать, где вам может потребоваться дополнительное тестирование.


Шаг 4: Имитация внешних зависимостей

При тестировании функций, которые зависят от внешних сервисов (например, вызовов базы данных или внешнего API), вы можете использовать интерфейсы для имитации этих зависимостей.

// Define a simple interface for our database
type Database interface {
    GetBooks() ([]Book, error)
}

// Implement a mock database
type MockDatabase struct{}

func (m MockDatabase) GetBooks() ([]Book, error) {
    return []Book{{Title: "Mock Book"}}, nil
}

Используя интерфейсы, вы можете заменить фактическую зависимость макетом во время тестирования. Благодаря этому ваши тесты будут быстрыми, изолированными и повторяемыми.


Что дальше?

Теперь, когда вы начали создавать модульные тесты, попробуйте добавить тесты в другие части вашего API! ? На следующей неделе мы рассмотрим интеграцию конвейера CI/CD, чтобы эти тесты могли запускаться автоматически при каждом изменении. Следите за обновлениями!


Вопрос для вас: Какой ваш любимый инструмент или метод тестирования? Оставьте комментарий ниже — мне бы хотелось услышать, как другие разработчики Go подходят к тестированию!


Благодаря этим основам вы уже на пути к написанию надежных тестов, которые сделают ваш Go API более надежным. Чтобы получить дополнительные советы по тестированию и передовые методы, следите за обновлениями в следующих публикациях. Приятного тестирования! ?

Заявление о выпуске Эта статья воспроизведена по адресу: https://dev.to/neelp03/essential-unit-testing-for-go-apis-build-code-with-confidence-ne3?1. Если есть какие-либо нарушения, свяжитесь с Study_golang@163. .com, чтобы удалить его
Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3