Resumen

¿Qué es el testing y por qué es importante?

El testing es una parte fundamental en el ciclo de desarrollo de software. Aunque es un tema vasto que podría requerir cursos enteros dedicados, en este contexto nos centraremos en crear pruebas unitarias para el código que desarrollamos. Las pruebas unitarias son pequeñas evaluaciones que verifican el comportamiento de funciones individuales. Este proceso no solo valida que el código funciona como se espera, sino que también nos ayuda a garantizar la calidad y a detectar errores con anticipación. Además, vamos a medir el code coverage, que nos indica qué porcentaje de nuestro código está cubierto por estas pruebas.

¿Cómo creamos pruebas unitarias en Go?

Para ilustrar el proceso de creación de pruebas unitarias en Go, comenzamos creando un archivo principal, main.go, que contiene una función simple de suma. Después, crearemos un archivo de pruebas, main_test.go, donde escribiremos las pruebas para la función de suma. Este archivo de pruebas debe seguir un formato específico para que Go lo reconozca, usando el sufijo _test.go.

Configuración inicial

Primero, definimos el paquete principal y la función que vamos a probar:

package main

func sum(x, y int) int {
    return x + y
}

Creación de la prueba unitaria

En el archivo main_test.go, definimos el paquete y la función de prueba. Es esencial importar el paquete testing, ya que proporciona las herramientas necesarias para verificar los resultados de las pruebas.

package main

import "testing"

func TestSum(t *testing.T) {
    total := sum(5, 5)
    if total != 10 {
        t.Errorf("Suma incorrecta, obtuvimos %d, pero esperábamos %d", total, 10)
    }
}

Ejecutando las pruebas

Para ejecutar las pruebas, utilizamos el comando go test desde la terminal. Si configuramos correctamente nuestro módulo con go mod init, las pruebas deberían ejecutarse sin problemas. En caso de haber errores, Go reportará los fallos y sus ubicaciones específicas en el código.

¿Cómo utilizamos tablas de prueba para múltiples casos?

Un patrón común para aplicar pruebas en Go es el uso de tablas de prueba. Esta técnica nos permite definir múltiples escenarios de prueba en un slice de structs, facilitando la iteración y ejecución de cada caso.

Creación de una tabla de pruebas

Definimos una estructura para nuestros casos de prueba, que incluya los valores de entrada y el resultado esperado.

func TestSum(t *testing.T) {
    testCases := []struct{a, b, expected int}{
        {1, 2, 3},
        {2, 2, 4},
        {25, 26, 51},
    }

    for _, tc := range testCases {
        result := sum(tc.a, tc.b)
        if result != tc.expected {
            t.Errorf("Suma incorrecta, obtuvimos %d, pero esperábamos %d", result, tc.expected)
        }
    }
}

Ventajas de las tablas de pruebas

Este enfoque no solo organiza el proceso de pruebas, sino que también permite agregar y modificar casos fácilmente sin cambiar la lógica de prueba. Además, proporciona un marco claro para identificar fallos específicos cuando ocurren.

¿Qué impacto tiene el code coverage?

El code coverage es una métrica que indica qué parte de nuestro código ha sido ejecutada durante las pruebas. Aunque Go no obliga a cubrir el 100% del código, un bajo porcentaje de cobertura podría ocultar errores en partes no probadas. Go ofrece comandos para generar informes de cobertura, permitiéndonos identificar y mejorar áreas deficientes en nuestras pruebas.

Integración del code coverage

Para calcular el code coverage, podemos usar el comando go test -cover, que mostrará un resumen del porcentaje de código cubierto por las pruebas. Esta práctica nos ayuda a mantener un estándar de calidad alto y a asegurar que todas las partes críticas del código estén debidamente verificadas.

El uso consciente de pruebas unitarias y el seguimiento del code coverage no solo mejoran la calidad del software, sino que también aumentan la confianza en nuestras aplicaciones. Invito a continuar explorando y aplicando estos conceptos en sus proyectos para asegurar un desarrollo más sólido y eficiente.