2. Preparación del proyecto base en Python para automatizar pruebas

2.1 Objetivo del tema

En el tema anterior vimos qué significa automatizar una prueba y cuándo conviene hacerlo. Ahora vamos a preparar un proyecto base en Python que nos servirá para practicar automatización durante el curso.

El objetivo no es crear una aplicación grande, sino una base ordenada: código separado de las pruebas, entorno virtual, dependencias registradas, configuración inicial y un comando simple para ejecutar la suite.

Objetivo práctico: dejar creado un proyecto Python mínimo, prolijo y listo para ejecutar pruebas automatizadas con pytest.

2.2 Por qué preparar un proyecto base

Una suite automatizada no debería crecer como una colección desordenada de archivos. Si desde el inicio usamos una estructura clara, será más fácil agregar pruebas, compartir utilidades, ejecutar comandos y entender las fallas.

Un buen proyecto base ayuda a responder rápidamente estas preguntas:

  • ¿Dónde está el código de la aplicación?
  • ¿Dónde están las pruebas automatizadas?
  • ¿Qué dependencias necesita el proyecto?
  • ¿Con qué comando se ejecuta la suite?
  • ¿Qué configuración usa pytest?

2.3 Crear la carpeta del proyecto

Desde una terminal, crea una carpeta para el proyecto del curso:

mkdir automatizacion-pruebas-python
cd automatizacion-pruebas-python

Usaremos esta carpeta como raíz del proyecto. Todos los comandos de este tema se ejecutarán desde allí, salvo que se indique lo contrario.

2.4 Crear el entorno virtual

Un entorno virtual permite aislar las dependencias de este proyecto. Ejecuta:

python -m venv .venv

Esto crea una carpeta llamada .venv. No escribiremos pruebas dentro de esa carpeta; solo contiene herramientas y paquetes instalados para el proyecto.

Recomendación: usa un entorno virtual por proyecto. Así evitas mezclar dependencias de distintas prácticas o cursos.

2.5 Activar el entorno virtual

En Windows PowerShell:

.venv\Scripts\Activate.ps1

En Windows CMD:

.venv\Scripts\activate.bat

En Linux o macOS:

source .venv/bin/activate

Cuando el entorno está activo, normalmente verás (.venv) al comienzo de la línea de comandos.

2.6 Actualizar pip e instalar pytest

Con el entorno virtual activo, actualiza pip e instala pytest:

python -m pip install --upgrade pip
python -m pip install pytest

Verifica la instalación:

python -m pytest --version

Usaremos python -m pytest porque ejecuta pytest con el Python del entorno activo.

2.7 Crear las carpetas principales

Vamos a separar el código de la aplicación y las pruebas:

mkdir app
mkdir tests

La carpeta app tendrá el código que queremos verificar. La carpeta tests tendrá las pruebas automatizadas.

2.8 Convertir app en un paquete Python

Dentro de app, crea un archivo vacío llamado __init__.py:

type nul > app\__init__.py

En Linux o macOS, puedes usar:

touch app/__init__.py

Este archivo permite importar módulos desde app de manera clara en nuestras pruebas.

2.9 Crear el primer módulo de la aplicación

Crea el archivo app/calculadora.py con este contenido:

def sumar(a, b):
    return a + b


def dividir(a, b):
    if b == 0:
        raise ValueError("No se puede dividir por cero")

    return a / b

Es un módulo pequeño, pero suficiente para verificar que la estructura del proyecto funciona.

2.10 Crear la primera prueba en la carpeta tests

Crea el archivo tests/test_calculadora.py:

import pytest

from app.calculadora import dividir, sumar


def test_sumar_devuelve_la_suma_de_dos_numeros():
    assert sumar(3, 4) == 7


def test_dividir_devuelve_el_resultado_de_la_division():
    assert dividir(10, 2) == 5


def test_dividir_rechaza_division_por_cero():
    with pytest.raises(ValueError):
        dividir(10, 0)

Observa que la prueba importa desde app.calculadora. Esa importación confirma que el código está separado de las pruebas.

2.11 Ejecutar la suite

Desde la raíz del proyecto, ejecuta:

python -m pytest

pytest buscará automáticamente archivos que comiencen con test_ o terminen en _test.py. En este caso encontrará tests/test_calculadora.py.

Si todo está correcto, deberías ver que las tres pruebas pasan.

2.12 Estructura obtenida

El proyecto debe quedar parecido a esto:

automatizacion-pruebas-python/
|-- .venv/
|-- app/
|   |-- __init__.py
|   `-- calculadora.py
`-- tests/
    `-- test_calculadora.py

Esta separación será la base para los próximos temas. Más adelante agregaremos configuración, datos de prueba, fixtures y reportes.

2.13 Registrar dependencias

Para que otra persona pueda preparar el mismo entorno, registra las dependencias en un archivo requirements.txt:

python -m pip freeze > requirements.txt

Luego, en otro equipo o entorno, se podrían instalar con:

python -m pip install -r requirements.txt

En proyectos reales podemos usar otras herramientas, pero requirements.txt es simple y suficiente para comenzar.

2.14 Crear una configuración inicial de pytest

Crea un archivo llamado pytest.ini en la raíz del proyecto:

[pytest]
testpaths = tests
python_files = test_*.py
python_functions = test_*

Esta configuración indica que pytest debe buscar pruebas dentro de la carpeta tests y usar la convención de nombres que estamos practicando.

No es obligatorio crear este archivo para que pytest funcione, pero ayuda a documentar las reglas del proyecto desde el principio.

2.15 Ejecutar con salida más clara

Ahora ejecuta:

python -m pytest -v

La opción -v muestra una salida más detallada. Es útil cuando queremos ver el nombre de cada prueba ejecutada.

También puedes detener la ejecución en la primera falla con:

python -m pytest -x

2.16 Crear un script simple de ejecución

Para evitar recordar comandos largos, crea un archivo llamado run_tests.py en la raíz:

import subprocess
import sys


def main():
    comando = [sys.executable, "-m", "pytest", "-v"]
    resultado = subprocess.run(comando, check=False)
    return resultado.returncode


if __name__ == "__main__":
    raise SystemExit(main())

Ejecuta el script con:

python run_tests.py

Este script todavía es simple, pero muestra una idea importante: podemos automatizar también la forma en que se ejecuta la suite.

2.17 Agregar un README mínimo

Un proyecto base debe explicar cómo preparar y ejecutar las pruebas. Crea un archivo README.md con este contenido:

# Automatización de Pruebas con Python

## Preparar el entorno

python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt

## Ejecutar pruebas

python -m pytest -v

El README evita depender de la memoria. Cualquier alumno o integrante del equipo puede revisar los pasos básicos del proyecto.

2.18 Estructura final del tema

Al terminar este tema, la estructura completa debería ser:

automatizacion-pruebas-python/
|-- .venv/
|-- app/
|   |-- __init__.py
|   `-- calculadora.py
|-- tests/
|   `-- test_calculadora.py
|-- pytest.ini
|-- README.md
|-- requirements.txt
`-- run_tests.py

Esta base ya permite escribir código, agregar pruebas, ejecutar la suite y compartir instrucciones mínimas.

2.19 Problemas frecuentes

  • No se encuentra el módulo app: ejecuta pytest desde la raíz del proyecto, no desde la carpeta tests.
  • pytest no se reconoce: activa el entorno virtual o ejecuta python -m pytest.
  • La prueba no se ejecuta: revisa que el archivo comience con test_ y que la función también comience con test_.
  • El editor marca errores de importación: selecciona el intérprete Python del entorno .venv.
  • El comando type nul no funciona: ese comando es de Windows. En Linux o macOS usa touch.

2.20 Ejercicio práctico

Agrega un nuevo archivo app/textos.py con una función llamada normalizar_texto. La función debe:

  • Quitar espacios al comienzo y al final.
  • Convertir el texto a minúsculas.
  • Reemplazar espacios dobles por un solo espacio.

Luego crea tests/test_textos.py y automatiza al menos tres pruebas para esa función.

2.21 Solución propuesta

Una posible implementación para app/textos.py es:

def normalizar_texto(texto):
    partes = texto.strip().lower().split()
    return " ".join(partes)

Y una posible suite en tests/test_textos.py es:

from app.textos import normalizar_texto


def test_normalizar_texto_quita_espacios_externos():
    assert normalizar_texto("  Python  ") == "python"


def test_normalizar_texto_convierte_a_minusculas():
    assert normalizar_texto("PyTest") == "pytest"


def test_normalizar_texto_reemplaza_espacios_multiples():
    assert normalizar_texto("curso   de    pruebas") == "curso de pruebas"

2.22 Lista de verificación

Antes de continuar con el próximo tema, verifica lo siguiente:

  • El proyecto tiene una carpeta app para el código.
  • El proyecto tiene una carpeta tests para las pruebas.
  • Existe un entorno virtual .venv.
  • pytest está instalado en el entorno virtual.
  • La suite se ejecuta con python -m pytest.
  • Las pruebas importan el código desde app.
  • Existe una configuración inicial en pytest.ini.

2.23 Conclusión

En este tema preparamos un proyecto base para automatizar pruebas con Python. Creamos una estructura separada para código y pruebas, instalamos pytest, escribimos una primera suite y agregamos configuración e instrucciones mínimas.

Esta base evita desorden cuando el curso avance. En el próximo tema profundizaremos en la estructura recomendada de carpetas para que la suite automatizada pueda crecer sin volverse confusa.