Тестирование и бенчмаркирование

GolangGolangBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

Этот лабораторный практикум旨在演示单元测试和基准测试在编写规范的Go程序中的重要性。testing包提供了编写单元测试所需的工具,而go test命令则用于运行测试。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL go(("Golang")) -.-> go/TestingandProfilingGroup(["Testing and Profiling"]) go/TestingandProfilingGroup -.-> go/testing_and_benchmarking("Testing and Benchmarking") subgraph Lab Skills go/testing_and_benchmarking -.-> lab-15518{{"Тестирование и бенчмаркирование"}} end

Тестирование и бенчмаркирование

Проблема, которую необходимо решить в этом лабораторном практикуме, — это протестировать и провести бенчмарк простой реализации функции нахождения минимального целого числа под названием 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, чтобы измерить ее производительность.