Fundamentos de Pruebas de Interfaz y su Automatización con pytest

Conceptos Básicos de Interfaces

Las interfaces en software se clasifican en dos categorías principales: internas y externas.

  • Interfaces internas: Facilitan la comunicación entre módulos o componentes dentro de una misma aplicación. Por ejemplo, en un sistema de redes sociales, el módulo de publicaciones puede depender de la autenticación del usuario, requiriendo una interfaz interna para esta interacción.
  • Interfaces externas: Permiten la integración con sistemas o servicios ajenos. Al acceder a datos de fuentes externas, como APIs de terceros, se utilizan interfaces definidas para el intercambio seguro de información sin exponer bases de datos directamente.
  • Tipos comunes incluyen APIs HTTP, RPC y otros protocolos para la comunicación entre sistemas.

Pruebas de Interfaz: Definición y Propósito

Las pruebas de interfaz verifican la interacción entre componentes de software, enfocándose en el flujo de datos, la lógica de negocio y el manejo de errores. Su objetivo es validar que las entradas y salidas cumplan con los requisitos funcionales y de seguridad.

Elementos Clave de una Interfaz

Una interfaz típicamente incluye: URL del endpoint, método HTTP (GET, POST, etc.), parámetros de solicitud (entrada) y respuesta (salida), así como encabezados opcionales. La documentación oficial, como la de APIs de servicios populares, proporciona estos detalles para guiar las pruebas.

Importancia de las Pruebas de Interfaz

  • Descubre defectos que no son visibles a nivel de interfaz de usuario.
  • Evalúa la capacidad del sistema para manejar excepciones y situaciones inesperadas.
  • Mejora la estabilidad y seguridad al validar la lógica de negocio subyacente.
  • Permite cambios en el frontend sin afectar al backend, siempre que las interfaces se mantengan estables.

Automatización de Pruebas de Interfaz

La automatización de pruebas de interfaz implica ejecutar scripts para validar componentes de forma repetible, lo que incremanta la eficiencia y precisión. Al centrarse en la lógica interna y el intercambio de datos, facilita la detección temprana de problemas en comparación con pruebas manuales o de UI.

Flujo de Trabajo para Automatización

  1. Análisis de Requisitos: Examinar los detalles de la solicitud (URL, método, parámetros) y la respuesta (formato, código de estado).
  2. Selección de Interfaces: Priorizar interfaces críticas, de alto riesgo o de uso frecuente para la automatización, considerando su complejidad y impacto en el negocio.
  3. Diseño de Casos de Prueba: Desarrollar escenarios positivos (funcionamiento esperado) y negativos (errores, límites), basados en documentación o pruebas existentes.
  4. Configuración del Entorno: Elegir herramientas y lenguajes adecuados, como Python con bibliotecas como requests para solicitudes HTTP y frameworks como pytest para la ejecución.
  5. Implemantación del Framework: Crear una estructura para organizar pruebas, manejar datos parametrizados y generar informes.
  6. Escritura y Ejecución de Scripts: Codificar los casos de prueba y ejecutarlos usando comandos del framework.
  7. Generación de Reportes: Utilizar herramientas como Allure o pytest-html para producir informes legibles tras la ejecución.

Framework de Pruebas Automatizadas: pytest

pytest es un framework de pruebas para Python que destaca por su simplicidad y extensibilidad. Su documentación oficial ofrece guías detalladas para su uso.

Reglas para Ejecución de Pruebas en pytest

  • Los archivos de prueba deben empezar con test_ o terminar con _test.
  • Las clases de prueba deben tener el prefijo Test y no deben incluir un método __init__.
  • Los métodos de prueba dentro de las clases deben iniciar con test.
  • La ausencia de __init__ evita interferencias con el mecanismo de auto-descubrimiento de pytest.

Parámetros de Línea de Comandos

Comando Descripción
pytest Ejecuta pruebas en el directorio actual y subdirectorios.
pytest -v Aumenta el nivel de detalle en la salida.
pytest -s Muestra las declaraciones print durante las pruebas.
pytest test_modulo.py Ejecuta pruebas en un módulo específico.
pytest -k <keyword></keyword> Ejecuta pruebas cuyo nombre contenga la palabra clave especificada.
pytest -m <marcador></marcador> Ejecuta pruebas marcadas con un marcador específico.

Archivo de Configuración: pytest.ini

El archivo pytest.ini permite configurar opciones predeterminadas. Ejemplo:

[pytest]
addopts = -vs
testpaths = ./pruebas
python_files = test_*.py
python_classes = Prueba*

Este archivo configura pytest para buscar pruebas en el directorio pruebas, con archivos que empiecen con test_ y clases con prefijo Prueba.

Configuración de Pre y Post Condiciones

pytest ofrece métodos para establecer acciones antes y después de las pruebas:

  • setup_method y teardown_method: Para cada método de prueba individual.
  • setup_class y teardown_class: Para toda la clase de prueba.
  • fixture: Enfoque recomendado para configuraciones flexibles y reutilizables.

Parametrización de Pruebas

La parametrización permite ejecutar la misma prueba con múltiples conjuntos de datos. Ejemplo con código modificado:

import pytest

@pytest.mark.parametrize("expresion,resultado_esperado", [("3+5", 8), ("2+4", 6), ("6*9", 42)])
def test_calculo(expresion, resultado_esperado):
    assert eval(expresion) == resultado_esperado

También se puede aplicar a clases:

import pytest

@pytest.mark.parametrize("numero,esperado", [(1, 2), (3, 4)])
class PruebaCalculo:
    def test_suma(self, numero, esperado):
        assert numero + 1 == esperado
    def test_multiplicacion(self, numero, esperado):
        assert (numero * 1) + 1 == esperado

Para parametrizar a nivel de módulo, se usa la variable pytestmark:

import pytest
pytestmark = pytest.mark.parametrize("numero,esperado", [(1, 2), (3, 4)])

class PruebaGlobal:
    def test_simple(self, numero, esperado):
        assert numero + 1 == esperado

Las fuentes de datos pueden ser externas, por ejemplo, de una función:

def proveedor_datos():
    return ["a", "b"]

@pytest.mark.parametrize("dato", proveedor_datos())
def test_con_proveedor(dato):
    assert dato is not None
    print(f"Probando con dato: {dato}")

Etiquetas: pytest Python API testing automatización de pruebas pruebas de interfaz

Publicado el 6-2 05:02