Тест Go содержит дорогой сценарий, который должен пропускаться в режиме short без маскировки под успешный п...

Тест Go содержит дорогой сценарий, который должен пропускаться в режиме short без маскировки под успешный проход. Какой механизм testing применить?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Проверьте флаг через testing.Short(), а затем завершите текущий тест вызовом t.Skip. Такой тест будет явно отмечен как пропущенный, а не как успешно выполненный.

func TestImport(t *testing.T) { if testing.Short() { t.Skip("пропускаем дорогой сценарий") } result := runLongImport() if result == nil { t.Fatal("импорт не выполнен") } }

Исторический контекст

В больших наборах тестов нужны быстрые проверки для частой локальной обратной связи и более дорогие сценарии для полного прогона. Поэтому режим short отделяет эти категории без необходимости удалять тесты или поддерживать отдельный набор файлов.

Постановка проблемы

Само включение режима short не отключает тест автоматически. Если тест не проверяет состояние флага, дорогой сценарий всё равно запустится, замедлив разработку и CI.

Простой return тоже не подходит: тест завершится без ошибки и будет выглядеть как успешно проверенный. Это скрывает тот факт, что проверка фактически не выполнялась.

Подробное решение

testing.Short() возвращает, включён ли режим короткого прогона, обычно активируемый флагом -short. Он только сообщает состояние режима и не прекращает выполнение теста.

Для пропуска нужно вызвать t.Skip, передав причину. Вызов помечает тест как skipped и прекращает выполнение его тела; это отличается от t.Error, t.Fatal и обычного возврата. Зарегистрированные через t.Cleanup функции сохраняют обычную семантику очистки.

Проверку следует выполнять до дорогой подготовки: создания больших данных, запуска внешних сервисов или выполнения длительной операции. При этом короткий режим не должен использоваться для сокрытия нестабильных или обязательных проверок: тест пропускают только если его стоимость действительно оправдывает разделение режимов.

Альтернатива в виде build tags полностью исключает файл из компиляции при выбранной конфигурации. Это полезно для платформенных или окруженческих различий, но хуже подходит для динамического выбора между быстрым и полным прогоном: результат не будет представлен как пропущенный тест.

Ситуация из практики

В репозитории был тест импорта большого архива. Разработчик добавил ранний return, чтобы локальный запуск был быстрым, но отчёт показывал успешный тест даже тогда, когда импорт вообще не проверялся.

Рассматривались три варианта: удалить тест из обычного набора, использовать build tag или применить testing.Short вместе с t.Skip. Удаление ухудшало обнаружение регрессий, build tag требовал отдельной конфигурации и скрывал тест из отчёта, поэтому выбран третий вариант.

В обычном прогоне тест выполняется, а в коротком явно отображается как skipped с причиной. Это сохраняет прозрачность отчёта и позволяет CI запускать полный набор отдельно.

Что кандидаты часто упускают

  1. Достаточно ли вызвать testing.Short(), чтобы тест автоматически не выполнялся?

Нет. testing.Short() только возвращает булево значение. Тест должен сам принять решение, например вызвать t.Skip; без этого дорогая часть продолжит выполняться.

  1. Почему ранний return хуже, чем t.Skip?

return завершает функцию без ошибки, поэтому тест считается успешным. t.Skip сообщает тестовому фреймворку, что сценарий намеренно не выполнялся, и причина видна в результате прогона.

  1. Когда вместо short-режима следует использовать build tags?

Build tags уместны, когда тест зависит от платформы, инструмента или окружения и не должен даже компилироваться в неподходящей конфигурации. Для временного пропуска дорогого, но валидного теста лучше использовать testing.Short и t.Skip, чтобы тест оставался частью отчёта и полного прогона.