| name | quarkus-verification |
| description | Bucle de verificación para proyectos Quarkus: build, análisis estático, pruebas con cobertura, escaneos de seguridad, compilación nativa y revisión de diff antes del lanzamiento o PR. |
| origin | ECC |
Bucle de Verificación Quarkus
Ejecutar antes de PRs, después de cambios importantes y antes del despliegue.
Cuándo Activar
- Antes de abrir un pull request para un servicio Quarkus
- Después de refactorizaciones importantes o actualizaciones de dependencias
- Verificación previa al despliegue para staging o producción
- Ejecutar el pipeline completo de build → lint → test → escaneo de seguridad → compilación nativa
- Validar que la cobertura de pruebas cumpla los umbrales (80%+)
- Probar compatibilidad con imagen nativa
Fase 1: Build
mvn clean verify -DskipTests
./gradlew clean assemble -x test
Si el build falla, detener y corregir errores de compilación.
Fase 2: Análisis Estático
Checkstyle, PMD, SpotBugs (Maven)
mvn checkstyle:check pmd:check spotbugs:check
SonarQube (si está configurado)
mvn sonar:sonar \
-Dsonar.projectKey=my-quarkus-project \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=${SONAR_TOKEN}
Problemas Comunes a Resolver
- Importaciones o variables sin usar
- Métodos complejos (alta complejidad ciclomática)
- Posibles desreferencias de puntero nulo
- Problemas de seguridad detectados por SpotBugs
Fase 3: Pruebas + Cobertura
mvn clean test
mvn jacoco:report
mvn jacoco:check
./gradlew test jacocoTestReport jacocoTestCoverageVerification
Categorías de Prueba
Pruebas Unitarias
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock UserRepository userRepository;
@InjectMocks UserService userService;
@Test
void createUser_validInput_returnsUser() {
var dto = new CreateUserDto("Alice", "alice@example.com");
doNothing().when(userRepository).persist(any(User.class));
User result = userService.create(dto);
assertThat(result.name).isEqualTo("Alice");
verify(userRepository).persist(any(User.class));
}
}
Pruebas de Integración
@QuarkusTest
@QuarkusTestResource(PostgresTestResource.class)
class UserRepositoryIntegrationTest {
@Inject
UserRepository userRepository;
@Test
@Transactional
void findByEmail_existingUser_returnsUser() {
User user = new User();
user.name = "Alice";
user.email = "alice@example.com";
userRepository.persist(user);
Optional<User> found = userRepository.findByEmail("alice@example.com");
assertThat(found).isPresent();
assertThat(found.get().name).isEqualTo("Alice");
}
}
Pruebas de API
@QuarkusTest
class UserResourceTest {
@Test
void createUser_validInput_returns201() {
given()
.contentType(ContentType.JSON)
.body("""
{"name": "Alice", "email": "alice@example.com"}
""")
.when().post("/api/users")
.then()
.statusCode(201)
.body("name", equalTo("Alice"));
}
@Test
void createUser_invalidEmail_returns400() {
given()
.contentType(ContentType.JSON)
.body("""
{"name": "Alice", "email": "invalid"}
""")
.when().post("/api/users")
.then()
.statusCode(400);
}
}
Reporte de Cobertura
Verificar target/site/jacoco/index.html para cobertura detallada:
- Cobertura de líneas total (objetivo: 80%+)
- Cobertura de ramas (objetivo: 70%+)
- Identificar rutas críticas sin cobertura
Fase 4: Escaneo de Seguridad
Vulnerabilidades de Dependencias (Maven)
mvn org.owasp:dependency-check-maven:check
Revisar target/dependency-check-report.html para CVEs.
Auditoría de Seguridad Quarkus
mvn quarkus:audit
mvn quarkus:list-extensions
OWASP ZAP (Pruebas de Seguridad de API)
docker run -t owasp/zap2docker-stable zap-api-scan.py \
-t http://localhost:8080/q/openapi \
-f openapi
Verificaciones de Seguridad Comunes
Fase 5: Compilación Nativa
Probar compatibilidad de imagen nativa GraalVM:
mvn package -Dnative
mvn package -Dnative -Dquarkus.native.container-build=true
./target/*-runner
curl http://localhost:8080/q/health/live
curl http://localhost:8080/q/health/ready
Solución de Problemas de Imagen Nativa
Problemas comunes:
- Reflexión: Agregar config de reflexión para clases dinámicas
- Recursos: Incluir recursos con
quarkus.native.resources.includes
- JNI: Registrar clases JNI si se usan bibliotecas nativas
Ejemplo de configuración de reflexión:
@RegisterForReflection(targets = {MyDynamicClass.class})
public class ReflectionConfiguration {}
Fase 6: Pruebas de Rendimiento
Prueba de Carga con K6
import http from 'k6/http';
import { check } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 50 },
{ duration: '1m', target: 100 },
{ duration: '30s', target: 0 },
],
};
export default function () {
const res = http.get('http://localhost:8080/api/markets');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
}
k6 run load-test.js
Fase 7: Health Checks
curl http://localhost:8080/q/health/live
curl http://localhost:8080/q/health/ready
curl http://localhost:8080/q/health
curl http://localhost:8080/q/metrics
Fase 8: Build de Imagen de Contenedor
mvn package -Dquarkus.container-image.build=true
trivy image myorg/my-quarkus-app:1.0.0
grype myorg/my-quarkus-app:1.0.0
Fase 9: Validación de Configuración
mvn quarkus:info
Verificaciones por Entorno
Fase 10: Revisión de Documentación
Generar especificación OpenAPI:
curl http://localhost:8080/q/openapi -o openapi.json
Lista de Verificación
Calidad del Código
Pruebas
Seguridad
Despliegue
Script de Verificación Automatizado
#!/bin/bash
set -e
echo "=== Fase 1: Build ==="
mvn clean verify -DskipTests
echo "=== Fase 2: Análisis Estático ==="
mvn checkstyle:check pmd:check spotbugs:check
echo "=== Fase 3: Pruebas + Cobertura ==="
mvn test jacoco:report jacoco:check
echo "=== Fase 4: Escaneo de Seguridad ==="
mvn org.owasp:dependency-check-maven:check
echo "=== Fase 5: Compilación Nativa ==="
mvn package -Dnative -Dquarkus.native.container-build=true
echo "=== Todas las Fases Completadas ==="
echo "Revisar reportes:"
echo " - Cobertura: target/site/jacoco/index.html"
echo " - Seguridad: target/dependency-check-report.html"
Buenas Prácticas
- Ejecutar el bucle de verificación antes de cada PR
- Automatizar en el pipeline CI/CD
- Corregir problemas inmediatamente; no acumular deuda técnica
- Mantener cobertura por encima del 80%
- Actualizar dependencias regularmente
- Probar compilación nativa periódicamente
- Monitorear tendencias de rendimiento
- Documentar cambios disruptivos