Серийное выполнение пакетных тестов
Я реализовал несколько пакетов для веб-API, каждый из которых имеет свои собственные тестовые случаи. Когда каждая упаковка тестируется с использованием go test ./api/pkgname
испытания проходят. Если я хочу запустить все тесты одновременно с go test ./api/...
тестовые случаи всегда терпят неудачу.
В каждом тестовом примере я воссоздаю всю схему, используя DROP SCHEMA public CASCADE
с последующим CREATE SCHEMA public
и применить все миграции. Набор тестов случайным образом сообщает об ошибках, говоря, что связь / таблица не существует, поэтому я предполагаю, что каждый набор тестов (для пакета) каким-то образом выполняется параллельно, что приводит к нарушению состояния БД.
Я пытался передать некоторые тестовые флаги, такие как go test -cpu 1 -parallel 0 ./src/api/...
без успеха.
Может ли быть проблема в том, что тесты выполняются параллельно, и если да, то как я могу форсировать последовательное выполнение?
Обновить:
В настоящее время я использую этот обходной путь для запуска тестов, но мне все еще интересно, есть ли лучшее решение
find <dir> -type d -exec go test {} \;
3 ответа
Как уже отмечали другие, -parallel не выполняет свою работу (он работает только внутри пакетов). Однако вы можете использовать флаг -p=1 для последовательного запуска тестов пакетов. Это задокументировано здесь:
http://golang.org/src/cmd/go/testflag.go
но (на самом деле) не в командной строке, иди в справку и т. д. Я не уверен, что это должно остаться (хотя я бы сказал, что, если он будет удален, -параллель должна быть исправлена).
Инструмент go предназначен для упрощения запуска модульных тестов, используя соглашение о том, что файлы *_test.go содержат в себе юнит-тесты. Поскольку он предполагает, что они являются юнит-тестами, он также предполагает, что они герметичны. Похоже, ваши тесты либо не являются юнит-тестами, либо они нарушают предположения, которые должен выполнить юнит-тест.
В том случае, если вы хотите, чтобы эти тесты были юнит-тестами, вам, вероятно, понадобится фиктивная база данных для ваших юнит-тестов. Макет, предпочтительно в памяти, вашей базы данных гарантирует, что юнит-тест герметичен и не может быть нарушен другими юнит-тестами.
В случае, если вы подразумеваете, что эти тесты являются интеграционными, вам, вероятно, лучше не использовать инструмент go для этих тестов. Вероятно, вы захотите создать отдельный тестовый бинарный файл, запуск которого вы можете контролировать, и написать там сценарии интеграционного тестирования.
Хорошей новостью является то, что создать макет в Go очень просто. Измените свой код, чтобы использовать интерфейс с методами, которые вам нужны для баз данных, а затем запишите реализацию этого интерфейса в памяти для целей тестирования и передайте его в код приложения, который вы хотите протестировать.
Просто чтобы уточнить, ответ @ Джереми по-прежнему принят:
Так как мои интеграционные тесты были запущены только на одном пакете (api
), В конце я удалил отдельный двоичный файл теста и создал шаблон для разделения типов тестов:
- Модульные тесты используют обычные
TestX
название - Интеграционные тесты используют
Test_X
Я создал сценарии оболочки (utest.sh
/itest.sh
) запустить любой из них.
- Для юнит-тестов
go test -run="^(Test|Benchmark)[^_](.*)"
- Для интеграционных тестов
go test -run"^(Test|Benchmark)_(.*)"
- Запустите оба, используя обычный
go test