usar unitarias unitaria software sistema que pruebas las ist integración integracion función desarrollo cuál cuando consisten beneficios unit-testing go integration-testing testify

unit-testing - software - pruebas unitarias beneficios



Pruebas unitarias de separación y pruebas de integración en Go (3)

¿Existe una mejor práctica establecida para separar las pruebas unitarias y las pruebas de integración en GoLang (testificar)? Tengo una combinación de pruebas unitarias (que no dependen de ningún recurso externo y, por lo tanto, funcionan muy rápido) y pruebas de integración (que dependen de los recursos externos y, por lo tanto, se ejecutan más lentamente). Por lo tanto, quiero poder controlar si incluir o no las pruebas de integración cuando digo " go test .

La técnica más directa parece ser definir una bandera de integración en main:

var runIntegrationTests = flag.Bool("integration", false , "Run the integration tests (in addition to the unit tests)")

Y luego para agregar un enunciado if al principio de cada prueba de integración:

if !*runIntegrationTests { this.T().Skip("To run this test, use: go test -integration") }

¿Es esto lo mejor que puedo hacer? Busqué en la documentación del testimonio para ver si hay tal vez una convención de nombres o algo que logre esto para mí, pero no encontré nada. ¿Me estoy perdiendo de algo?


@ Ainar-G sugiere varios patrones geniales para separar las pruebas.

Este conjunto de prácticas de Go de SoundCloud recomienda usar etiquetas de compilación ( descritas en la sección "Restricciones de compilación" del paquete de compilación ) para seleccionar qué pruebas ejecutar:

Escribe un integration_test.go y dale una etiqueta de compilación de integración. Defina indicadores (globales) para cosas como direcciones de servicio y cadenas de conexión, y úselos en sus pruebas.

// +build integration var fooAddr = flag.String(...) func TestToo(t *testing.T) { f, err := foo.Connect(*fooAddr) // ... }

ir prueba toma etiquetas de compilación al igual que ir compilación, por lo que puede llamar go test -tags=integration . También sintetiza un paquete principal que llama a flag.Parse, por lo que las banderas declaradas y visibles se procesarán y estarán disponibles para sus pruebas.

Como una opción similar, también podría tener pruebas de integración ejecutadas de forma predeterminada mediante el uso de una condición de compilación // +build !unit , y luego desactivarlas bajo demanda ejecutando go test -tags=unit .

@adamc comenta:

Para cualquier otra persona que intente usar etiquetas de compilación, es importante que el // +build test comentario de // +build test sea ​​la primera línea en su archivo, y que incluya una línea en blanco después del comentario; de lo contrario, el comando -tags ignorará la directiva.

Además, la etiqueta utilizada en el comentario de compilación no puede tener un guión, aunque se permiten subrayados. Por ejemplo, // +build unit-tests no funcionará, mientras que // +build unit_tests hará.


Para explicar mi comentario a la excelente respuesta de @Ainar-G, en el último año he estado usando la combinación de -short con la convención de nomenclatura de Integration para lograr lo mejor de ambos mundos.

Unit and Integration prueba la armonía, en el mismo archivo

Construir banderas anteriormente me obligó a tener múltiples archivos ( services_test.go , services_integration_test.go , etc.).

En su lugar, tome este ejemplo a continuación donde los dos primeros son pruebas unitarias y tengo una prueba de integración al final:

package services import "testing" func TestServiceFunc(t *testing.T) { t.Parallel() ... } func TestInvalidServiceFunc3(t *testing.T) { t.Parallel() ... } func TestPostgresVersionIntegration(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") } ... }

Tenga en cuenta que la última prueba tiene la convención de:

  1. usando Integration en el nombre de la prueba.
  2. comprobando si se está ejecutando bajo la directiva -short flag.

Básicamente, la especificación dice: "escriba todas las pruebas normalmente. Si se trata de pruebas de larga duración o una prueba de integración, siga esta convención de nomenclatura y verifique que" -short sea ​​agradable para sus compañeros ".

Ejecutar solo pruebas unitarias:

go test -v -short

esto le proporciona un buen conjunto de mensajes como:

=== RUN TestPostgresVersionIntegration --- SKIP: TestPostgresVersionIntegration (0.00s) service_test.go:138: skipping integration test

Ejecute solo pruebas de integración:

go test -run Integration

Esto solo ejecuta las pruebas de integración. Útil para pruebas de humo de canarios en producción.

Obviamente, la desventaja de este enfoque es que si alguien ejecuta la go test , sin el -short , ejecutará por defecto todas las pruebas de prueba de unidad e integración.

En realidad, si su proyecto es lo suficientemente grande como para tener pruebas unitarias y de integración, entonces es muy probable que esté usando un Makefile donde pueda tener directivas simples para usar go test -short en él. O bien, simplemente README.md en su archivo README.md y README.md el día.


Veo tres soluciones posibles. El primero es usar el modo corto para pruebas unitarias. Así que usaría go test -short con pruebas unitarias y lo mismo pero sin el -short para ejecutar también sus pruebas de integración. La biblioteca estándar usa el modo corto para omitir pruebas de larga ejecución o hacer que se ejecuten más rápido al proporcionar datos más simples.

El segundo es usar una convención y llamar a sus pruebas ya sea TestUnitFoo o TestIntegrationFoo y luego usar el -run prueba de -run para indicar qué pruebas ejecutar. Por lo tanto, debería utilizar la go test -run ''Unit'' para las pruebas unitarias e go test -run ''Integration'' para las pruebas de integración.

La tercera opción es usar una variable de entorno y obtenerla en la configuración de pruebas con os.Getenv . Luego, usaría la go test simple para las pruebas unitarias y FOO_TEST_INTEGRATION=true go test para las pruebas de integración.

Yo personalmente preferiría la solución " -short porque es más simple y se usa en la biblioteca estándar, por lo que parece que es una forma de hecho de separar / simplificar las pruebas de larga duración. Pero las soluciones -run y os.Getenv ofrecen más flexibilidad (se requiere más precaución también, ya que las expresiones regulares están involucradas con -run ).