Добавление теста
Теперь, когда код находится в стабильном состоянии (хорошая работа, кстати),
добавьте тест. Тестирование кода во время разработки может выявить ошибки,
которые могут появиться при внесении изменений. В этой теме добавляется тест
для функции Hello.
Встроенные возможности Go для модульного тестирования упрощают тестирование
во время разработки. В частности, используя соглашения об именовании,
пакет testing и команда go test, можно быстро
написать и выполнить тесты.
-
В каталоге greetings создайте файл с именем greetings_test.go.
Завершение имени файла на _test.go указывает команде
go test, что этот файл содержит функции тестов. -
В файле greetings_test.go вставьте следующий код и сохраните файл.
package greetings import ( "testing" "regexp" ) // TestHelloName calls greetings.Hello with a name, checking // for a valid return value. func TestHelloName(t *testing.T) { name := "Gladys" want := regexp.MustCompile(`\b`+name+`\b`) msg, err := Hello("Gladys") if !want.MatchString(msg) || err != nil { t.Errorf(`Hello("Gladys") = %q, %v, want match for %#q, nil`, msg, err, want) } } // TestHelloEmpty calls greetings.Hello with an empty string, // checking for an error. func TestHelloEmpty(t *testing.T) { msg, err := Hello("") if msg != "" || err == nil { t.Errorf(`Hello("") = %q, %v, want "", error`, msg, err) } }В этом коде реализуются:
- Функции тестов в том же пакете, что и тестируемый код.
-
Создаются две функции теста для проверки функции
greetings.Hello. Имена функций тестов имеют видTestName, где Name описывает конкретный тест. Также функции тестов принимают указатель на типtesting.Tиз пакетаtestingв качестве параметра. Этот параметр используется для отчетов и логирования из теста. -
Реализуются два теста:
-
TestHelloNameвызывает функциюHello, передавая значениеname, при котором функция должна вернуть корректное приветствие. Если вызов возвращает ошибку или неожиданное сообщение (не содержащее имя, переданное в функцию), используется методErrorfпараметраtдля вывода сообщения в консоль. -
TestHelloEmptyвызывает функциюHelloс пустой строкой. Этот тест предназначен для проверки обработки ошибок. Если вызов возвращает непустую строку или отсутствует ошибка, используется методErrorfпараметраtдля вывода сообщения в консоль.
-
-
В командной строке в каталоге greetings выполните команду
go testдля запуска теста.Команда
go testвыполняет функции тестов (имена которых начинаются сTest) в файлах тестов (имена которых заканчиваются на _test.go). Можно добавить флаг-vдля получения подробного вывода, который перечисляет все тесты и их результаты.Тесты должны пройти успешно.
$ go test PASS ok example.com/greetings 0.364s $ go test -v === RUN TestHelloName --- PASS: TestHelloName (0.00s) === RUN TestHelloEmpty --- PASS: TestHelloEmpty (0.00s) PASS ok example.com/greetings 0.372s
-
Испортируйте функцию
greetings.Hello, чтобы увидеть неудачный тест.Функция теста
TestHelloNameпроверяет возвращаемое значение для имени, переданного в качестве параметра функцииHello. Чтобы увидеть результат неудачного теста, измените функциюgreetings.Helloтак, чтобы она больше не включала имя.В файле greetings/greetings.go вставьте следующий код вместо функции
Hello. Обратите внимание, что выделенные строки изменяют возвращаемое значение функции, как если бы аргументnameбыл случайно удалён.// Hello returns a greeting for the named person. func Hello(name string) (string, error) { // If no name was given, return an error with a message. if name == "" { return name, errors.New("empty name") } // Create a message using a random format. <ins>// message := fmt.Sprintf(randomFormat(), name) message := fmt.Sprint(randomFormat())</ins> return message, nil } -
В командной строке в каталоге greetings выполните
go testдля запуска теста.На этот раз выполните
go testбез флага-v. Вывод будет содержать результаты только неудачных тестов, что может быть полезно при большом количестве тестов. ТестTestHelloNameдолжен завершиться неудачей —TestHelloEmptyпо-прежнему пройдет.$ go test --- FAIL: TestHelloName (0.00s) greetings_test.go:15: Hello("Gladys") = "Hail, %v! Well met!", <nil>, want match for `\bGladys\b`, nil FAIL exit status 1 FAIL example.com/greetings 0.182s
В следующей (и последней) теме вы увидите, как компилировать и устанавливать ваш код для локального запуска.