A logo showing the text blog.marcnuri.com
English
Inicio»Go»Introducción a Testcontainers para 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

Introducción a Testcontainers para Go

2023-11-03 en Go etiquetado Go / Testcontainers / Testing / Test-Driven Development (TDD) / HTTP por Marc Nuri | Última actualización: 2023-11-03
English version

Introducción

Testcontainers es una potente librería open source diseñada para realizar pruebas de integración en tus aplicaciones Go. La librería proporciona una forma sencilla de crear y gestionar contenedores Docker efímeros, permitiéndote simular dependencias como bases de datos, brokers de mensajería u otros servicios necesarios para el funcionamiento de tu aplicación durante la fase de pruebas. Mediante el uso de Testcontainers, puedes probar tu aplicación en un entorno que se asemeje a tu entorno de producción, reduciendo la necesidad de mocks o costosos entornos de pruebas.

En este artículo, te guiaré para que puedas comenzar a usar Testcontainers, centrándome en cómo incorporarlo a tu proyecto Go. Comenzaremos creando un nuevo proyecto Go y añadiendo la librería Testcontainers como dependencia. A continuación, te mostraré cómo crear e interactuar con un contenedor Docker que ejecuta un servidor HTTP como parte de tus pruebas.

Puedes encontrar el código fuente completo de este tutorial en GitHub.

Creando el proyecto

Comencemos creando un nuevo proyecto para explorar las posibilidades de Testcontainers.

Inicializando un nuevo módulo Go

Emplearemos Go Modules para gestionar nuestras dependencias. Para comenzar, crea un nuevo directorio e inicializa un nuevo módulo Go:

bash
mkdir testcontainers-go-getting-started
cd testcontainers-go-getting-started
go mod init github.com/marcnuri-demo/testcontainers-go-getting-started

Si el proceso se completa correctamente, deberías tener un nuevo archivo go.mod con el siguiente contenido:

go.mod
module github.com/marcnuri-demo/testcontainers-go-getting-started

go 1.21.2

Creando el paquete main

A continuación, crearemos un nuevo archivo main_test.go que nos servirá como la base para la implementación del test:

main_test.go
package main

import "testing"

func TestExample(t *testing.T) {
}

Añadiendo la dependencia de Testcontainers

Ahora que tenemos la estructura para el test, podemos añadir la librería Testcontainers como dependencia. Para ello, emplearemos el comando go get:

bash
go get github.com/testcontainers/testcontainers-go

Este comando añadirá la dependencia de Testcontainers en tu archivo go.mod y creará un archivo go.sum con los checksums de las dependencias.

Implementando el test

Con la estructura del proyecto y la dependencia de Testcontainers en su lugar, podemos comenzar a trabajar en nuestro test.

Comenzaremos viendo cómo crear un nuevo contenedor que ejecute un sencillo servidor HTTP.

Creando un contenedor

Modifiquemos la función TestExample para incluir una petición a Testconainers para crear un nuevo contenedor:

main_test.go
func TestExample(t *testing.T) {
	containerCtx := context.Background()
	chuckNorris, _ := testcontainers.GenericContainer(containerCtx, testcontainers.GenericContainerRequest{
		Started: true,
		ContainerRequest: testcontainers.ContainerRequest{
			Image:        "marcnuri/chuck-norris:latest",
			ExposedPorts: []string{"8080/tcp"},
			WaitingFor:   wait.ForLog("Listening on: http://0.0.0.0:8080"),
		},
	})
	defer func() {
		err := chuckNorris.Terminate(containerCtx)
		if err != nil {
			panic(err)
		}
	}()
}

Veamos qué está sucediendo en el código anterior:

  • Iniciamos un contexto Go llamado containerCtx que Testcontainers empleará para gestionar la información sobre el ciclo de vida del contenedor.
  • Usando la función GenericContainer, creamos un nuevo contenedor. Esta función requiere un contexto Go como primer argumento. El segundo parámetro es una estructura GenericContainerRequest con los siguientes campos:
    • Started: Un booleano que indica si el contenedor debe iniciarse tan pronto como se crea. Como queremos que el contenedor se inicie automáticamente, lo establecemos a true.
    • ContainerRequest: Una estructura ContainerRequest que contiene la información sobre el contenedor que queremos crear. En este caso, queremos crear un nuevo contenedor usando la imagen marcnuri/chuck-norris:latest que expone una API HTTP en el puerto 8080.

Veamos con más detalle los campos de la estructura ContainerRequest:

  • Image: La imagen Docker que se usará para el contenedor.
  • ExposedPorts: Un array que especifica los puertos que se exponen desde el contenedor.
  • WaitingFor: Una estructura LogStrategy que se usará para esperar a que el contenedor esté listo. En este ejemplo, usamos la función ForLog para esperar a que el contenedor registre el mensaje Listening on: http://0.0.0.0:8080 que es el mensaje que el contenedor traza cuando está listo para aceptar peticiones.

Por último, diferimos una función para asegurarnos de que el contenedor se termina después de que el test concluya, independientemente del resultado del test.

Puedes ejecutar el test con el siguiente comando:

bash
go test

Si todo va bien, deberías ver una salida similar a la siguiente:

bash
github.com/testcontainers/testcontainers-go - Connected to docker:
  Resolved Docker Host: unix:///var/run/docker.sock
  Resolved Docker Socket Path: /var/run/docker.sock
  Test SessionID: 459a37cc7f20d8c0f04f777e23bcea0cfe0556ba695e226e643a700ed927b4b1
  Test ProcessID: 52bf9bdd-48a2-4744-8f4e-52cfef44a17d
🐳 Creating container for image marcnuri/chuck-norris:latest
✅ Container created: a7a9ef65cf1a
🐳 Starting container: a7a9ef65cf1a
✅ Container started: a7a9ef65cf1a
🚧 Waiting for container id a7a9ef65cf1a image: marcnuri/chuck-norris:latest. Waiting for: &{timeout:<nil> Log:Listening on: http://0.0.0.0:8080 IsRegexp:false Occurrence:1 PollInterval:100ms}
🐳 Terminating container: a7a9ef65cf1a
🚫 Container terminated: a7a9ef65cf1a

Haciendo peticiones al contenedor

Ahora que tenemos un contenedor en ejecución, veamos cómo interactuar con él. Modificaremos la función TestExample para hacer una petición al contenedor y validar su respuesta:

main_test.go
func TestExample(t *testing.T) {
  // ... Testcontainers initialization code
	endpoint, err := chuckNorris.Endpoint(containerCtx, "http")
	if err != nil {
		t.Error(err)
	}
	response, err := http.Get(endpoint)
	if err != nil {
		t.Error(err)
	}
	if response.StatusCode != http.StatusOK {
		t.Errorf("Expected status code %d, got %d", http.StatusOK, response.StatusCode)
	}
	body, err := io.ReadAll(response.Body)
	if err != nil {
		t.Error(err)
	}
	bodyString := string(body)
	if !strings.Contains(strings.ToLower(bodyString), "chuck") {
		t.Errorf("Expected a Chuck Norris approved response, got \"%s\"", bodyString)
	}
}

El fragmento de código anterior hace lo siguiente:

  • Empleando la función Endpoint recuperamos el endpoint del contenedor. Esta función requiere un contexto Go como primer argumento y un protocolo como segundo argumento. En el ejemplo, queremos recuperar el endpoint HTTP, así que pasamos http como segundo argumento.
  • Empleando la función http.Get, hacemos una petición al endpoint del contenedor.
  • Validamos que el código de estado de la respuesta es 200 OK.
  • Leemos el cuerpo de la respuesta y validamos que contiene la palabra Chuck.

Puedes ejecutar el test de nuevo empleando el comando go test. Todo debería de funcionar como se espera y deberías ver el test en verde.

Conclusión

En este artículo, hemos visto cómo empezar a usar Testcontainers para Go desde cero. Hemos comenzado creando un nuevo proyecto Go y añadiendo la dependencia de Testcontainers. A continuación, hemos implementado un sencillo test que crea un nuevo contenedor y hace una petición HTTP al mismo. Ahora ya deberías de tener una sólida base para incorporar Testcontainers en tus proyectos Go.

Puedes encontrar el código fuente completo para este artículo en GitHub.

¡Feliz testing!

Twitter iconFacebook iconLinkedIn iconPinterest iconEmail icon

Navegador de artículos
Eclipse JKube 1.15 está disponible!Pruebas unitarias para APIs REST basadas en Go Gin Web Framework con httptest
© 2007 - 2025 Marc Nuri