¿Cómo ejecutar pruebas de golang de forma secuencial?

Resuelto Varun Patro asked hace 9 años • 5 respuestas

Cuando ejecuto go test, mi salida:

--- 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)

Pero después de volver a ejecutar go test, todas mis pruebas pasan.

Las pruebas fallan solo cuando reinicio mi base de datos MySQL y luego las ejecuto go testpor primera vez.

Para cada GETsolicitud, hago una POSTsolicitud antes para asegurarme de que haya datos creados en la base de datos.

¿Alguien podría ayudarme a asegurarme de que las pruebas se ejecuten de forma secuencial? ¿ Es decir que las POSTsolicitudes se ejecutan antes que las GETsolicitudes?

Varun Patro avatar Jul 03 '15 15:07 Varun Patro
Aceptado

No puede ni debe confiar en el orden de ejecución de la prueba. El orden en que se ejecutan las pruebas no está definido y con el uso de indicadores de prueba es posible excluir la ejecución de las pruebas, por lo que no tiene ninguna garantía de que se ejecutarán.

Por ejemplo, el siguiente comando solo ejecutará pruebas cuyo nombre contenga una 'W'letra:

go test -run W

También tenga en cuenta que si algunas funciones de prueba se marcan como elegibles para la ejecución paralela utilizando el T.Parallel()método, la herramienta go reordenará las pruebas para ejecutar primero pruebas no paralelas y luego ejecutar pruebas paralelas en paralelo bajo ciertas circunstancias (controladas por indicadores de prueba como -p). Puedes ver ejemplos de esto en esta respuesta: ¿ Las pruebas se ejecutan en paralelo en Go o una por una?

Las pruebas deben ser independientes entre sí. Si una función de prueba tiene requisitos previos, eso no se puede hacer/implementar en otra función de prueba.

Opciones para realizar tareas adicionales antes de ejecutar una función de prueba:

  • Puedes ponerlo en la propia función de prueba.
  • Puedes ponerlo en una init()función de paquete, en el _test.gopropio archivo. Esto se ejecutará una vez antes de que comience la ejecución de las funciones de prueba.
  • Puede optar por implementar una TestMain()función que se llamará primero y en la que puede realizar una configuración adicional antes de llamar M.Run()para activar la ejecución de funciones de prueba.
  • Puede combinar las opciones anteriores.

En su caso en paquete init()o TestMain()debe verificar si su base de datos está inicializada (hay registros de prueba insertados), y si no, insertar los registros de prueba.

Tenga en cuenta que a partir de Go 1.7, puede utilizar subpruebas en las que define el orden de ejecución de las subpruebas. Para obtener más información, consulte la publicación del blog: Uso de subpruebas y subbenchmarks y la documentación del paquete testing.

icza avatar Jul 03 '2015 10:07 icza

Para aquellos que, como yo, tienen problemas debido a que se ejecutan múltiples pruebas simultáneas. Encontré una manera de limitar el número máximo de pruebas que se ejecutan en paralelo:

go test -p 1

Con esto, su prueba se ejecutará secuencialmente una por una.

Fuente

Alik Khilazhev avatar Jun 05 '2020 08:06 Alik Khilazhev

Aparte de las bibliotecas de terceros como Convey y Ginkgo , con Golang 1.7 simple puedes ejecutar pruebas de forma secuencial. Puede leer más aquí

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>
}

Y puedes ejecutarlos condicionalmente con:

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".

Entonces digamos que tienes un userpaquete de una API REST que deseas probar. Debe probar el controlador de creación para poder probar el controlador de inicio de sesión. Normalmente tendría esto en eluser_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()
    })

}

Luego puedo agregar métodos al tipo UserTest que no serán ejecutados por el go testcomando en ningún _test.goarchivo.

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)
}
CESCO avatar Sep 27 '2016 20:09 CESCO

La mejor manera de lograrlo es crear un TestMain, como se presenta aquí .

import (
  "testing"
  "os"
)

func TestMain(m *testing.M) {
   // Do your stuff here
   os.Exit(m.Run())
}
nouney avatar Jul 03 '2015 08:07 nouney