Тип testing.M

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

Синтаксис

gotype M struct {
  // содержит скрытые поля
}

func (m *M) Run() int

Чтобы использовать testing.M, необходимо определить функцию TestMain в пакете с тестами. В этой функции создается экземпляр testing.M через вызов testing.Main или он передается автоматически при запуске тестов. Метод Run запускает все тесты и возвращает код завершения, который затем передается в os.Exit.

Пример с настройкой подключения к базе данных

Давайте рассмотрим пример использования testing.M для инициализации и очистки ресурсов перед выполнением тестов:

gopackage main

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

func TestMain(m *testing.M) {
  // Инициализация ресурсов
  fmt.Println("Подготовка к тестированию...")
  setup()

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

  // Очистка ресурсов
  cleanup()
  fmt.Println("Тестирование завершено")

  // Выход с кодом завершения
  os.Exit(code)
}

func setup() {
  // Настройка подключения к базе данных
  fmt.Println("Соединение с БД установлено")
}

func cleanup() {
  // Закрытие подключения
  fmt.Println("Соединение с БД закрыто")
}

func TestExample(t *testing.T) {
  // Пример теста
  if 2+2 != 4 {
    t.Error("Ошибка в вычислениях")
  }
}

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

go"Подготовка к тестированию..."
"Соединение с БД установлено"
"Соединение с БД закрыто"
"Тестирование завершено"

Пример с обработкой флагов командной строки

testing.M позволяет обрабатывать пользовательские флаги командной строки перед запуском тестов:

gopackage main

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

var (
  verbose = flag.Bool("v", false, "Подробный вывод")
  host  = flag.String("host", "localhost", "Адрес сервера")
)

func TestMain(m *testing.M) {
  // Парсинг пользовательских флагов
  flag.Parse()

  fmt.Printf("Хост: %s, Подробный вывод: %t\n",
    *host, *verbose)

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

  os.Exit(code)
}

func TestServer(t *testing.T) {
  // Проверка подключения к серверу
  if *host == "" {
    t.Error("Адрес хоста не указан")
  }
}

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

go"Хост: example.com, Подробный вывод: true"

Пример с отложенной очисткой ресурсов

Используем defer для обеспечения гарантированной очистки ресурсов при любом исходе тестов:

gopackage main

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

func TestMain(m *testing.M) {
  // Создание временной директории
  tmpDir := "/tmp/testdata"
  fmt.Printf("Создана директория: %s\n", tmpDir)

  // Отложенная очистка
  defer func() {
    fmt.Printf("Удалена директория: %s\n", tmpDir)
  }()

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

  os.Exit(code)
}

func TestTempFile(t *testing.T) {
  // Проверка работы с временной директорией
  if 1+1 != 2 {
    t.Error("Ошибка в вычислениях")
  }
}

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

go"Создана директория: /tmp/testdata"
"Удалена директория: /tmp/testdata"

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

  • тип testing.T,
    который используется для управления тестами
  • тип testing.B,
    который используется для бенчмарков
  • функцию TestMain,
    которая является точкой входа для управления тестами
  • функцию testing.Short,
    которая проверяет флаг короткого режима тестирования