# Tests Unitarios - MCP SQL
Este directorio contiene tests unitarios para todas las herramientas del proyecto MCP SQL.
## Estructura
```
tests/
├── __init__.py # Inicialización del paquete de tests
├── conftest.py # Fixtures y configuración compartida de pytest
├── test_list_servers.py # Tests para ListServersService
├── test_get_databases.py # Tests para GetDatabasesService
├── test_get_tables.py # Tests para GetTablesService
├── test_describe_table.py # Tests para DescribeTableService
├── test_explore_table.py # Tests para ExploreTableService
├── test_query_columns.py # Tests para QueryColumnsService
└── test_execute_select.py # Tests para ExecuteSelectService
```
## Instalación de Dependencias
Para ejecutar los tests, necesitas instalar las dependencias de testing:
```bash
pip install pytest pytest-asyncio pytest-cov
```
O actualizar el archivo `requirements.txt` del proyecto.
## Ejecutar los Tests
### Ejecutar todos los tests
```bash
pytest tests/
```
### Ejecutar tests de una herramienta específica
```bash
pytest tests/test_execute_select.py
```
### Ejecutar con cobertura de código
```bash
pytest tests/ --cov=mcp_sql --cov-report=html
```
### Ejecutar en modo verbose
```bash
pytest tests/ -v
```
### Ejecutar tests específicos por nombre
```bash
pytest tests/ -k "test_execute_returns"
```
## Fixtures Compartidos
El archivo `conftest.py` proporciona las siguientes fixtures reutilizables:
### Fixtures de Contexto
- `mock_context`: Contexto mock de FastMCP
- `mock_credentials`: Credenciales válidas mock
- `mock_invalid_credentials`: Credenciales inválidas mock
### Fixtures de Managers
- `mock_connection_manager`: ConnectionManager mock
- `mock_credentials_manager`: CredentialsManager mock (con credenciales válidas)
- `mock_credentials_manager_invalid`: CredentialsManager mock (con credenciales inválidas)
- `mock_database_inspector`: DatabaseInspector mock
- `mock_query_executor`: QueryExecutor mock
### Fixtures Combinadas
- `tool_dependencies`: Todas las dependencias necesarias para una herramienta
- `tool_dependencies_invalid`: Dependencias con credenciales inválidas
## Estructura de los Tests
Cada archivo de test sigue esta estructura:
1. **Tests de propiedades**: Verifican `name` y `description`
2. **Tests de funcionalidad básica**: Verifican el comportamiento normal
3. **Tests de validación**: Verifican manejo de errores y validaciones
4. **Tests de integración con mocks**: Verifican llamadas a dependencias
## Cobertura de Tests
Los tests cubren los siguientes casos para cada herramienta:
- ✅ Verificación de nombre y descripción
- ✅ Ejecución exitosa con datos válidos
- ✅ Manejo de credenciales inválidas
- ✅ Validación de parámetros requeridos
- ✅ Verificación de llamadas a servicios dependientes
- ✅ Casos edge (límites, valores vacíos, etc.)
## Agregar Nuevos Tests
Para agregar tests para una nueva herramienta:
1. Crea un archivo `test_nombre_herramienta.py`
2. Importa la clase de servicio
3. Crea una clase de test que herede de los casos base
4. Usa las fixtures de `conftest.py`
5. Marca los tests async con `@pytest.mark.asyncio`
Ejemplo:
```python
import pytest
from mcp_sql.tools.mi_herramienta import MiHerramientaService
@pytest.mark.asyncio
class TestMiHerramientaService:
async def test_name_property(self, tool_dependencies):
service = MiHerramientaService(**tool_dependencies)
assert service.name == "mi_herramienta"
async def test_execute(self, tool_dependencies, mock_context):
service = MiHerramientaService(**tool_dependencies)
result = await service.execute(mock_context)
assert result is not None
```
## Mejores Prácticas
1. **Usa mocks**: No conectes a bases de datos reales en tests unitarios
2. **Tests aislados**: Cada test debe ser independiente
3. **Nombres descriptivos**: Los nombres de tests deben describir qué verifican
4. **Un assert por concepto**: Enfócate en un aspecto por test
5. **Fixture reusable**: Usa las fixtures de `conftest.py` para evitar duplicación
## CI/CD
Para integrar los tests en un pipeline de CI/CD:
```yaml
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pip install pytest pytest-asyncio pytest-cov
- run: pytest tests/ --cov=mcp_sql --cov-report=xml
```
## Troubleshooting
### Error: "Module not found"
Asegúrate de ejecutar pytest desde el directorio raíz del proyecto:
```bash
cd /ruta/a/mcp-sql
pytest tests/
```
### Error: "No module named 'mcp_sql'"
Instala el paquete en modo desarrollo:
```bash
pip install -e .
```
### Tests async no se ejecutan
Verifica que tienes instalado `pytest-asyncio` y que los tests async están marcados con `@pytest.mark.asyncio`.