Ejecutar Tests¶
Guia completa para ejecutar los tests de mcp-scan.
Comandos Rapidos¶
# Todos los tests
make test
# Tests con verbose
make test-verbose
# Tests con cobertura
make test-coverage
# Tests golden (snapshots)
make test-golden
# Tests de deteccion contra DVMCP
make test-detection
# Benchmarks
make bench
Tests Unitarios¶
Ejecutar todos los tests¶
Ejecutar tests de un paquete especifico¶
# Parser
go test ./internal/parser/...
# Motor de patrones
go test ./internal/pattern/...
# Taint analysis
go test ./internal/taint/...
# Scanner
go test ./pkg/scanner/...
# ML classifier
go test ./internal/ml/...
Ejecutar un test especifico¶
# Por nombre
go test ./internal/pattern/... -run TestPatternEngine_PromptInjection
# Con verbose
go test -v ./internal/pattern/... -run TestPatternEngine_PromptInjection
# Con output detallado de fallos
go test -v ./internal/pattern/... -run TestPatternEngine_PromptInjection -failfast
Ejecutar tests que coincidan con patron¶
# Todos los tests de SQL
go test ./... -run ".*SQL.*"
# Todos los tests de clasificador
go test ./... -run ".*Classifier.*"
# Todos los tests de taint
go test ./... -run ".*Taint.*"
Tests con Cobertura¶
Generar reporte de cobertura¶
# Ejecutar con cobertura
go test -coverprofile=coverage.out ./...
# Ver resumen en terminal
go tool cover -func=coverage.out
# Generar HTML interactivo
go tool cover -html=coverage.out -o coverage.html
open coverage.html # macOS
Cobertura por paquete¶
# Cobertura del parser
go test -coverprofile=parser.out ./internal/parser/...
go tool cover -func=parser.out
# Cobertura del motor de patrones
go test -coverprofile=pattern.out ./internal/pattern/...
go tool cover -func=pattern.out
Cobertura minima requerida¶
El proyecto requiere cobertura minima del 80%:
# Verificar cobertura minima
go test -coverprofile=coverage.out ./...
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | tr -d '%')
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "FAIL: Coverage $COVERAGE% < 80%"
exit 1
fi
Tests de Integracion¶
Ejecutar tests de integracion¶
# Tests de integracion (no se saltan)
go test -v ./pkg/scanner/... -run Integration
# Con timeout extendido (para proyectos grandes)
go test -v -timeout 5m ./pkg/scanner/... -run Integration
Saltar tests de integracion en CI rapido¶
Tests E2E completos¶
# Construir binario
make build
# Ejecutar contra fixture
./bin/mcp-scan scan testdata/fixtures/class_a/ --mode fast --output json
# Verificar salida
./bin/mcp-scan scan testdata/fixtures/class_a/ --mode fast --output json | jq '.findings | length'
Tests Golden (Snapshots)¶
Los tests golden comparan salidas actuales contra snapshots guardados.
Ejecutar tests golden¶
Actualizar snapshots¶
Cuando el formato de salida cambia intencionalmente:
# Actualizar todos los snapshots
UPDATE_GOLDEN=1 go test ./... -run Golden
# Actualizar snapshot especifico
UPDATE_GOLDEN=1 go test ./internal/reporter/... -run TestGolden_JSON
Ubicacion de snapshots¶
testdata/golden/
├── json/
│ ├── class_a_output.json
│ ├── class_g_output.json
│ └── ...
├── sarif/
│ ├── class_a_output.sarif
│ └── ...
└── evidence/
└── ...
Benchmarks¶
Ejecutar todos los benchmarks¶
Benchmarks de un paquete¶
# Benchmarks del clasificador ML
go test -bench=. ./internal/ml/...
# Benchmarks del scanner
go test -bench=. ./pkg/scanner/...
Benchmark especifico¶
# Solo el benchmark del clasificador
go test -bench=BenchmarkRuleBasedClassifier ./internal/ml/...
# Con memoria
go test -bench=BenchmarkRuleBasedClassifier -benchmem ./internal/ml/...
Comparar benchmarks¶
# Guardar baseline
go test -bench=. ./... > bench_old.txt
# Despues de cambios
go test -bench=. ./... > bench_new.txt
# Comparar (requiere benchstat)
go install golang.org/x/perf/cmd/benchstat@latest
benchstat bench_old.txt bench_new.txt
Benchmarks importantes¶
| Benchmark | Paquete | Descripcion |
|---|---|---|
BenchmarkRuleBasedClassifier |
ml | Clasificacion de prompts |
BenchmarkFeatureExtraction |
ml | Extraccion de features |
BenchmarkScanner_SmallProject |
scanner | Scan proyecto pequeno |
BenchmarkScanner_MediumProject |
scanner | Scan proyecto mediano |
BenchmarkParser_Python |
parser | Parsing Python |
BenchmarkParser_TypeScript |
parser | Parsing TypeScript |
Tests contra DVMCP¶
Configuracion inicial¶
# Clonar DVMCP si no existe
if [ ! -d "testdata/damn-vulnerable-MCP-server" ]; then
git clone https://github.com/harishsg993010/damn-vulnerable-MCP-server \
testdata/damn-vulnerable-MCP-server
fi
Ejecutar tests de deteccion¶
Validar cobertura de deteccion¶
Makefile Targets¶
# Tests basicos
test:
go test ./...
# Tests con verbose
test-verbose:
go test -v ./...
# Tests con cobertura
test-coverage:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# Tests golden
test-golden:
go test ./... -run Golden
# Tests de deteccion DVMCP
test-detection:
go test -v ./... -run TestDVMCP
# Benchmarks
bench:
go test -bench=. -benchmem ./...
# Tests rapidos (sin integracion)
test-fast:
go test -short ./...
# Tests con race detector
test-race:
go test -race ./...
CI/CD¶
GitHub Actions¶
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Run tests
run: go test -v -race -coverprofile=coverage.out ./...
- name: Check coverage
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | tr -d '%')
echo "Coverage: $COVERAGE%"
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "Coverage below 80%"
exit 1
fi
- name: Run benchmarks
run: go test -bench=. -benchtime=1s ./...
Pre-commit hook¶
#!/bin/bash
# .git/hooks/pre-commit
# Ejecutar tests rapidos
go test -short ./...
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi
# Verificar formato
gofmt -l . | grep -q .
if [ $? -eq 0 ]; then
echo "Some files need gofmt. Run: gofmt -w ."
exit 1
fi
Debugging de Tests¶
Ver output detallado¶
# Output completo de tests fallidos
go test -v ./... 2>&1 | tee test.log
# Filtrar solo fallos
go test -v ./... 2>&1 | grep -A 10 "FAIL"
Ejecutar un test en modo debug¶
Generar trace¶
Troubleshooting¶
Test timeout¶
Out of memory¶
Cache de tests¶
Tests flaky¶
# Ejecutar multiples veces para detectar flakiness
for i in {1..10}; do
go test ./internal/pattern/... -run TestFlaky
if [ $? -ne 0 ]; then
echo "Failed on iteration $i"
break
fi
done