Введение
Этот лабораторный практикум旨在演示单元测试和基准测试在编写规范的Go程序中的重要性。testing
包提供了编写单元测试所需的工具,而go test
命令则用于运行测试。
This tutorial is from open-source community. Access the source code
💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал
Этот лабораторный практикум旨在演示单元测试和基准测试在编写规范的Go程序中的重要性。testing
包提供了编写单元测试所需的工具,而go test
命令则用于运行测试。
Проблема, которую необходимо решить в этом лабораторном практикуме, — это протестировать и провести бенчмарк простой реализации функции нахождения минимального целого числа под названием IntMin
.
testing
.IntMin
должна принимать два целочисленных параметра и возвращать целое число.TestIntMinBasic
должна тестировать функцию IntMin
для базовых значений входных данных.TestIntMinTableDriven
должна тестировать функцию IntMin
в табличном стиле.BenchmarkIntMin
должна провести бенчмарк функции IntMin
.## Запустить все тесты в текущем проекте в подробном режиме.
## Запустить все бенчмарки в текущем проекте. Все тесты
## выполняются перед бенчмарками. Флаг `bench` фильтрует
## имена функций бенчмарков с помощью регулярного выражения.
Ниже представлен полный код:
// Юнит-тестирование является важной частью написания
// принципиальных Go-программ. Пакет `testing`
// предоставляет инструменты, которые нам нужны для написания
// юнит-тестов, а команда `go test` запускает тесты.
// В целях демонстрации этот код находится в пакете
// `main`, но это может быть любой пакет. Код для тестирования
// обычно находится в том же пакете, что и код, который он тестирует.
package main
import (
"fmt"
"testing"
)
// Мы будем тестировать эту простую реализацию
// нахождения минимального целого числа. Обычно код,
// который мы тестируем, находится в исходном файле,
// названном, например, `intutils.go`, а тестовый файл
// для него будет называться `intutils_test.go`.
func IntMin(a, b int) int {
if a < b {
return a
}
return b
}
// Тест создается путем написания функции с именем,
// начинающимся с `Test`.
func TestIntMinBasic(t *testing.T) {
ans := IntMin(2, -2)
if ans!= -2 {
// `t.Error*` сообщит о неудаче теста, но продолжит
// выполнение теста. `t.Fatal*` сообщит о неудаче теста
// и немедленно остановит тест.
t.Errorf("IntMin(2, -2) = %d; want -2", ans)
}
}
// Пишение тестов может быть повторяющимся процессом, поэтому
// обычно используется *табличный стиль*, где входные данные
// теста и ожидаемые выходные данные перечислены в таблице,
// и единственный цикл проходит по ним и выполняет логику теста.
func TestIntMinTableDriven(t *testing.T) {
var tests = []struct {
a, b int
want int
}{
{0, 1, 0},
{1, 0, 0},
{2, -2, -2},
{0, -1, -1},
{-1, 0, -1},
}
for _, tt := range tests {
// t.Run позволяет запускать "подтесты", по одному для
// каждой записи таблицы. Они отображаются отдельно
// при выполнении `go test -v`.
testname := fmt.Sprintf("%d,%d", tt.a, tt.b)
t.Run(testname, func(t *testing.T) {
ans := IntMin(tt.a, tt.b)
if ans!= tt.want {
t.Errorf("got %d, want %d", ans, tt.want)
}
})
}
}
// Бенчмарк-тесты обычно находятся в файлах `_test.go` и
// именуются с префиксом `Benchmark`. Выполняющийся тестер
// несколько раз запускает каждую функцию бенчмарка,
// увеличивая `b.N` на каждой итерации, пока не получит
// точную меру.
func BenchmarkIntMin(b *testing.B) {
// Обычно бенчмарк запускает функцию, которую мы
// бенчмаркируем, в цикле `b.N` раз.
for i := 0; i < b.N; i++ {
IntMin(1, 2)
}
}
Этот лабораторный практикум показал, как писать юнит-тесты и функции бенчмарка с использованием пакета testing
в Go. Функция TestIntMinBasic
тестировала функцию IntMin
для базовых значений входных данных, в то время как функция TestIntMinTableDriven
использовала табличный стиль для тестирования функции IntMin
. Функция BenchmarkIntMin
провела бенчмарк функции IntMin
, чтобы измерить ее производительность.