Что такое модульный тест
Модульный тест — это небольшая программа, которая проверяет один фрагмент вашего кода, обычно одну функцию. Тесты запускают после каждого изменения: если изменение что-то сломало, тест сообщит об этом сразу, раньше, чем это заметят пользователи.
В Go есть всё необходимое: пакет testing и команда go test входят в состав инструментов языка. Не нужно ставить дополнительных библиотек и что-то настраивать — достаточно файла рядом с вашим кодом.
Тесты также делают изменения безопасными: с хорошими тестами вы можете переписать функцию и за считаные секунды убедиться, что она ведёт себя по-прежнему.
Файлы тестов и тестовые функции
Тест становится тестом благодаря двум правилам именования:
1. Имя файла заканчивается на _test.go — для calc.go вы пишете calc_test.go. Такие файлы компилируются только командой go test и никогда не попадают в обычную сборку.
2. Функция называется TestXxx — она начинается с Test, дальше идёт заглавная буква, и принимает один аргумент: t *testing.T.
Внутри теста вы вызываете функцию, сравниваете то, что получили (got), с тем, что ожидали (want), и через t сообщаете о падении теста, если значения различаются. Если о падении не сообщено, тест считается пройденным.
Первый успешный тест
TestAdd вызывает Add(2, 3) и сравнивает результат с 5. Значения совпадают, поэтому ничего не сообщается и тест проходит: go test выводит PASS.
Вывод: программа на Go и захваченный вывод
package calc
import "testing"
func Add(a, b int) int {
return a + b
}
func TestAdd(t *testing.T) {
got := Add(2, 3)
want := 5
if got != want {
t.Errorf("Add(2, 3) = %d; ожидалось %d", got, want)
}
}
Падающий тест
В этой версии Add есть ошибка — она умножает. Тест её обнаруживает: t.Errorf выводит сообщение со значениями got и want, и запуск завершается словом FAIL.
Вывод: программа на Go и захваченный вывод
package calc
import "testing"
// В Add есть ошибка: она умножает вместо сложения.
func Add(a, b int) int {
return a * b
}
func TestAdd(t *testing.T) {
got := Add(2, 3)
want := 5
if got != want {
t.Errorf("Add(2, 3) = %d; ожидалось %d", got, want)
}
}
Запуск тестов
go test запускает все тесты в текущей папке. При успехе команда немногословна — одна строка ok — и говорит только тогда, когда что-то падает.
go test -v (подробный режим) перечисляет каждый тест по имени строками === RUN и --- PASS. Используйте этот режим, чтобы увидеть, что именно было запущено. Для всего проекта go test ./... запускает тесты во всех папках.
Два теста, подробный вывод
В файле две тестовые функции — по одной на каждую проверяемую функцию. С флагом -v каждая из них появляется в выводе отдельно, и видно, что обе запустились и обе прошли.
Вывод: программа на Go и захваченный вывод
package calc
import "testing"
func Double(n int) int {
return n * 2
}
func Half(n int) int {
return n / 2
}
func TestDouble(t *testing.T) {
if Double(4) != 8 {
t.Error("Double(4) должно быть 8")
}
}
func TestHalf(t *testing.T) {
if Half(8) != 4 {
t.Error("Half(8) должно быть 4")
}
}