mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-15 04:31:27 +08:00
315 lines
6.6 KiB
Markdown
315 lines
6.6 KiB
Markdown
---
|
||
name: quarkus-verification
|
||
description: "Quarkus项目验证循环:构建、静态分析、带覆盖率的测试、安全扫描、原生编译以及发布或PR前的diff审查。"
|
||
origin: ECC
|
||
---
|
||
|
||
# Quarkus 验证循环
|
||
|
||
在PR前、重大变更后和部署前运行。
|
||
|
||
## 何时激活
|
||
|
||
- 为Quarkus服务打开PR前
|
||
- 大规模重构或依赖升级后
|
||
- 预发布或生产的部署前验证
|
||
- 运行完整的构建 → lint → 测试 → 安全扫描 → 原生编译流水线
|
||
- 验证测试覆盖率达到阈值(80%+)
|
||
- 测试原生镜像兼容性
|
||
|
||
## 阶段1: 构建
|
||
|
||
```bash
|
||
# Maven
|
||
mvn clean verify -DskipTests
|
||
|
||
# Gradle
|
||
./gradlew clean assemble -x test
|
||
```
|
||
|
||
构建失败时,停止并修复编译错误。
|
||
|
||
## 阶段2: 静态分析
|
||
|
||
### Checkstyle、PMD、SpotBugs(Maven)
|
||
|
||
```bash
|
||
mvn checkstyle:check pmd:check spotbugs:check
|
||
```
|
||
|
||
### SonarQube(如已配置)
|
||
|
||
```bash
|
||
mvn sonar:sonar \
|
||
-Dsonar.projectKey=my-quarkus-project \
|
||
-Dsonar.host.url=http://localhost:9000 \
|
||
-Dsonar.login=${SONAR_TOKEN}
|
||
```
|
||
|
||
### 需要解决的常见问题
|
||
|
||
- 未使用的导入或变量
|
||
- 复杂方法(高圈复杂度)
|
||
- 潜在的空指针解引用
|
||
- SpotBugs标记的安全问题
|
||
|
||
## 阶段3: 测试 + 覆盖率
|
||
|
||
```bash
|
||
# 运行所有测试
|
||
mvn clean test
|
||
|
||
# 生成覆盖率报告
|
||
mvn jacoco:report
|
||
|
||
# 强制覆盖率阈值(80%)
|
||
mvn jacoco:check
|
||
|
||
# 或使用Gradle
|
||
./gradlew test jacocoTestReport jacocoTestCoverageVerification
|
||
```
|
||
|
||
### 测试类别
|
||
|
||
#### 单元测试
|
||
使用模拟依赖测试服务逻辑:
|
||
|
||
```java
|
||
@ExtendWith(MockitoExtension.class)
|
||
class UserServiceTest {
|
||
@Mock UserRepository userRepository;
|
||
@InjectMocks UserService userService;
|
||
|
||
@Test
|
||
void createUser_validInput_returnsUser() {
|
||
var dto = new CreateUserDto("Alice", "alice@example.com");
|
||
var expected = new User();
|
||
expected.id = 1L;
|
||
expected.name = dto.name();
|
||
|
||
when(userRepository.persist(any(User.class))).thenReturn(expected);
|
||
|
||
User result = userService.create(dto);
|
||
|
||
assertThat(result.name).isEqualTo("Alice");
|
||
verify(userRepository).persist(any(User.class));
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 集成测试
|
||
使用真实数据库(Testcontainers)测试:
|
||
|
||
```java
|
||
@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端点:
|
||
|
||
```java
|
||
@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%+)
|
||
- 识别未覆盖的关键路径
|
||
|
||
## 阶段4: 安全扫描
|
||
|
||
### 依赖漏洞(Maven)
|
||
|
||
```bash
|
||
mvn org.owasp:dependency-check-maven:check
|
||
```
|
||
|
||
查看`target/dependency-check-report.html`中的CVE。
|
||
|
||
### Quarkus安全审计
|
||
|
||
```bash
|
||
# 检查有漏洞的扩展
|
||
mvn quarkus:audit
|
||
|
||
# 列出所有扩展
|
||
mvn quarkus:list-extensions
|
||
```
|
||
|
||
### 常见安全检查
|
||
|
||
- [ ] 所有密钥在环境变量中(不在代码中)
|
||
- [ ] 所有端点有输入验证
|
||
- [ ] 认证/授权已配置
|
||
- [ ] CORS正确配置
|
||
- [ ] 安全头已设置
|
||
- [ ] 密码使用BCrypt哈希
|
||
- [ ] SQL注入保护(参数化查询)
|
||
- [ ] 公共端点有速率限制
|
||
|
||
## 阶段5: 原生编译
|
||
|
||
测试GraalVM原生镜像兼容性:
|
||
|
||
```bash
|
||
# 构建原生可执行文件
|
||
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**: 使用原生库时注册JNI类
|
||
|
||
反射配置示例:
|
||
```java
|
||
@RegisterForReflection(targets = {MyDynamicClass.class})
|
||
public class ReflectionConfiguration {}
|
||
```
|
||
|
||
## 阶段6: 健康检查
|
||
|
||
```bash
|
||
# 存活检查
|
||
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
|
||
```
|
||
|
||
## 验证清单
|
||
|
||
### 代码质量
|
||
- [ ] 构建无警告通过
|
||
- [ ] 静态分析干净(无高/中问题)
|
||
- [ ] 代码遵循团队规范
|
||
- [ ] PR中无注释代码或TODO
|
||
|
||
### 测试
|
||
- [ ] 所有测试通过
|
||
- [ ] 代码覆盖率 ≥ 80%
|
||
- [ ] 使用真实数据库的集成测试
|
||
- [ ] 安全测试通过
|
||
- [ ] 性能在可接受范围内
|
||
|
||
### 安全
|
||
- [ ] 无依赖漏洞
|
||
- [ ] 认证/授权已测试
|
||
- [ ] 输入验证完成
|
||
- [ ] 源代码中无密钥
|
||
- [ ] 安全头已配置
|
||
|
||
### 部署
|
||
- [ ] 原生编译成功
|
||
- [ ] 容器镜像可构建
|
||
- [ ] 健康检查正确响应
|
||
- [ ] 目标环境配置有效
|
||
|
||
## 自动化验证脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
set -e
|
||
|
||
echo "=== 阶段1: 构建 ==="
|
||
mvn clean verify -DskipTests
|
||
|
||
echo "=== 阶段2: 静态分析 ==="
|
||
mvn checkstyle:check pmd:check spotbugs:check
|
||
|
||
echo "=== 阶段3: 测试 + 覆盖率 ==="
|
||
mvn test jacoco:report jacoco:check
|
||
|
||
echo "=== 阶段4: 安全扫描 ==="
|
||
mvn org.owasp:dependency-check-maven:check
|
||
|
||
echo "=== 阶段5: 原生编译 ==="
|
||
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"
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
- 每次PR前运行验证循环
|
||
- 在CI/CD流水线中自动化
|
||
- 立即修复问题,不积累技术债务
|
||
- 保持覆盖率在80%以上
|
||
- 定期更新依赖
|
||
- 定期测试原生编译
|
||
- 监控性能趋势
|
||
- 记录破坏性变更
|
||
- 审查安全扫描结果
|
||
- 验证每个环境的配置
|