Добавление теста

Теперь, когда код находится в стабильном состоянии (хорошая работа, кстати), добавьте тест. Тестирование кода во время разработки может выявить ошибки, которые могут появиться при внесении изменений. В этой теме добавляется тест для функции Hello.

Встроенные возможности Go для модульного тестирования упрощают тестирование во время разработки. В частности, используя соглашения об именовании, пакет testing и команда go test, можно быстро написать и выполнить тесты.

  1. В каталоге greetings создайте файл с именем greetings_test.go.

    Завершение имени файла на _test.go указывает команде go test, что этот файл содержит функции тестов.

  2. В файле 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 для вывода сообщения в консоль.
  3. В командной строке в каталоге 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
    
  4. Испортируйте функцию 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
    }
    
  5. В командной строке в каталоге 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
    

В следующей (и последней) теме вы увидите, как компилировать и устанавливать ваш код для локального запуска.

GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang