Два способа сообщить о падении
Тест может сообщить о проблеме двумя способами, и разница в том, что происходит дальше:
t.Errorf помечает тест как упавший и продолжает работу. Оставшаяся часть теста всё равно выполняется, поэтому за один запуск можно увидеть сразу несколько проблем.
t.Fatalf помечает тест как упавший и немедленно останавливает его. Используйте его тогда, когда продолжать бессмысленно — следующие строки либо аварийно завершатся, либо выдадут лишний шум.
У обоих есть простые близнецы без форматирования: t.Error(...) и t.Fatal(...) просто печатают свои аргументы.
t.Errorf: сообщить и продолжить
Когда тест проверяет несколько случаев подряд, t.Errorf — подходящий инструмент: о сломанном случае сообщается, а следующие случаи всё равно проверяются.
Так один запуск go test показывает вам весь объём поломок — а не только первый сломанный случай.
Увидеть все сломанные случаи сразу
Эта функция Add игнорирует b, поэтому все три проверки падают. Так как они используют t.Errorf, все три сообщения появляются в одном запуске — с t.Fatalf вы увидели бы только первое.
Вывод: программа на Go и захваченный вывод
package calc
import "testing"
// В Add есть ошибка: она игнорирует b.
func Add(a, b int) int {
return a
}
func TestAdd(t *testing.T) {
if got := Add(2, 2); got != 4 {
t.Errorf("Add(2, 2) = %d; ожидалось 4", got)
}
if got := Add(2, 3); got != 5 {
t.Errorf("Add(2, 3) = %d; ожидалось 5", got)
}
if got := Add(10, 1); got != 11 {
t.Errorf("Add(10, 1) = %d; ожидалось 11", got)
}
}
t.Fatalf: остановиться сразу
Иногда неудачная проверка означает, что остальная часть теста работать не может. Типичный случай: тест сначала готовит значение, а затем изучает его. Если подготовка уже пошла не так, изучать его бесполезно или даже опасно — программа может аварийно завершиться.
t.Fatalf останавливает тест прямо на этом месте. Проверки после него не выполняются никогда — и в этом весь смысл.
Остановиться до бесполезных проверок
В функции Split есть ошибка (она разбивает строку по неправильному символу), поэтому возвращается 1 часть вместо 3. t.Fatalf сообщает об этом и останавливает тест — до проверки первой части ниже дело не доходит.
Вывод: программа на Go и захваченный вывод
package words
import (
"strings"
"testing"
)
// В Split есть ошибка: она разбивает по ";" вместо ",".
func Split(s string) []string {
return strings.Split(s, ";")
}
func TestSplit(t *testing.T) {
parts := Split("one,two,three")
if len(parts) != 3 {
t.Fatalf("получено %d parts, ожидалось 3 — их нельзя проверить", len(parts))
}
// Никогда не выполняется, пока есть эта ошибка.
if parts[0] != "one" {
t.Errorf("first part = %q; ожидалось %q", parts[0], "one")
}
}
Error и Fatal без форматирования
Когда вам не нужны подстановки %d или %q, используйте простые формы: t.Error("сообщение") и t.Fatal("сообщение"). Они ведут себя точно так же, как их близнецы с f, — сообщить и продолжить или сообщить и остановиться.
Простые сообщения
Две простые логические проверки с обычными сообщениями t.Error. Здесь обе проходят, поэтому сообщения молчат, а запуск печатает PASS.
Вывод: программа на Go и захваченный вывод
package calc
import "testing"
func IsEven(n int) bool {
return n%2 == 0
}
func TestIsEven(t *testing.T) {
if !IsEven(4) {
t.Error("4 должно быть чётным")
}
if IsEven(3) {
t.Error("3 не должно быть чётным")
}
}