Тестирование и отладка

10. Тестирование и отладка #

Тестирование и отладка — важные аспекты разработки на Go. Язык предоставляет встроенные инструменты для написания тестов, профилирования и трассировки, что помогает повысить качество кода и производительность.


10.1 Основы тестирования в Go #

В Go тесты пишутся в файлах с суффиксом _test.go, а тестирующий код находится в функциях с сигнатурой func TestXxx(t *testing.T).

Пример простого теста:

package main

import "testing"

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

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

Запуск тестов осуществляется командой:

go test ./...

10.2 Написание unit-тестов #

Unit-тесты проверяют работу отдельных функций или модулей. Использование таблиц тестирования помогает структурировать и упрощать тесты.

Пример с таблицей тестов:

func Multiply(a, b int) int {
    return a * b
}

func TestMultiply(t *testing.T) {
    tests := []struct {
        a, b, expected int
    }{
        {2, 3, 6},
        {0, 5, 0},
        {-1, 3, -3},
    }

    for _, test := range tests {
        result := Multiply(test.a, test.b)
        if result != test.expected {
            t.Errorf("Multiply(%d, %d) = %d; want %d", test.a, test.b, result, test.expected)
        }
    }
}

10.3 Использование testing и testify #

Пакет testing #

Встроенный пакет testing используется для написания тестов, примеров и бенчмарков.

Пример бенчмарка:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

Библиотека testify #

testify — это популярная сторонняя библиотека, упрощающая тестирование.

Установка:

go get github.com/stretchr/testify

Пример использования:

package main

import (
    "testing"

    "github.com/stretchr/testify/assert"
)

func TestAddWithTestify(t *testing.T) {
    assert.Equal(t, 5, Add(2, 3))
    assert.NotEqual(t, 6, Add(2, 3))
}

10.4 Профилирование и оптимизация #

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

Включение профилирования CPU:

package main

import (
    "os"
    "runtime/pprof"
)

func main() {
    f, _ := os.Create("cpu.prof")
    pprof.StartCPUProfile(f)
    defer pprof.StopCPUProfile()

    // Ваша программа
    for i := 0; i < 1e6; i++ {
        _ = i * i
    }
}

Анализ профиля:

go tool pprof cpu.prof

10.5 Введение в pprof и трассировку #

Пакет net/http/pprof #

Для веб-приложений можно включить профилирование через net/http/pprof.

Пример:

package main

import (
    _ "net/http/pprof"
    "net/http"
)

func main() {
    http.ListenAndServe(":8080", nil)
}

Запустите приложение и откройте в браузере:

http://localhost:8080/debug/pprof/

Трассировка (Tracing) #

Трассировка помогает понять, как программа взаимодействует с системой.

Создание трассировки:

package main

import (
    "os"
    "runtime/trace"
)

func main() {
    f, _ := os.Create("trace.out")
    defer f.Close()

    trace.Start(f)
    defer trace.Stop()

    // Ваш код
    for i := 0; i < 1e6; i++ {
        _ = i * i
    }
}

Анализ трассировки:

go tool trace trace.out

Итог #

Go предоставляет мощные инструменты для тестирования и отладки, от базового testing до инструментов профилирования и трассировки. Эти возможности помогают писать надежный и производительный код.