quarkus-verification

quarkus-verification

热门

适用于 Quarkus 项目的全套验证闭环:涵盖编译构建、静态代码检查、单测与覆盖率校验、安全扫描、原生镜像(Native Image)编译以及发布/提交 PR 前的代码 Diff 审查。

24万Star
3.6万Fork
更新于 2026/8/3
SKILL.md
只读
名称
quarkus-verification
描述

适用于 Quarkus 项目的全套验证闭环:涵盖编译构建、静态代码检查、单测与覆盖率校验、安全扫描、原生镜像(Native Image)编译以及发布/提交 PR 前的代码 Diff 审查。

Quarkus 项目全校验闭环

建议在提交 PR 前、重大架构变更后以及上线部署前运行。

何时触发 / 使用场景

  • 提交 Quarkus 服务的 Pull Request (PR) 之前
  • 完成重大重构或依赖版本升级之后
  • 预发布环境(Staging)或生产环境部署前的终检
  • 需要运行完整的“构建 → 静态检查 → 测试 → 安全扫描 → 原生编译”流水线时
  • 验证单元测试覆盖率是否达标(80%+)
  • 测试 GraalVM 原生镜像(Native Image)的兼容性

阶段一:项目构建

# Maven
mvn clean verify -DskipTests

# Gradle
./gradlew clean assemble -x test

若构建失败,请先彻底修复编译错误再继续后续步骤。

阶段二:静态代码分析

Checkstyle, PMD, SpotBugs (Maven)

mvn checkstyle:check pmd:check spotbugs:check

SonarQube(如已配置)

mvn sonar:sonar \
  -Dsonar.projectKey=my-quarkus-project \
  -Dsonar.host.url=http://localhost:9000 \
  -Dsonar.login=${SONAR_TOKEN}

需要重点关注的问题

  • 未使用的 import 引用或变量
  • 过度复杂的函数/方法(圈复杂度过高)
  • 潜在的空指针解引用风险
  • SpotBugs 标记出的潜在安全隐患

阶段三:测试与覆盖率校验

# 运行所有测试
mvn clean test

# 生成覆盖率报告
mvn jacoco:report

# 强制校验覆盖率门槛(80%)
mvn jacoco:check

# 或使用 Gradle
./gradlew test jacocoTestReport jacocoTestCoverageVerification

测试分类

单元测试

使用 Mock 依赖测试 Service 业务逻辑:

@ExtendWith(MockitoExtension.class)
class UserServiceTest {
  @Mock UserRepository userRepository;
  @InjectMocks UserService userService;

  @Test
  void createUser_validInput_returnsUser() {
    var dto = new CreateUserDto("Alice", "alice@example.com");

    // Panache 的 persist() 返回 void,使用 doNothing + verify 验证
    doNothing().when(userRepository).persist(any(User.class));

    User result = userService.create(dto);

    assertThat(result.name).isEqualTo("Alice");
    verify(userRepository).persist(any(User.class));
  }
}
集成测试

结合真实数据库进行测试(基于 Testcontainers):

@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");
  }
}
API 接口测试

使用 REST Assured 测试 REST 接口:

@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);
  }
}

覆盖率报告

查看 target/site/jacoco/index.html 获取详细的覆盖率报告:

  • 总体行覆盖率(目标:80%+)
  • 分支覆盖率(目标:70%+)
  • 排查未覆盖到的核心业务路径

阶段四:安全扫描

依赖漏洞扫描(Maven)

mvn org.owasp:dependency-check-maven:check

检查 target/dependency-check-report.html 中的 CVE 漏洞列表。

Quarkus 安全审计

# 检查存在漏洞的扩展插件
mvn quarkus:audit

# 列出所有使用的扩展插件
mvn quarkus:list-extensions

OWASP ZAP(API 安全漏洞测试)

docker run -t owasp/zap2docker-stable zap-api-scan.py \
  -t http://localhost:8080/q/openapi \
  -f openapi

核心安全检查清单

  • [ ] 所有敏感凭据(Secrets)均配置在环境变量中,严禁硬编码
  • [ ] 所有 API 接口均已配置输入参数校验
  • [ ] 已配置身份认证与权限授权
  • [ ] CORS 跨域策略已按需合理配置
  • [ ] 已正确配置安全 HTTP Header
  • [ ] 密码使用 BCrypt 算法哈希加密
  • [ ] 具备 SQL 注入防护(使用参数化查询)
  • [ ] 公开接口已配置限流保护

阶段五:原生镜像编译

校验 GraalVM 原生镜像(Native Image)的兼容性:

# 编译原生可执行文件
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

原生镜像排坑指南

常见问题及应对策略:

  • 反射问题(Reflection):为需要动态调用的类添加反射配置
  • 静态资源(Resources):通过 quarkus.native.resources.includes 显式打包静态资源文件
  • JNI 调用:如果使用了 Native 库,需注册对应的 JNI 类

反射配置示例:

@RegisterForReflection(targets = {MyDynamicClass.class})
public class ReflectionConfiguration {}

阶段六:性能测试

使用 K6 进行压测

// load-test.js
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

核心监控指标

  • 响应时间(p50、p95、p99 延迟分位数)
  • 吞吐量(RPS / 每秒请求数)
  • 错误率
  • 内存占用
  • CPU 使用率

阶段七:健康检查

# 存活探针(Liveness)
curl http://localhost:8080/q/health/live

# 就绪探针(Readiness)
curl http://localhost:8080/q/health/ready

# 全量健康状态
curl http://localhost:8080/q/health

# 指标数据(如已启用)
curl http://localhost:8080/q/metrics

预期响应结果:

{
  "status": "UP",
  "checks": [
    {
      "name": "Database connection",
      "status": "UP"
    }
  ]
}

阶段八:容器镜像构建

# 构建容器镜像
mvn package -Dquarkus.container-image.build=true

# 或指定 Registry 构建
mvn package \
  -Dquarkus.container-image.build=true \
  -Dquarkus.container-image.registry=docker.io \
  -Dquarkus.container-image.group=myorg \
  -Dquarkus.container-image.tag=1.0.0

# 测试容器运行
docker run -p 8080:8080 myorg/my-quarkus-app:1.0.0

镜像安全扫描

# Trivy
trivy image myorg/my-quarkus-app:1.0.0

# Grype
grype myorg/my-quarkus-app:1.0.0

阶段九:配置合法性校验

# 检查所有配置属性
mvn quarkus:info

# 查看所有配置源
curl http://localhost:8080/q/dev/io.quarkus.quarkus-vertx-http/config

分环境配置检查事项

  • [ ] 数据库连接 URL 已按各环境分别正确配置
  • [ ] 密钥与敏感配置已外部化(如注入 Vault 或环境变量)
  • [ ] 日志级别(Logging level)配置合理
  • [ ] CORS 允许的 Origin 域已设置准确
  • [ ] 限流规则已启用
  • [ ] 监控与链路追踪(Tracing)功能已开启

阶段十:文档审核

  • [ ] OpenAPI/Swagger 接口文档保持最新(访问 /q/swagger-ui 查验)
  • [ ] README 文档清晰指引了环境准备与搭建流程
  • [ ] API 变动说明已更新
  • [ ] 若包含破坏性变更(Breaking changes),必须补充迁移指南
  • [ ] 相关的配置项参数均已在文档中明确说明

导出 OpenAPI 描述文件:

curl http://localhost:8080/q/openapi -o openapi.json

全校验检查清单

代码质量

  • [ ] 构建顺利通过,且无警告信息
  • [ ] 静态分析清零(无高危/中危级别报告)
  • [ ] 代码严格遵循团队开发规范
  • [ ] PR 中无废弃的注释代码或未完成的 TODO 标记

测试

  • [ ] 所有测试套件全部通过
  • [ ] 代码覆盖率 ≥ 80%
  • [ ] 已通过基于真实数据库的集成测试
  • [ ] 安全相关测试项全量通过
  • [ ] 性能指标表现控制在允许范围内

安全

  • [ ] 无已知依赖项安全漏洞
  • [ ] 身份验证和鉴权逻辑均经过充分测试
  • [ ] 所有的输入数据均设置了严密的校验机制
  • [ ] 源码中未包含任何明文硬编码密钥
  • [ ] 安全 Header 已配置完毕

部署

  • [ ] 原生镜像构建无报错
  • [ ] 容器镜像能够成功构建
  • [ ] 健康检查端点(Health check)正常打通
  • [ ] 目标部署环境下的配置验证有效

原生镜像

  • [ ] 原生二进制文件成功编译
  • [ ] 原生测试正常通过
  • [ ] 应用启动耗时小于 100ms
  • [ ] 运行时内存占用控制在预期之内

自动化校验脚本

#!/bin/bash
set -e

echo "=== 阶段一:项目构建 ==="
mvn clean verify -DskipTests

echo "=== 阶段二:静态代码分析 ==="
mvn checkstyle:check pmd:check spotbugs:check

echo "=== 阶段三:测试与覆盖率校验 ==="
mvn test jacoco:report jacoco:check

echo "=== 阶段四:安全扫描 ==="
mvn org.owasp:dependency-check-maven:check

echo "=== 阶段五:原生镜像编译 ==="
mvn package -Dnative -Dquarkus.native.container-build=true

echo "=== 全阶段验证完毕 ==="
echo "请复核相关报告:"
echo "  - 覆盖率报告: target/site/jacoco/index.html"
echo "  - 安全扫描报告: target/dependency-check-report.html"
echo "  - 原生镜像程序: target/*-runner"

CI/CD 流水线集成

GitHub Actions 示例

name: Verification

on: [push, pull_request]

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 21
        uses: actions/setup-java@v3
        with:
          java-version: '21'
          distribution: 'temurin'

      - name: Cache Maven packages
        uses: actions/cache@v3
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}

      - name: Build
        run: mvn clean verify -DskipTests

      - name: Test with Coverage
        run: mvn test jacoco:report jacoco:check

      - name: Security Scan
        run: mvn org.owasp:dependency-check-maven:check

      - name: Upload Coverage
        uses: codecov/codecov-action@v3
        with:
          files: target/site/jacoco/jacoco.xml

最佳实践

  • 每次提交 PR 前必须跑一遍全量验证闭环
  • 在 CI/CD 流水线中实现全自动校验
  • 发现问题立即修复,切勿搁置积累技术债务
  • 坚守覆盖率 80% 以上的质量底线
  • 定期更新和维护依赖版本
  • 定期执行 Native 原生镜像编译测试
  • 持续观察和跟踪性能趋势
  • 凡涉及 Breaking Changes 必须配套健全的变动文档
  • 仔细复核安全扫描出来的报告细节
  • 严格校验各环境下的配置生效情况