Функция TestMain

Функция TestMain предоставляет возможность управлять выполнением всех тестов в пакете. Она принимает один параметр - указатель на тип testing.M, который предоставляет методы для выполнения тестов и получения информации о них. Эта функция выполняется один раз перед запуском всех тестов пакета, что позволяет выполнить глобальную инициализацию, настроить внешние зависимости или выполнить очистку после тестирования.

Синтаксис

gofunc TestMain(m *testing.M) {
  // Настройка ресурсов
  code := m.Run()
  // Очистка ресурсов
  os.Exit(code)
}

Функция TestMain должна быть объявлена в пакете с тестами и принимать единственный параметр типа *testing.M. Метод Run вызывает все тесты в пакете и возвращает код завершения, который затем передается в os.Exit. Для выполнения инициализации и очистки ресурсов используются стандартные конструкции Go.

Пример с инициализацией и очисткой

Давайте создадим тестовый пакет с функцией TestMain, которая открывает файл для записи логов, выполняет тесты и затем закрывает файл:

gopackage main

import (
  "fmt"
  "os"
  "testing"
)

func TestAddition(t *testing.T) {
  res := 2 + 2
  if res != 4 {
    t.Errorf("expected 4, got %d", res)
  }
  fmt.Println("TestAddition passed")
}

func TestMain(m *testing.M) {
  // Открываем файл для логов
  file, err := os.Create("test.log")
  if err != nil {
    fmt.Printf("Failed to create log file: %v\n", err)
    os.Exit(1)
  }
  defer file.Close()

  // Перенаправляем вывод в файл
  oldStdout := os.Stdout
  os.Stdout = file

  // Запускаем тесты
  code := m.Run()

  // Восстанавливаем stdout
  os.Stdout = oldStdout

  fmt.Printf("Tests completed with code: %d\n", code)
  os.Exit(code)
}

Результат выполнения кода:

go"Tests completed with code: 0"

Пример с настройкой окружения

Используем TestMain для установки переменных окружения и проверки их влияния на тесты:

gopackage main

import (
  "os"
  "testing"
)

func TestDatabaseURL(t *testing.T) {
  url := os.Getenv("DB_URL")
  if url == "" {
    t.Error("DB_URL environment variable is empty")
  }
}

func TestMain(m *testing.M) {
  // Устанавливаем переменную окружения
  os.Setenv("DB_URL", "postgres://localhost:5432/testdb")

  // Запускаем тесты
  code := m.Run()

  // Очищаем переменную окружения
  os.Unsetenv("DB_URL")

  os.Exit(code)
}

Результат выполнения кода:

go"ok"

Пример с несколькими тестами

Продемонстрируем, как TestMain обрабатывает выполнение нескольких тестов:

gopackage main

import (
  "fmt"
  "testing"
)

func TestOne(t *testing.T) {
  fmt.Println("Running TestOne")
}

func TestTwo(t *testing.T) {
  fmt.Println("Running TestTwo")
}

func TestMain(m *testing.M) {
  fmt.Println("Starting test suite")
  code := m.Run()
  fmt.Println("All tests completed")
  os.Exit(code)
}

Результат выполнения кода:

go"Starting test suite"
"Running TestOne"
"Running TestTwo"
"All tests completed"

Смотрите также

  • функцию testing.M,
    которая представляет собой набор тестов для выполнения
  • функцию testmain,
    которая описывает внутреннюю структуру и процесс выполнения тестов
  • функцию testing.T.Run,
    которая запускает подтесты внутри основного теста
  • функцию testing.T.Cleanup,
    которая регистрирует функции для очистки после завершения теста