Avatar ·

Как запустить все тесты в проекте Go (go test) и не пропустить ни одного?

Привет, коллеги! Я только начал изучать Go и пытаюсь разобраться с тестированием. У меня есть небольшой проект с такой структурой: ``` myproject/ ├── main.go ├── go.mod ├── pkg/ │ ├── calc/ │ │ ├── calc.go │ │ └── calc_test.go │ └── utils/ │ ├── strings.go │ └── strings_test.go └── tests/ └── integration_test.go ``` Когда я нахожусь в корне проекта и запускаю `go test`, он почему-то запускает только тесты из текущей папки (где лежит main.go), а тесты в подпапках `pkg/` и `tests/` игнорируются. Я пробовал писать `go test ./...`, но тогда он ругается на то, что не может найти некоторые файлы, особенно в `tests/`. Что я делаю не так? Как правильно запустить все тесты проекта одной командой? Нужно ли как-то специально настраивать `go.mod` или структуру папок? Буду благодарен за подробный ответ с примерами, так как в документации описано много флагов, но я путаюсь. <<>>

Основная команда и её нюансы

Для запуска всех тестов в проекте Go стандартная команда — go test ./.... Три точки означают "рекурсивно пройти по всем подпапкам". Однако, если команда выдаёт ошибки, это почти всегда связано с неправильной структурой проекта или именованием файлов.

Правильная структура и имена

В Go есть жёсткие правила:

  • Тестовые файлы обязательно должны заканчиваться на _test.go. Ваш integration_test.go — ок, но проверьте, что в папке tests/ нет других файлов без суффикса _test.
  • Функции тестов должны начинаться с Test, например TestSum.
  • Пакет в тестовом файле должен совпадать с пакетом тестируемого кода, либо быть package main с суффиксом _test (для внешних тестов).

Почему go test ./... может не работать

Ошибки "cannot find package" или "no test files" возникают из-за:

  • Файлы не входят в сборку. Если в папке tests/ лежит integration_test.go, а рядом нет обычного .go файла с тем же пакетом, Go не сможет скомпилировать тест. Решение: либо добавьте в папку tests/ файл с пакетом (например, package tests и пустую функцию), либо переместите интеграционные тесты в папку с основным кодом.
  • Несовместимость версий Go. Убедитесь, что go.mod указывает правильную версию (например, go 1.21).
  • Циклические зависимости. Если пакеты импортируют друг друга по кругу, тесты не соберутся.

Пошаговое решение для вашей структуры

Сделайте так:

  1. Переименуйте папку tests/ в integration/ и внутри создайте файл integration_test.go с пакетом integration или main_test.
  2. Убедитесь, что в папке integration/ есть хотя бы один не-тестовый файл (пустой) с тем же пакетом, иначе Go проигнорирует папку.
  3. Запускайте тесты из корня проекта командой:
    go test ./...

Полезные флаги

  • -v — подробный вывод (каждый тест поимённо).
  • -count=1 — отключить кэширование (полезно для свежих результатов).
  • -run ^TestName$ — запустить конкретный тест по имени.
  • -short — если вы написали поддержку коротких тестов в коде.

Пример полной команды для вашего случая:

go test -v -count=1 ./...

Что делать, если тесты всё равно не запускаются?

Проверьте:

  • Нет ли в папках файлов с ошибками синтаксиса.
  • Не используете ли вы go test внутри подпапки (тогда тесты выше не запустятся).
  • Не забыли ли вы выполнить go mod tidy для обновления зависимостей.

Если всё равно проблемы — временно удалите папку tests/ и запустите go test ./pkg/.... Если работает, значит проблема именно в папке с интеграционными тестами.

<<>>

Альтернативный подход: Makefile или скрипты

Если вы часто путаетесь в командах или хотите автоматизировать запуск с разными флагами, создайте в корне проекта файл Makefile:

test:
	go test -v -count=1 -race ./...

test-short:
	go test -v -short ./...

test-coverage:
	go test -coverprofile=coverage.out ./...
	go tool cover -html=coverage.out

Теперь достаточно писать make test или make test-coverage. Это удобно для CI/CD и командной работы.

Ещё один вариант: go test с явным перечислением пакетов

Если структура проекта сложная и ./... не подходит, можно перечислить все пакеты вручную:

go test ./pkg/calc/... ./pkg/utils/... ./tests/...

Но это неудобно при добавлении новых пакетов.

Совет по интеграционным тестам

Для изоляции интеграционных тестов от юнит-тестов используйте теги сборки (build tags). Добавьте в начало файла integration_test.go строку:

//go:build integration

Тогда они будут запускаться только по команде:

go test -tags=integration ./...

Это позволит держать быстрые юнит-тесты отдельно от медленных интеграционных.