Запуск main-подобного в неосновном пакете

У нас есть пакет с изрядным количеством сложных тестов. Как часть набора тестов, они запускаются в сборках и т. д.

 func TestFunc(t *testing.T) {
    //lots of setup stuff and defining success conditions
    result := SystemModel.Run()
 }

Теперь, для одного из этих тестов, я хочу представить какой-то интерфейс, который позволит мне отлаживать некоторые вещи. Это не совсем тест, а инструмент отладки. Для этого я хочу просто запустить тот же тест, но с шаблоном Builder:

 func TestFuncWithFrontend(t *testing.T) {
    //lots of setup stuff and defining success conditions
    result := SystemModel.Run().WithHTTPFrontend(":9999")
 }

Тогда тест начнется только в том случае, если я отправлю сигнал через HTTP из внешнего интерфейса. В основном WithHTTPFrontend() просто ожидает с каналом HTTP-вызова от внешнего интерфейса.

Это, конечно, приведет к сбою автоматических тестов, потому что такой сигнал не будет отправлен и выполнение зависнет.

Я не могу просто переименовать пакет в main, потому что в пакете 15 файлов, и они используются где-то еще в системе.

Точно так же я не нашел способа запускать тест только по запросу, исключая его из набора тестов, чтобы TestFuncWithFrontend запускался только из командной строки - мне все равно, с go run или go test или чем-то еще.

Я также подумал о ExampleTestFunc(), но тест дает так много результатов, что он бесполезен, и без определения Output: ... пример не будет работать.

К сожалению, на уровне пакета (частный, то есть в нижнем регистре) есть также много кода инициализации, который необходим тесту. Так что я не могу просто создать подпакет main, так как многие из этих вещей будут недоступны.

Кажется, у меня есть три варианта:

  1. Экспортируйте все эти переменные инициализации и код в верхнем регистре, чтобы я мог использовать его из подосновного пакета.

  2. Дублируйте весь код.

  3. Переместите тест в подпакет main, а затем получите func main() для теста с Frontend и _test.go для обычного теста, который должен импортировать некоторые вещи из родительского пакета.

Я бы предпочел обойтись без второго варианта ... И первый лучше, но ИМХО тоже не лучший. Думаю, пойду на третий, но ...

мне не хватает другого варианта?

1
0
2 072
2

Ответы 2

Я наконец нашел приемлемый вариант. Этот ответ

Пропустите некоторые тесты с помощью теста go

привел меня на верный путь.

По сути, с использованием тегов сборки, которых нет в обычных сборках, но которые я могу предоставить при выполнении вручную.

Вы можете передать настраиваемый аргумент командной строки в go test и запустить порт отладки на его основе. Что-то вроде этого:

package hello_test

import (
    "flag"
    "log"
    "testing"
)

var debugTest bool

func init() {
    flag.BoolVar(&debugTest, "debug-test", false, "Setup debugging for tests")
}

func TestHelloWorld(t *testing.T) {
    if debugTest {
        log.Println("Starting debug port for test...")
        // Start the server here
    }

    log.Println("Done")
}

Затем, если вы хотите запустить именно этот тест, go test -debug-test -run '^TestHelloWorld$' ./.

В качестве альтернативы также можно установить пользовательскую переменную среды, которую вы проверяете в тестовой функции, чтобы изменить поведение.

Мне это действительно нравится! Никаких дополнительных тестов не требуется, и выполняется точно такой же код! Я подумаю об этом дальше, а затем решу и, возможно, приму. Спасибо!

transient_loop 13.09.2018 22:15

Да, это приятная особенность. Хотя ваш вариант использования новый, мы используем его для включения / отключения тестов, выполнение которых требует времени или зависит от внешних служб. Таким образом, быстрый go test можно запускать довольно часто, а более длительный и подробный тест можно запускать, если быстрые тесты пройдут успешно или перед отправкой в ​​репозиторий.

svsd 13.09.2018 22:26

Другие вопросы по теме