Как запустить конкретный тест или все тесты из определённого файла в Go?
Правильный запуск тестов из конкретного файла
Проблема в том, что команда go test handlers_test.go пытается скомпилировать только указанный файл, но не подключает другие файлы пакета (например, handlers.go). В Go тесты работают на уровне пакета, поэтому нужно указывать либо весь пакет, либо все необходимые файлы.
Основное решение: используйте шаблон go test -run для фильтрации тестов по имени, а файлы указывайте все, которые нужны для компиляции:
go test -run "TestHandleRequest" handlers_test.go handlers.go
Но такой подход неудобен, если файлов много. Лучший способ — запускать тесты для всего пакета, но с фильтром по имени теста:
go test -v -run "TestHandleRequest" ./...
Эта команда запустит только тесты, имя которых содержит TestHandleRequest, во всех пакетах проекта. Флаг -v (verbose) покажет подробный вывод.
Запуск всех тестов из конкретного файла
Если нужно запустить все тесты из handlers_test.go, используйте регулярное выражение, которое соответствует всем тестам в этом файле. Обычно тесты именуются с префиксом, например TestHandle:
go test -v -run "TestHandle" ./...
Или можно запустить тесты только для конкретного пакета (если файлы находятся в отдельной папке):
go test -v ./handlers/
Запуск одного конкретного теста
Для запуска одного теста используйте флаг -run с точным именем:
go test -v -run "^TestHandleRequest$" ./...
Символы ^ и $ — это якоря регулярного выражения, которые гарантируют точное совпадение имени.
Работа с зависимостями и тестовыми файлами
Если тесты используют вспомогательные функции из других файлов того же пакета (например, utils.go), их тоже нужно указывать в команде, если вы не используете ./...:
go test -v -run "TestHandle" handlers_test.go handlers.go utils.go
Но повторюсь: самый простой и правильный способ — запускать все тесты пакета с фильтром:
go test -v -run "TestHandle" ./
Дополнительные советы
- Используйте флаг
-count=1, чтобы отключить кэширование результатов тестов:go test -count=1 -v -run "TestHandle" ./... - Для параллельного запуска добавьте
-parallel N, где N — количество параллельных тестов. - Проверьте покрытие кода для конкретного теста:
go test -cover -run "TestHandle" ./... - Используйте табличные тесты (table-driven tests), чтобы легко запускать отдельные подтесты по имени.
Пример табличного теста
func TestHandleRequest(t *testing.T) {
tests := []struct {
name string
input string
want string
}{
{"valid_input", "test", "expected"},
{"empty_input", "", "error"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := HandleRequest(tt.input)
if got != tt.want {
t.Errorf("got %v, want %v", got, tt.want)
}
})
}
}
Теперь вы можете запустить только подтест valid_input:
go test -v -run "TestHandleRequest/valid_input" ./...
<<Альтернативный подход: использование тегов сборки (build tags)
Если вам нужно часто запускать тесты только из определённых файлов, можно использовать механизм тегов сборки. Добавьте в начало тестового файла специальный комментарий:
//go:build integration
package main
import "testing"
func TestIntegrationFeature(t *testing.T) {
// ...
}
Теперь этот тест будет выполняться только при указании тега:
go test -tags=integration -v ./...
А обычные тесты (без тега) будут запускаться как обычно. Это удобно для разделения юнит-тестов и интеграционных тестов.
Использование Go 1.22+ для фильтрации по файлам
Начиная с Go 1.22, появилась возможность фильтровать тесты по исходному файлу через флаг -run с использованием синтаксиса file:testname. Пока эта функция экспериментальная, но в будущем может стать стандартной. Следите за обновлениями документации.
Работа в IDE
В большинстве IDE (VS Code с расширением Go, GoLand) есть возможность запустить конкретный тест прямо из редактора — нажмите на зелёную стрелку рядом с именем функции. Это самый простой способ для повседневной разработки.