Шаг 1: Аудит существующих зависимостей. Первым делом необходимо составить полную картину используемых инструментов. Выполните в корне вашего проекта команду `go list -m all`, чтобы увидеть все модульные зависимости. Отдельно проанализируйте файл `go.mod`. Ключевые цели для анализа — это библиотеки и фреймворки для тестирования. Стандартная библиотека `testing` — это основа, она является частью самого Go и не требует замены. В фокусе внимания должны быть:
- Фреймворки для модульного и интеграционного тестирования (например, `testify`, `gocheck`).
- Библиотеки для моков (например, `gomock`, `mockery`).
- Инструменты для тестирования производительности и бенчмарков (например, `go test -bench`).
- Системы запуска тестов и генерации отчетов (встроенный `go test`, `gotestsum`).
- Использование стандартной библиотеки `testing` везде, где это возможно. Она мощна и покрывает 80% потребностей.
- Поиск или создание отечественных аналогов для конкретных нужд (например, фреймворк утверждений — assertions).
- Форк международного проекта с открытым кодом и его локализация (перенос репозитория, перевод документации, адаптация под внутренние стандарты).
- Разработка собственных минималистичных инструментов силами команды.
- Отказаться от утверждений в пользу стандартного `if got != want { t.Errorf(...) }`. Это повысит прозрачность тестов.
- Написать свой минимальный пакет `assert` (50-100 строк кода), реализующий ключевые функции: `Equal`, `NotNil`, `NoError`. Это даст контроль и независимость.
- Исследовать открытые репозитории на платформах вроде GitFlic или Forgejo на предмет уже созданных локальных решений.
- Рассмотрите подход ручного мокинга через создание структур-заглушек, реализующих нужные интерфейсы. Это трудоемко, но максимально прозрачно и контролируемо.
- Используйте встроенные фичи Go: табличные тесты (table-driven tests) и dependency injection (внедрение зависимостей через интерфейсы в конструктор) часто снижают потребность в сложных моках.
- Если генерация необходима, можно рассмотреть использование `go:generate` директив вместе с простыми скриптами на самом Go для генерации кода заглушек по интерфейсам.
Шаг 6: Работа с кэшем модулей и прокси. Для полного цикла необходимо обеспечить внутреннее зеркалирование модулей Go. Настройте `GOPROXY` на внутренний сервер, например, `athens` или `goproxy`, развернутый внутри вашей инфраструктуры. Это изолирует процесс сборки от внешних репозиториев и ускорит загрузку зависимостей. Все прямые зависимости, которые остались после очистки (например, специализированные библиотеки), должны быть завендорины (скопированы в репозиторий проекта с помощью `go mod vendor`) или также размещены на внутреннем proxy.
Шаг 7: Создание внутренней документации и стандартов. Зафиксируйте принятые решения: какой инструментарий используется, как писать тесты без внешних фреймворков, как создавать моки. Это обеспечит единообразие в команде и упростит onboarding новых разработчиков.
Шаг 8: Поэтапный рефакторинг. Не пытайтесь переписать все тесты сразу. Начните с нового модуля или пакета в проекте, напишите тесты по новым стандартам. Постепенно рефакторьте старые тесты по мере изменения кода, к которому они привязаны. Используйте возможности `go test` для запуска тестов только определенного пакета.
Этот путь требует дополнительных усилий и может привести к увеличению объема шаблонного кода в тестах. Однако выигрыш — это полная независимость от внешней экосистемы в критически важном процессе обеспечения качества кода, соответствие требованиям регуляторов и повышенная безопасность. Код тестов становится проще и понятнее, хотя и более многословным. В конечном счете, вы получаете полностью контролируемый и суверенный цикл разработки и тестирования вашего Go-проекта.
Комментарии (13)