Compartir comentarios
Las respuestas se generan en base a la documentación.

Escribe pruebas con Testcontainers

Crearás un contenedor PostgreSQL utilizando Testcontainers y lo usarás para todas las pruebas. Antes de cada prueba, eliminarás todos los registros de clientes para que las pruebas se ejecuten con una base de datos limpia.

Configura fixtures de pytest

Esta guía utiliza fixtures de pytest para la lógica de inicialización (setup) y finalización (teardown). Un enfoque recomendado es utilizar finalizadores para garantizar que la limpieza se ejecute incluso si la configuración inicial falla:

@pytest.fixture
def setup(request):
    # código de configuración (setup)

    def cleanup():
        # código de finalización (teardown)

    request.addfinalizer(cleanup)
    return some_value

Crea el archivo de prueba

Crea un archivo tests/__init__.py vacío para habilitar la detección automática (auto-discovery) de pytest.

Luego crea tests/test_customers.py con las fixtures:

import os
import pytest
from testcontainers.postgres import PostgresContainer

from customers import customers

postgres = PostgresContainer("postgres:16-alpine")


@pytest.fixture(scope="module", autouse=True)
def setup(request):
    postgres.start()

    def remove_container():
        postgres.stop()

    request.addfinalizer(remove_container)
    os.environ["DB_CONN"] = postgres.get_connection_url()
    os.environ["DB_HOST"] = postgres.get_container_host_ip()
    os.environ["DB_PORT"] = str(postgres.get_exposed_port(5432))
    os.environ["DB_USERNAME"] = postgres.username
    os.environ["DB_PASSWORD"] = postgres.password
    os.environ["DB_NAME"] = postgres.dbname
    customers.create_table()


@pytest.fixture(scope="function", autouse=True)
def setup_data():
    customers.delete_all_customers()

Esto es lo que hacen las fixtures:

  • La fixture setup tiene scope="module", por lo que se ejecuta una vez para todas las pruebas del archivo. Inicia un contenedor PostgreSQL, establece variables de entorno con los detalles de conexión y crea la tabla customers. Una función de limpieza detiene el contenedor después de que se completan todas las pruebas.
  • La fixture setup_data tiene scope="function", por lo que se ejecuta antes de cada prueba. Elimina todos los registros para dar a cada prueba una base de datos limpia.

Escribe las pruebas

Añade las funciones de prueba al mismo archivo:

def test_get_all_customers():
    customers.create_customer("Siva", "[email protected]")
    customers.create_customer("James", "[email protected]")
    customers_list = customers.get_all_customers()
    assert len(customers_list) == 2


def test_get_customer_by_email():
    customers.create_customer("John", "[email protected]")
    customer = customers.get_customer_by_email("[email protected]")
    assert customer.name == "John"
    assert customer.email == "[email protected]"
  • test_get_all_customers() inserta dos registros de clientes, obtiene todos los clientes y verifica la cantidad.
  • test_get_customer_by_email() inserta un cliente, lo obtiene por correo electrónico y verifica los detalles.

Debido a que setup_data elimina todos los registros antes de cada prueba, las pruebas pueden ejecutarse en cualquier orden.