A logo showing the text blog.marcnuri.com
English
Inicio»Go»Cómo preparar y desmontar tests unitarios en Go

Entradas Recientes

  • Fabric8 Kubernetes Client 7.2.0 está disponible!
  • Conectarse a un servidor MCP con JavaScript y AI SDK
  • Conectarse a un servidor MCP con JavaScript y LangChain.js
  • El Futuro de las Herramientas para Desarrolladores en la era de la IA
  • Conectarse a un servidor Model Context Protocol (MCP) con Java y LangChain4j

Categorías

  • Antiguo
  • Front-end
  • Go
  • Herramientas
  • Industria y negocios
  • Inteligencia Artificial
  • Java
  • JavaScript
  • Operaciones
  • Personal
  • Proyectos personales

Archivos

  • mayo 2025
  • abril 2025
  • marzo 2025
  • febrero 2025
  • enero 2025
  • diciembre 2024
  • noviembre 2024
  • agosto 2024
  • junio 2024
  • mayo 2024
  • abril 2024
  • marzo 2024
  • febrero 2024
  • enero 2024
  • diciembre 2023
  • noviembre 2023
  • octubre 2023
  • septiembre 2023
  • agosto 2023
  • julio 2023
  • junio 2023
  • mayo 2023
  • abril 2023
  • marzo 2023
  • febrero 2023
  • enero 2023
  • diciembre 2022
  • noviembre 2022
  • octubre 2022
  • agosto 2022
  • julio 2022
  • mayo 2022
  • marzo 2022
  • febrero 2022
  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021
  • diciembre 2020
  • octubre 2020
  • agosto 2020
  • junio 2020
  • mayo 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • noviembre 2019
  • octubre 2019
  • julio 2019
  • diciembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • marzo 2018
  • febrero 2018
  • noviembre 2017
  • octubre 2017
  • agosto 2017
  • julio 2017
  • enero 2017
  • julio 2016
  • enero 2016
  • diciembre 2015
  • noviembre 2015
  • diciembre 2014
  • marzo 2014
  • febrero 2011
  • junio 2008
  • mayo 2008
  • abril 2008
  • enero 2008
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007

Cómo preparar y desmontar tests unitarios en Go

2023-10-12 en Go etiquetado Go / Testing / Test-Driven Development (TDD) por Marc Nuri | Última actualización: 2025-02-11
English version

Introducción

Cuando escribimos pruebas unitarias en Go, a veces es útil realizar acciones comunes que deben ejecutarse antes y después de un test. Estas tareas de preparación y desmontaje pueden ser necesarias en diferentes ámbitos:

  • Antes y después de que se ejecute la suite completa de pruebas.
  • Antes y después de que se ejecute cada prueba.
  • O incluso antes y después de que se ejecute un grupo concreto de pruebas.

Procedente de un entorno Java, esta es una práctica común. Los frameworks de pruebas como JUnit tienen anotaciones integradas que proporcionan esta funcionalidad de forma aspect-oriented. Sin embargo, lograr lo mismo en Go con la biblioteca estándar de pruebas ha sido un poco esquivo. En este artículo, te mostraré cómo conseguirlo en Go.

Ejecutar código antes y después de la suite completa de tests

A partir de Go 1.4, la biblioteca estándar proporciona una forma de ejecutar código antes y después de que se ejecute la suite completa de pruebas. Si un fichero de test en un paquete contiene una función con la firma:

func TestMain(m *testing.M)

Go ejecutará esa función en lugar de ejecutar las pruebas directamente. Puedes aprender más sobre esta función en la documentación de la biblioteca estándar de Go.

Una implementación típica de esta función sería:

func TestMain(m *testing.M) {
  // Setup code goes here
  code := m.Run()
  // Teardown code goes here
  os.Exit(code)
}

Esta función nos permite ejecutar código antes y después de que se ejecute la suite completa de pruebas. Para ejecutar las pruebas, necesitamos llamar a m.Run().

Nota

Nótese cómo almacenamos el resultado de m.Run() en una variable y luego llamamos a os.Exit(code) para salir del programa con el código de salida adecuado.

Cuestiones a tener en cuenta:

  • Puedes definir esta función en cualquiera de los ficheros de test de tu paquete.
  • Los nombres de las funciones son únicos en un paquete, por lo que sólo puedes definir una función TestMain por paquete.
  • Si tu paquete contiene varios ficheros de test, coloca la función TestMain donde tenga más sentido.
  • Si no llamas a os.Exit con el código de retorno de m.Run(), tu comando de test siempre devolverá 0 (incluso si falla).

Veamos ahora cómo ejecutar código antes y después de un grupo de tests.

Ejecutar código antes y después de un grupo de tests

Otro escenario común es ejecutar código o preparar el entorno de pruebas antes de que se ejecute un grupo de tests. Los subtests de Go son muy útiles en este caso.

Los Subtests emplean la función t.Run(name string, f func(t *T)) para ejecutar la función f como un subtest de t.

Veamos un ejemplo:

func TestSomethingWhenGivenCondition(t *testing.T) {
  // Setup code for given condition goes here
  t.Run("Something has property one", func(t *testing.T) {
    // Subtest 1 code goes here
  })
  t.Run("Something has property two", func(t *testing.T) {
    // Subtest 2 code goes here
  })
  // Teardown code for given condition goes here
}

Supongamos que queremos probar el comportamiento de nuestra aplicación en un entorno con condiciones específicas. Los subtests nos permiten agrupar estas pruebas bajo una función, en este caso, TestSomethingWhenGivenCondition.

Esta función nos permite configurar y desmontar el entorno ejecutando código antes y después de la invocación de cada subtest. A continuación, podemos ejecutar un subtest usando la función t.Run para cada propiedad o comportamiento de la aplicación que queremos probar.

Puedes encontrar un ejemplo completo en este enlace. Veamos ahora cómo ejecutar código antes y después de cada test individual.

Ejecutar código antes y después de cada test

La biblioteca estándar de pruebas de Go no proporciona una forma integrada de ejecutar código antes y después de cada test. Si queremos hacer esto, necesitamos proporcionar una implementación alternativa. Esto es lo que suelo hacer.

Define un struct para contener el contexto del test que se inicializará y desmontará antes y después de cada test.

type testContext struct {
  some    string
  test    *pkg.Var
  context int64
}

func (c *testContext) beforeEach() {
  // Setup code for context goes here
}

func (c *testContext) afterEach() {
  // Teardown code for context goes here
}

A continuación, define una función que se utilizará para encapsular cada test:

func testCase(test func(t *testing.T, c *testContext)) func(*testing.T) {
  return func(t *testing.T) {
    context := &testContext{}
    context.beforeEach()
    defer context.afterEach()
    test(t, context)
  }
}

Por último, utiliza esta función en un subtest:

func TestSomething(t *testing.T) {
  t.Run("Some test case", testCase(func(t *testing.T, c *testContext) {
    // Test code goes here which can leverage the context
  }))
}

Por cada invocación de test, se crea un nuevo testContext y se llaman a las funciones beforeEach y afterEach antes y después de que se ejecute el test.

Puedes encontrar un ejemplo completo en este enlace.

Conclusión

En este artículo, hemos visto cómo configurar y desmontar correctamente un test unitario en Go usando la biblioteca estándar de Go para pruebas unitarias. Hemos visto cómo ejecutar código antes y después de la suite completa de pruebas, antes y después de un grupo de pruebas, y antes y después de cada prueba. Estas técnicas te ayudarán a escribir pruebas robustas y bien organizadas en tus proyectos Go.

¡Feliz testing!

Te puede interesar

  • Cómo Inicializar un Nuevo Proyecto Go con Módulos
  • Pruebas unitarias para APIs REST basadas en Go Gin Web Framework con httptest
  • Introducción a Testcontainers para Go
Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Navegador de artículos
Pruebas unitarias para APIs REST basadas en Go Gin Web Framework con httptestFabric8 Kubernetes Client 6.9 está disponible!
© 2007 - 2025 Marc Nuri