Есть ли устоявшаяся передовая практика разделения модульных и интеграционных тестов в GoLang (свидетельствовать)? У меня есть сочетание модульных тестов (которые не полагаются на какие-либо внешние ресурсы и поэтому выполняются очень быстро) и интеграционных тестов (которые полагаются на любые внешние ресурсы и, следовательно, работают медленнее). Итак, я хочу иметь возможность контролировать, включать ли интеграционные тесты, когда я говорю go test
.
Казалось бы, самый простой способ - определить флаг -integrate в main:
var runIntegrationTests = flag.Bool("integration", false
, "Run the integration tests (in addition to the unit tests)")
А затем добавить оператор if в начало каждого интеграционного теста:
if !*runIntegrationTests {
this.T().Skip("To run this test, use: go test -integration")
}
Это лучшее, что я могу сделать? Я просмотрел свидетельскую документацию, чтобы узнать, существует ли, возможно, соглашение об именах или что-то, что позволяет мне это сделать, но ничего не нашел. Я что-то упускаю?
источник
var integration = flag.Bool("integration", true, "Enable integration testing.")
переменную как вне функции, переменная будет отображаться в области пакета, и флаг будет работать правильноОтветы:
@ Ainar-G предлагает несколько отличных шаблонов для разделения тестов.
Этот набор практик Go от SoundCloud рекомендует использовать теги сборки ( описанные в разделе «Ограничения сборки» пакета сборки ) для выбора тестов для запуска:
В качестве аналогичного варианта вы также можете запустить интеграционные тесты по умолчанию с использованием условия сборки
// +build !unit
, а затем отключить их по запросу, запустивgo test -tags=unit
.@adamc комментарии:
Для всех, кто пытается использовать теги сборки, важно, чтобы
// +build test
комментарий был первой строкой в вашем файле, и чтобы вы включили пустую строку после комментария, в противном случае-tags
команда проигнорирует директиву.Кроме того, тег, используемый в комментарии к сборке, не может содержать тире, хотя знаки подчеркивания разрешены. Например,
// +build unit-tests
работать не будет, а// +build unit_tests
будет.источник
// + build unit
модульные тесты и использовать -tag unit для запуска тестов// +build
тестовый комментарий был первой строкой в вашем файле, а вы добавили пустую строку после комментария, иначе-tags
команда проигнорирует директиву. Кроме того, тег, используемый в комментарии к сборке, не может содержать тире, хотя знаки подчеркивания разрешены. Например,// +build unit-tests
не будет работать, тогда как// +build unit_tests
будетgo test -tags=integration ./...
не работает, игнорирует тегЧтобы подробнее рассказать о моем комментарии к отличному ответу @Ainar-G, за последний год я использовал комбинацию
-short
сIntegration
соглашением об именах, чтобы добиться лучшего из обоих миров.Гармония модульных и интеграционных тестов в одном файле
Флаги сборки ранее заставляли меня иметь несколько файлов (
services_test.go
,services_integration_test.go
и т. Д.).Вместо этого возьмите этот пример ниже, где первые два являются модульными тестами, а в конце у меня есть интеграционный тест:
Обратите внимание, что последний тест имеет соглашение:
Integration
в названии теста.-short
директивой flag.По сути, спецификация гласит: «Пишите все тесты в обычном режиме. Если это длительные тесты или интеграционный тест, следуйте этому соглашению об именах и проверяйте,
-short
чтобы они были вежливыми по отношению к вашим коллегам».Запускать только модульные тесты:
это дает вам хороший набор сообщений, например:
Запустить только тесты интеграции:
Это запускает только интеграционные тесты. Полезно для дымовых испытаний канареек на производстве.
Очевидно, обратная сторона этого подхода заключается в том, что если кто-то работает
go test
без-short
флага, по умолчанию будут выполняться все тесты - модульные и интеграционные.В действительности, если ваш проект достаточно велик, чтобы иметь модульные и интеграционные тесты, то вы, скорее всего, используете a,
Makefile
где у вас могут быть простые директивы для использованияgo test -short
в нем. Или просто положите это в свойREADME.md
файл и скажите, что будет.источник
import
свой пакет и тестировать с ним, что в итоге показывает мне, как мой API выглядит для других. Затем я отслеживаю оставшуюся логику, которую необходимо включить в имена внутренних тестовых пакетов.package services
содержится тестовый набор интеграции, поэтому для тестирования API-интерфейса пакета как черного ящика мы должны назвать его по-другому, такpackage services_integration_test
как это не даст нам возможности работать с внутренними структурами. Итак, пакет для модульных тестов (доступ к внутреннему устройству) должен быть названpackage services
. Это так?Я вижу три возможных решения. Первый - использовать короткий режим для модульных тестов. Таким образом, вы должны использовать
go test -short
с модульными тестами и то же самое, но без-short
флага, чтобы запускать ваши интеграционные тесты. Стандартная библиотека использует короткий режим, чтобы либо пропустить длительные тесты, либо ускорить их выполнение, предоставляя более простые данные.Второй - использовать соглашение и вызывать ваши тесты либо
TestUnitFoo
или,TestIntegrationFoo
а затем использовать-run
флаг тестирования, чтобы указать, какие тесты запускать. Таким образом, вы должны использоватьgo test -run 'Unit'
для модульных тестов иgo test -run 'Integration'
для интеграционных тестов.Третий вариант - использовать переменную среды и получить ее в настройках тестов с помощью
os.Getenv
. Затем вы использовали бы простойgo test
для модульных тестов иFOO_TEST_INTEGRATION=true go test
для интеграционных тестов.Я лично предпочел бы это
-short
решение, так как оно проще и используется в стандартной библиотеке, поэтому кажется, что это де-факто способ разделения / упрощения длительных тестов. Но-run
иos.Getenv
решения предлагают большую гибкость (более необходима осторожность , а также, так как регэкспы участвуют с-run
).источник
Tester-Go
общие для IDE (Atom, Sublime и т. д.) имеют встроенную опцию для запуска с-short
флагом, а также с-coverage
другими. поэтому я использую комбинацию Integration в названии теста вместе сif testing.Short()
проверками внутри этих тестов. он позволяет мне использовать лучшее из обоих миров: запускать-short
в среде IDE и явно запускать только интеграционные тесты сgo test -run "Integration"
Недавно я пытался найти решение для того же самого. Это были мои критерии:
Вышеупомянутые решения (настраиваемый флаг, настраиваемый тег сборки, переменные среды) на самом деле не удовлетворяли всем вышеперечисленным критериям, поэтому, немного покопавшись и поиграв, я пришел к следующему решению:
Реализация проста и минимальна. Хотя это требует простого соглашения для тестов, но менее подвержено ошибкам. Дальнейшее улучшение может заключаться в экспорте кода во вспомогательную функцию.
использование
Запускайте интеграционные тесты только для всех пакетов в проекте:
Запустить все тесты ( обычные и интеграционные):
Запускайте только обычные тесты:
Это решение хорошо работает без инструментов, но Makefile или некоторые псевдонимы могут облегчить пользователю задачу. Его также можно легко интегрировать в любую среду IDE, которая поддерживает запуск тестов go.
Полный пример можно найти здесь: https://github.com/sagikazarmark/modern-go-application
источник