← Все этапы
04 · ПАКЕТЫ И НАДЁЖНОСТЬУрок 21 из 3322 минуты

Проверки с go test

Выносим проверки в отдельный файл и одним набором кейсов проверяем разные входные данные.

Проверка как исполняемая спецификация

Обычная программа может работать сегодня и сломаться после будущего изменения. Тесты фиксируют ожидаемое поведение функции и запускаются инструментом Go. Тестовый файл заканчивается на _test.go; функция-тест принимает *testing.T и называется с префиксом Test.

Тесты могут находиться в том же пакете, чтобы проверять внутреннее поведение, или в отдельном пакете с суффиксом _test, чтобы проверять только публичный API. Для маленькой функции можно перечислить несколько входов в таблице и пройти её циклом. t.Errorf сообщает об ошибке и продолжает текущий тест, а t.Fatalf прекращает его, когда продолжать бессмысленно.

Файл main.go

Первая программа запускается сама; тест ниже хранится рядом с ней в файле main_test.go.

package main

import "fmt"

func shippingLabel(city string, boxes int) string {
	return fmt.Sprintf("%s, коробок: %d", city, boxes)
}

func main() {
	fmt.Println(shippingLabel("Пермь", 2))
}

Файл main_test.go

Каждая строка таблицы задаёт один вход и ожидаемый результат. Сравнение строк проверяет весь ответ, включая пробелы и знаки препинания.

package main

import "testing"

// TestShippingLabel проверяет подпись отправления для разных входных данных.
func TestShippingLabel(t *testing.T) {
	tests := []struct {
		name  string
		city  string
		boxes int
		want  string
	}{
		{name: "one box", city: "Пермь", boxes: 1, want: "Пермь, коробок: 1"},
		{name: "several boxes", city: "Тула", boxes: 4, want: "Тула, коробок: 4"},
		{name: "empty city", city: "", boxes: 0, want: ", коробок: 0"},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			got := shippingLabel(test.city, test.boxes)
			if got != test.want {
				t.Errorf("shippingLabel(%q, %d) = %q, want %q", test.city, test.boxes, got, test.want)
			}
		})
	}
}

Положи оба файла в папку Go-модуля. Команда go test ./... соберёт пакет и выполнит тестовые функции во всех пакетах текущего модуля; для одной папки достаточно go test. Если проверка падает, сообщение показывает полученное и ожидаемое значения. Тесты должны проверять результат и граничные случаи, а не повторять реализацию функции.

Практика

Попробуйте сами

Напиши в main.go функцию fullName(first, last string) string, которая склеивает имя и фамилию через один пробел. В main_test.go создай табличный тест как минимум для обычных имён и пустой фамилии. Добавь подпись кейса и диагностическое сообщение со входом, фактом и ожиданием.

Проверка результата

Как понять, что получилось

Команда go test ./... завершается успешно. Проверяются результаты «Анна Волкова» для двух непустых частей и «Анна » для пустой фамилии. Если временно изменить ожидаемый результат одного кейса, тест должен завершиться ошибкой и назвать этот кейс.

Проверки с go test | Go | WebSchool · Go