Как запустить тесты golang последовательно?

когда я запускаю go test мой вывод:

--- FAIL: TestGETSearchSuccess (0.00s)
        Location:       drivers_api_test.go:283
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

--- FAIL: TestGETCOSearchSuccess (0.00s)
        Location:       drivers_api_test.go:391
        Error:          Not equal: 200 (expected)
                                != 204 (actual)

но после того, как я запустить go test опять же, все мои тесты проходят.

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

для каждого GET запрос, я делаю POST запрос перед тем, чтобы убедиться, что есть данные, созданные в БД.

может кто-нибудь помочь мне с тем, чтобы убедиться, что тесты выполняются последовательно? Это POST запросы выполняются до GET запросы?

3 ответов


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

например, следующая команда будет запускать только тесты, имя которых содержит 'W' письмо:

go test -run W

также обратите внимание, что если некоторые тестовые функции помечают себя для параллельного выполнения с помощью T.Parallel() метод, инструмент go будет переупорядочивать тесты для первого запуска непараллельных тестов, а затем запускать параллельные тесты параллельно при определенных обстоятельствах (контролируется тестовыми флагами, такими как -p). Вы можете увидеть примеры этого в этом ответе:тесты выполняются параллельно в Go или один за другим?

тесты должны быть независимая друг от друга. Если тестовая функция имеет необходимые условия, это невозможно сделать / реализовать в еще одна тестовая функция.

опции для выполнения дополнительных задач перед запуском тестовой функции:

  • вы можете поместить его в функцию проверить себя
  • вы можете положить его в пакет

отдельно для сторонних библиотек, таких как передать и гинкго, С простым Golang 1.7 вы можете запускать тесты последовательно. Вы можете прочитать больше здесь

func TestFoo(t *testing.T) {
    // <setup code>
    t.Run("A=1", func(t *testing.T) { ... })
    t.Run("A=2", func(t *testing.T) { ... })
    t.Run("B=1", func(t *testing.T) { ... })
    // <tear-down code>
}

и вы можете запустить их условно с:

go test -run ''      # Run all tests.
go test -run Foo     # Run top-level tests matching "Foo", such as "TestFooBar".
go test -run Foo/A=  # For top-level tests matching "Foo", run subtests matching "A=".
go test -run /A=1    # For all top-level tests, run subtests matching "A=1".

Итак, скажем, у вас есть user пакет из REST api, который вы хотите протестировать. Вам нужно протестировать обработчик create, чтобы иметь возможность протестировать обработчик входа в систему. Обычно у меня было бы это на user_test.go

type UserTests struct { Test *testing.T}
func TestRunner(t *testing.T) {

    t.Run("A=create", func(t *testing.T) {
        test:= UserTests{Test: t}
        test.TestCreateRegularUser()
        test.TestCreateConfirmedUser()
        test.TestCreateMasterUser()
        test.TestCreateUserTwice()
    })
    t.Run("A=login", func(t *testing.T) {
        test:= UserTests{Test: t}
        test.TestLoginRegularUser()
        test.TestLoginConfirmedUser()
        test.TestLoginMasterUser()
    })

}

тогда я могу добавить методы к типу UserTest, который не будет выполняться в любом

func (t *UserTests) TestCreateRegularUser() {
    registerRegularUser := util.TableTest{
        Method:      "POST",
        Path:        "/iot/users",
        Status:      http.StatusOK,
        Name:        "registerRegularUser",
        Description: "register Regular User has to return 200",
        Body: SerializeUser(RegularUser),
    }
    response := util.SpinSingleTableTests(t.Test, registerRegularUser)
    util.LogIfVerbose(color.BgCyan, "IOT/USERS/TEST", response)
}

лучший способ достичь этого-создать TestMain, представленного здесь.

import (
  "testing"
  "os"
)

func TestMain(m *testing.M) {
   // Do your stuff here
   os.Exit(m.Run())
}