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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
tests.python -m pytest.test_ y que la función también comience con test_..venv.touch.Agrega un nuevo archivo app/textos.py con una función llamada normalizar_texto. La función debe:
Luego crea tests/test_textos.py y automatiza al menos tres pruebas para esa función.
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"
Antes de continuar con el próximo tema, verifica lo siguiente:
app para el código.tests para las pruebas..venv.pytest está instalado en el entorno virtual.python -m pytest.app.pytest.ini.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.