Aprende a estructurar un test | Programador Web Valencia

Aprende a estructurar un test

4 minutos

Testing

Usar un flujo de testing de algún tipo (TDD, BDD, E2E…) es una buena medida de calidad. No porque te asegure que la función u objeto funcione como esperas, sino porque indica que el proyecto posee una buena arquitectura y detrás hay buenos desarrolladores.

Hacer testing no trata solo sobre crear código que compruebe otro código, sino una metodología de trabajo profesional que amplia la visión del código. Escribes un preciso guión de que buscas, dejando claro como debe comportarse y de que manera reaccionará en casos extraordinarios. Todo ello sin tan siquiera escribir la funcionalidad. Además, de manera indirecta, dejas documentado el funcionamiento.

Suele decirse que hacer testing es artesanal, que todos los casos son únicos. No es cierto, disponemos de patrones o plantillas que nos ayudan a empezar y estructurar. Y entre las más sencillas y conocidos son encontramos con Given-When-Then.

Creado por Daniel Terhorst-North y Chris Matts como parte de BDD (Behavior-Driven Development), son sugieren un patrón de 3 bloques informales de comentarios para dividir el código.

  1. Given (Dado): Preparas el escenario del test, como la base de datos, variables o condiciones propicias.
  2. When (Cuando): Condiciones que transformarán el contenido.
  3. Then (Entonces): Verificas el resultado final, que se ha cumplido todo lo que esperabas o los casos propuestos.

Pongamos sobre la mesa un ejemplo en prosa. Vamos a escribir un test para el cuento de “los 3 cerditos”. El objetivo es comprobar que están a salvo del lobo.

Dado 3 casas, [‘paja’, ‘madera’, ‘ladrillos’]…

Cuando sople el lobo sobre cada una…

Entonces debe existir 1 o más casas en pie.

Con esta estructura, podemos escribir el test en cualquier lenguaje.

Antes de picar el código, vamos a definir una tabla con los casos que queremos probar. En este caso, vamos a probar 3 casos fictios de un login.

ID SCENARIO TEST CASE PRE-CONDITION GIVEN (INPUTS) THEN (Expected results)
test_login_1 Verify correct login Enter valid Email and valid Password Need a valid account Valid email and Valid password Successful login page
test_login_2 Verify login with wrong fields Enter a wrong email and a valid password Need a valid account Wrong email and Valid password Same page, error message: “The account does not exist or the password is wrong”
test_login_3 Verify login with wrong fields Enter a valid email and a wrong password Need a valid account Valid email and Wrong password Same page, error message: “The account does not exist or the password is wrong”

Aunque yo te recomiendo redactarlo en inglés, puedes hacerlo en el idioma que prefieras.

Ahora, vamos a escribir el código. Usaré Python con la librería pytest, pero puedes usar el lenguaje que prefieras.

import pytest

# Pre-condition: Need a valid account
VALID_EMAIL = "valid@example.com"
VALID_PASSWORD = "correctpassword"
WRONG_EMAIL = "wrong@example.com"
WRONG_PASSWORD = "wrongpassword"

# Given section: Input data for tests
@pytest.fixture
def valid_email():
    return VALID_EMAIL

@pytest.fixture
def valid_password():
    return VALID_PASSWORD

@pytest.fixture
def wrong_email():
    return WRONG_EMAIL

@pytest.fixture
def wrong_password():
    return WRONG_PASSWORD

# When section: Actions to be performed in tests
def login(email, password):
    # Mocked login function; replace with actual login implementation
    if email == VALID_EMAIL and password == VALID_PASSWORD:
        return {"msg": "Successful login page"}
    else:
        return {"msg": "The account does not exist or the password is wrong"}

# Then section: Expected results
def test_login_1(valid_email, valid_password):
    # Given
    email = valid_email
    password = valid_password

    # When
    result = login(email, password)

    # Then
    assert result.msg == "Successful login page"

def test_login_2(wrong_email, valid_password):
    # Given
    email = wrong_email
    password = valid_password

    # When
    result = login(email, password)

    # Then
    assert result.msg == "The account does not exist or the password is wrong"

def test_login_3(valid_email, wrong_password):
    # Given
    email = valid_email
    password = wrong_password

    # When
    result = login(email, password)

    # Then
    assert result.msg == "The account does not exist or the password is wrong"

Hemos implementado el mismo test que hemos definido en la tabla. En cada test, hemos definido las condiciones iniciales, las acciones a realizar y los resultados esperados. Los nombres de las funciones deben coincidir con los nombres de los test cases definidos en la tabla. De este modo podremos identificar fácilmente qué test case está fallando si alguno de ellos no pasa.

Los casos más comunes en testing

Cuando realizas testing, te encontrarás un patrón, casos comunes que debes tener en cuenta. A continuación voy a darte una lista de puntos a considerar a la hora de implementar:

  • Los datos son correctos y el resultado esperado es correcto. El caso ideal.
  • Los datos son incorrectos y el resultado esperado es incorrecto. Por ejemplo, un email incorrecto y una contraseña incorrecta.
  • Los inputs de entrada son insuficientes. Por ejemplo, falta un campo obligatorio.
  • Los inputs de entrada tienen tipos incorrectos. Por ejemplo, un número en lugar una lista.
  • Devuelve todos los mensajes de error posibles. Por ejemplo, si el email ya existe, el mensaje de error debe ser “Email ya existente”.
  • Datos de entrada extremos. Por ejemplo, un email con 1000 caracteres.
  • Datos de entrada límite. Por ejemplo, un email con 254 caracteres, que es el límite de un email.

Resumen

Has sido testigo de todos los pasos típicos en un desarrollo con la metodología TDD.

  1. Documentar.
  2. Crear test.
  3. Ejecutar el test, recibiendo que falla.
  4. Crear la funcionalidad.
  5. Volver a ejecutar, recibiendo un éxito.

Si quieres profundizar, puedes explorar mi curso gratuito de testing donde podrás conocer otras técnicas e implementaciones en otros lenguajes.

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario

Tal vez también te interese...