240 lines
5.9 KiB
Markdown
240 lines
5.9 KiB
Markdown
|
|
# Coverage & Performance Implementation Plan
|
|||
|
|
|
|||
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|||
|
|
|
|||
|
|
**Goal:** 提升 ActivityService 与全量 controller 覆盖率到 0.65/0.55/0.65/0.65,并在此基础上执行 journey/performance 测试。
|
|||
|
|
|
|||
|
|
**Architecture:** 以单元测试/切片测试为主,不改动生产行为;服务层以 Mockito 构造依赖并覆盖关键分支,控制器以 `@WebMvcTest` 校验 ApiResponse 结构与错误路径;完成后提升 JaCoCo 门槛并执行完整回归与性能/旅程套件。
|
|||
|
|
|
|||
|
|
**Tech Stack:** Java 17, Spring Boot 3, JUnit 5, Mockito, Maven Surefire, JaCoCo, Testcontainers (Podman)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 1: ActivityService 校验与奖励计算覆盖
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Create: `src/test/java/com/mosquito/project/service/ActivityServiceCoverageTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 写测试覆盖 accessActivity/uploadCustomizationImage/calculateReward**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void accessActivity_shouldReject_whenNotInTargetUsers() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void uploadCustomizationImage_shouldReject_largeOrInvalidType() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void calculateReward_shouldSupportDifferentialAndCumulative() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 运行测试确认状态**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ActivityServiceCoverageTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 补齐 calculateMultiLevelReward 与 createReward 分支**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void calculateMultiLevelReward_shouldApplyDecay() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void createReward_shouldThrow_whenCouponMissingOrUnsupported() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 4: 再次运行**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ActivityServiceCoverageTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 5: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 2: ActivityService API Key 生命周期覆盖
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `src/test/java/com/mosquito/project/service/ActivityServiceCoverageTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 覆盖 generate/validate/revoke/mark/reveal 分支**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void generateApiKey_shouldSaveEncryptedAndReturnRawKey() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void validateApiKeyByPrefix_shouldUpdateLastUsedAt() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void revealApiKey_shouldRejectRevokedAndPersistRevealTime() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 运行测试**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ActivityServiceCoverageTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 3: ActivityService 统计/排行榜/图谱覆盖
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `src/test/java/com/mosquito/project/service/ActivityServiceCoverageTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 覆盖 getLeaderboard/getActivityStats/getActivityGraph 分支**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void getLeaderboard_shouldReturnEmpty_whenNoInvites() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void getActivityStats_shouldAggregateTotals() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void getActivityGraph_shouldRespectRootDepthAndLimit() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 运行测试**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ActivityServiceCoverageTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 4: ApiKeyController 覆盖补齐
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Create: `src/test/java/com/mosquito/project/controller/ApiKeyControllerTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 覆盖 create/reveal/revoke/use/validate 正常路径**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void createApiKey_shouldReturn201WithEnvelope() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void validateApiKey_shouldReturnOk() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 运行测试**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ApiKeyControllerTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 5: ShareTrackingController 覆盖补齐
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Create: `src/test/java/com/mosquito/project/controller/ShareTrackingControllerTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 覆盖 create/metrics/top-links/funnel/share-meta/register-source**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void getShareMetrics_shouldApplyDefaultTimeRange() { ... }
|
|||
|
|
|
|||
|
|
@Test
|
|||
|
|
void registerShareSource_shouldForwardChannelAndParams() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 运行测试**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=ShareTrackingControllerTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 6: UserExperience/ShortLink 控制器异常分支覆盖
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `src/test/java/com/mosquito/project/controller/UserExperienceControllerTest.java`
|
|||
|
|
- Modify: `src/test/java/com/mosquito/project/controller/ShortLinkControllerTest.java`
|
|||
|
|
|
|||
|
|
**Step 1: 补齐 poster/image 与 poster/html 异常路径**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void posterImage_shouldReturn500_whenRenderFails() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 补齐 redirect 记录点击异常分支**
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
@Test
|
|||
|
|
void redirect_shouldStillReturn302_whenClickSaveFails() { ... }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 3: 运行测试**
|
|||
|
|
|
|||
|
|
Run: `mvn -Dtest=UserExperienceControllerTest,ShortLinkControllerTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 4: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 7: 提升 JaCoCo 门槛到 0.65/0.55/0.65/0.65
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- Modify: `pom.xml`
|
|||
|
|
|
|||
|
|
**Step 1: 调整覆盖率阈值**
|
|||
|
|
|
|||
|
|
```xml
|
|||
|
|
<minimum>0.65</minimum> <!-- INSTRUCTION -->
|
|||
|
|
<minimum>0.55</minimum> <!-- BRANCH -->
|
|||
|
|
<minimum>0.65</minimum> <!-- METHOD -->
|
|||
|
|
<minimum>0.65</minimum> <!-- LINE -->
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Step 2: 构建检查**
|
|||
|
|
|
|||
|
|
Run: `mvn -q -DskipTests package`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 3: 记录变更(按指示不执行 git commit)**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 8: 全量回归(Podman)
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- None
|
|||
|
|
|
|||
|
|
**Step 1: 回归**
|
|||
|
|
|
|||
|
|
Run: `DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock" TESTCONTAINERS_RYUK_DISABLED="true" mvn -q verify`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 9: 启用并执行 journey/performance 测试
|
|||
|
|
|
|||
|
|
**Files:**
|
|||
|
|
- None
|
|||
|
|
|
|||
|
|
**Step 1: 运行 journey**
|
|||
|
|
|
|||
|
|
Run: `DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock" TESTCONTAINERS_RYUK_DISABLED="true" mvn -Djourney.test.enabled=true -Djunit.jupiter.tags.exclude= -Dtest=UserOperationJourneyTest test`
|
|||
|
|
Expected: PASS
|
|||
|
|
|
|||
|
|
**Step 2: 运行 performance**
|
|||
|
|
|
|||
|
|
Run: `DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock" TESTCONTAINERS_RYUK_DISABLED="true" mvn -Dperformance.test.enabled=true -Djunit.jupiter.tags.exclude= -Dtest=ApiPerformanceTest,SimplePerformanceTest,UltraSimplePerformanceTest test`
|
|||
|
|
Expected: PASS (如阈值过严会失败,需要记录并回报)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Notes**
|
|||
|
|
- 按用户指示,本计划不包含 git commit/branch 步骤。
|