@xulthekl/team-flow 0.32.2 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.claude/always/phase-guard.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/.cursor-plugin/marketplace.json +1 -1
  6. package/.cursor-plugin/plugin.json +1 -1
  7. package/.github/plugin/marketplace.json +2 -2
  8. package/AGENTS.md +2 -0
  9. package/CHANGELOG.md +56 -0
  10. package/CONTRIBUTING.md +44 -0
  11. package/GEMINI.md +1 -1
  12. package/INSTALL.md +1 -1
  13. package/README.md +1 -1
  14. package/agents/architecture-design.md +1 -34
  15. package/agents/architecture-reviewer.md +1 -42
  16. package/agents/bug-investigator.md +1 -37
  17. package/agents/build-executor.md +1 -22
  18. package/agents/change-split-auditor.md +1 -42
  19. package/agents/code-reviewer.md +1 -42
  20. package/agents/contract-builder.md +1 -22
  21. package/agents/cross-change-consistency-checker.md +2 -43
  22. package/agents/need-explorer.md +1 -22
  23. package/agents/prd-completeness-reviewer.md +1 -47
  24. package/agents/prototype-builder.md +1 -41
  25. package/agents/prototype-env-scout.md +1 -26
  26. package/agents/prototype-reviewer.md +1 -41
  27. package/agents/release-archivist.md +1 -22
  28. package/agents/spec-writer.md +1 -22
  29. package/docs/README_en.md +1 -1
  30. package/docs/solutions/INDEX.md +1 -0
  31. package/docs/solutions/cross-phase/2026-08-04-no-summary.md +17 -0
  32. package/gemini-extension.json +1 -1
  33. package/hooks/session-start +2 -2
  34. package/llms.txt +1 -1
  35. package/package.json +5 -4
  36. package/plugin.json +1 -1
  37. package/scripts/lib/conventions-generator.mjs +350 -0
  38. package/scripts/lib/test-record.mjs +65 -2
  39. package/skills/e2e/SKILL.md +1 -1
  40. package/skills/test-strategy/SKILL.md +38 -1
  41. package/skills/test-strategy/references/integration-test-contracts.md +237 -0
  42. package/skills/test-strategy/references/integration-test-isolation.md +346 -0
  43. package/skills/test-strategy/references/test-quality-rules.md +292 -0
  44. package/skills/workflow-bootstrap/SKILL.md +40 -3
  45. package/templates/agent-template.md +41 -0
  46. package/templates/conventions/_manifest.json +39 -0
  47. package/templates/conventions/glaf4-compliant/java-testing.md +367 -0
  48. package/templates/conventions/glaf4-compliant/spring-patterns.md +415 -0
  49. package/templates/conventions/js-testing.md +261 -0
  50. package/templates/conventions/python-testing.md +333 -0
@@ -0,0 +1,237 @@
1
+ # Integration Test Contracts(集成测试契约)
2
+
3
+ > 来源:glaf4-test social-test-contracts.md 的通用模式(v0.13 §58)
4
+ > 用途:集成测试的组织方法论,contract-builder 生成矩阵时参考
5
+
6
+ ---
7
+
8
+ ## 一、核心概念
9
+
10
+ **社交测试(Social Test)**:跨类/跨层交互的测试,需要声明式契约来明确测试边界和依赖。
11
+
12
+ **契约的作用**:
13
+ - 明确测试的输入和输出
14
+ - 声明依赖的真实/mock/stub
15
+ - 定义测试隔离和清理策略
16
+ - 确保测试可重复和可维护
17
+
18
+ ---
19
+
20
+ ## 二、五种契约类型
21
+
22
+ ### 1. 入口契约(Entry Contract)
23
+
24
+ **定义**:系统边界入口声明
25
+
26
+ **内容**:
27
+ - API 端点(URL、HTTP 方法、请求格式)
28
+ - 消息队列(exchange、routingKey、消息格式)
29
+ - 定时任务(cron 表达式、触发条件)
30
+
31
+ **示例**:
32
+ ```markdown
33
+ ## 入口契约
34
+
35
+ - API: `POST /api/users`
36
+ - Content-Type: application/json
37
+ - 请求体: `{ "name": "string", "email": "string" }`
38
+ - 认证: Bearer Token
39
+ ```
40
+
41
+ ### 2. 协作者契约(Collaborator Contract)
42
+
43
+ **定义**:依赖分级声明
44
+
45
+ **分级**:
46
+ | 级别 | 说明 | 使用场景 |
47
+ |------|------|---------|
48
+ | **真实(Real)** | 使用真实实现 | Repository 层、内部 Service |
49
+ | **Mock** | 使用 mock 框架创建 | 外部 API、第三方服务 |
50
+ | **Stub** | 使用固定返回值 | 简单依赖、配置服务 |
51
+
52
+ **示例**:
53
+ ```markdown
54
+ ## 协作者契约
55
+
56
+ | 协作者 | 级别 | 理由 |
57
+ |--------|------|------|
58
+ | UserRepository | Real | 测试真实持久化逻辑 |
59
+ | EmailService | Mock | 外部服务,避免真实发送 |
60
+ | ConfigService | Stub | 返回固定配置值 |
61
+ ```
62
+
63
+ ### 3. 数据契约(Data Contract)
64
+
65
+ **定义**:测试数据规格声明
66
+
67
+ **内容**:
68
+ - 输入数据格式和约束
69
+ - 输出数据格式和验证点
70
+ - 测试数据准备方式
71
+
72
+ **示例**:
73
+ ```markdown
74
+ ## 数据契约
75
+
76
+ ### 输入
77
+ - name: string, 1-50 字符
78
+ - email: string, 有效邮箱格式
79
+
80
+ ### 输出
81
+ - User 对象,包含 id、name、email、createdAt
82
+ - id: 雪花算法生成,非空
83
+ - createdAt: 当前时间,非空
84
+
85
+ ### 准备方式
86
+ - 使用 Builder 模式构建测试数据
87
+ - 每个测试独立数据,避免共享状态
88
+ ```
89
+
90
+ ### 4. 中间件契约(Middleware Contract)
91
+
92
+ **定义**:基础设施交互规格
93
+
94
+ **内容**:
95
+ | 中间件 | 交互方式 | 测试策略 |
96
+ |--------|---------|---------|
97
+ | **数据库** | SQL 查询/写入 | H2 内存库 / @Transactional 回滚 |
98
+ | **消息队列** | 发送/接收消息 | rabbitmq-mock / embedded broker |
99
+ | **缓存** | 读写 Redis | embedded-redis / mock |
100
+ | **外部 HTTP** | 调用第三方 API | MockWebServer / WireMock |
101
+
102
+ **示例**:
103
+ ```markdown
104
+ ## 中间件契约
105
+
106
+ | 中间件 | 交互 | 测试策略 |
107
+ |--------|------|---------|
108
+ | MySQL | INSERT/SELECT | H2 内存库,@Transactional 回滚 |
109
+ | RabbitMQ | 发送用户创建事件 | rabbitmq-mock |
110
+ | Redis | 缓存用户信息 | embedded-redis (port 6378) |
111
+ | 支付网关 | 调用支付 API | MockWebServer |
112
+ ```
113
+
114
+ ### 5. 清理契约(Cleanup Contract)
115
+
116
+ **定义**:测试隔离清理声明
117
+
118
+ **原则**:
119
+ - 每个测试独立,不共享状态
120
+ - 测试后清理所有创建的数据
121
+ - 异步操作需要等待完成
122
+
123
+ **策略**:
124
+ | 场景 | 清理方式 |
125
+ |------|---------|
126
+ | **同步操作** | @Transactional 自动回滚 |
127
+ | **异步操作** | 手动清理(@AfterEach) |
128
+ | **消息队列** | 清空队列 |
129
+ | **缓存** | 清空 key |
130
+
131
+ **示例**:
132
+ ```markdown
133
+ ## 清理契约
134
+
135
+ - 数据库:@Transactional 自动回滚
136
+ - 消息队列:@AfterEach 清空队列
137
+ - 缓存:@AfterEach 清空测试 key
138
+ - ThreadLocal:@AfterEach 清理 TraceIdHolder
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 三、契约声明格式
144
+
145
+ 在 test-matrix.md 的集成测试 case 中,使用以下格式声明契约:
146
+
147
+ ```markdown
148
+ | ID | work_mode | test_tier | design_method | description | priority | mock |
149
+ |----|-----------|-----------|---------------|-------------|----------|------|
150
+ | TC-010 | TDD | integration | equivalence | [contract] 创建用户:POST /api/users | P0 | entry:POST /api/users, collaborator:EmailService=Mock, data:User{name,email}, cleanup:@Transactional |
151
+ ```
152
+
153
+ **字段说明**:
154
+ - `entry`: 入口契约
155
+ - `collaborator`: 协作者契约(Real/Mock/Stub)
156
+ - `data`: 数据契约
157
+ - `middleware`: 中间件契约
158
+ - `cleanup`: 清理契约
159
+
160
+ ---
161
+
162
+ ## 四、矩阵生成指南
163
+
164
+ ### contract-builder 生成集成测试矩阵时:
165
+
166
+ 1. **识别入口**:从 specs/*.md 中提取 API 端点、消息队列、定时任务
167
+ 2. **分析依赖**:从代码中识别所有依赖,按真实/mock/stub 分级
168
+ 3. **定义数据**:明确输入输出数据格式
169
+ 4. **选择中间件**:识别涉及的基础设施,选择测试策略
170
+ 5. **设计清理**:根据操作类型(同步/异步)设计清理策略
171
+
172
+ ### 示例:用户注册功能
173
+
174
+ ```markdown
175
+ ## 集成测试矩阵
176
+
177
+ ### TC-010: 创建用户成功
178
+ - 入口:POST /api/users
179
+ - 协作者:UserRepository=Real, EmailService=Mock
180
+ - 数据:{name:"John", email:"john@example.com"}
181
+ - 中间件:MySQL=H2
182
+ - 清理:@Transactional
183
+
184
+ ### TC-011: 创建用户失败(邮箱已存在)
185
+ - 入口:POST /api/users
186
+ - 协作者:UserRepository=Real(预先插入重复数据)
187
+ - 数据:{name:"John", email:"existing@example.com"}
188
+ - 中间件:MySQL=H2
189
+ - 清理:@Transactional
190
+ - 预期:409 Conflict
191
+
192
+ ### TC-012: 创建用户后发送欢迎邮件
193
+ - 入口:POST /api/users
194
+ - 协作者:UserRepository=Real, EmailService=Mock
195
+ - 数据:{name:"John", email:"john@example.com"}
196
+ - 中间件:MySQL=H2, RabbitMQ=rabbitmq-mock
197
+ - 清理:@Transactional + 清空队列
198
+ - 验证:EmailService.sendWelcomeEmail() 被调用
199
+ ```
200
+
201
+ ---
202
+
203
+ ## 五、最佳实践
204
+
205
+ ### 1. 契约最小化
206
+ - 只声明必要的契约
207
+ - 避免过度 mock(内部依赖尽量用真实实现)
208
+
209
+ ### 2. 契约可读性
210
+ - 使用表格格式,清晰易读
211
+ - 提供理由说明(为什么选择 Mock/Stub)
212
+
213
+ ### 3. 契约可维护性
214
+ - 契约与测试代码同步更新
215
+ - 定期审查契约的有效性
216
+
217
+ ### 4. 契约复用
218
+ - 相似功能的契约可以复用
219
+ - 提取公共契约模板
220
+
221
+ ---
222
+
223
+ ## 六、与 test-strategy 的关系
224
+
225
+ 集成测试契约是 test-strategy §1(Design Method 选择规则)的补充:
226
+ - **基础级**(equivalence/boundary/error):适用于所有测试
227
+ - **扩展级**(path/state/exception/reject):条件触发
228
+ - **高级**(permission/idempotency/concurrency/contract):场景触发
229
+ - **contract**:跨模块/跨服务接口契约,需要声明集成测试契约
230
+
231
+ ---
232
+
233
+ ## 变更记录
234
+
235
+ | 日期 | 版本 | 变更内容 |
236
+ |------|------|---------|
237
+ | 2026-08-04 | v1.0 | 从 glaf4-test social-test-contracts.md 抽取通用模式 |
@@ -0,0 +1,346 @@
1
+ # Integration Test Isolation(集成测试隔离分级)
2
+
3
+ > 来源:glaf4-test h2-rabbitmq-redis.md 的隔离策略(v0.13 §59)
4
+ > 用途:集成测试的分层策略,write-integration-worker 参考
5
+
6
+ ---
7
+
8
+ ## 一、核心原则
9
+
10
+ **测试隔离**:每个测试独立运行,不依赖其他测试的状态,不污染共享资源。
11
+
12
+ **隔离级别**:
13
+ - **L1:进程内隔离**(最严格):H2、embedded-redis、rabbitmq-mock
14
+ - **L2:事务隔离**:@Transactional 自动回滚
15
+ - **L3:手动清理**:@AfterEach 手动清理资源
16
+ - **L4:无隔离**(最宽松):共享真实基础设施(仅限开发环境)
17
+
18
+ ---
19
+
20
+ ## 二、基础设施隔离策略
21
+
22
+ ### 1. 数据库(MySQL/PostgreSQL)
23
+
24
+ | 策略 | 适用场景 | 实现方式 | 优缺点 |
25
+ |------|---------|---------|--------|
26
+ | **H2 内存库** | Repository 层测试 | `@DataJpaTest` + H2 依赖 | ✅ 快速、隔离 ❌ SQL 兼容性差异 |
27
+ | **@Transactional** | Service 层测试 | 测试类加 `@Transactional` | ✅ 自动回滚 ❌ 异步操作不适用 |
28
+ | **Testcontainers** | 需要真实数据库 | Docker 容器 | ✅ 真实环境 ❌ 慢、需要 Docker |
29
+
30
+ **推荐**:
31
+ - Repository 层:H2 内存库
32
+ - Service 层:@Transactional(同步操作)
33
+ - API 层:@Transactional 或 Testcontainers
34
+
35
+ **H2 配置示例**:
36
+ ```yaml
37
+ # application-test.yml
38
+ spring:
39
+ datasource:
40
+ url: jdbc:h2:mem:testdb;MODE=MySQL;DATABASE_TO_UPPER=false
41
+ driver-class-name: org.h2.Driver
42
+ jpa:
43
+ hibernate:
44
+ ddl-auto: create-drop
45
+ ```
46
+
47
+ ### 2. 消息队列(RabbitMQ/Kafka)
48
+
49
+ | 策略 | 适用场景 | 实现方式 | 优缺点 |
50
+ |------|---------|---------|--------|
51
+ | **rabbitmq-mock** | MQ 生产者测试 | `MockConnectionFactory` | ✅ 快速、隔离 ❌ 不测试真实 MQ |
52
+ | **embedded broker** | MQ 消费者测试 | embedded-rabbitmq | ✅ 真实协议 ❌ 慢、资源占用 |
53
+ | **Testcontainers** | 端到端测试 | Docker 容器 | ✅ 真实环境 ❌ 慢、需要 Docker |
54
+
55
+ **推荐**:
56
+ - 生产者:rabbitmq-mock
57
+ - 消费者:embedded broker 或 Testcontainers
58
+
59
+ **rabbitmq-mock 配置示例**:
60
+ ```java
61
+ @Configuration
62
+ public class RabbitMockConfig {
63
+ @Bean
64
+ public ConnectionFactory connectionFactory() {
65
+ return new MockConnectionFactory();
66
+ }
67
+ }
68
+ ```
69
+
70
+ ### 3. 缓存(Redis)
71
+
72
+ | 策略 | 适用场景 | 实现方式 | 优缺点 |
73
+ |------|---------|---------|--------|
74
+ | **embedded-redis** | 缓存测试 | embedded-redis(port 6378) | ✅ 真实协议 ❌ ARM64 兼容问题 |
75
+ | **mock** | 简单缓存逻辑 | Mockito mock | ✅ 快速 ❌ 不测试真实 Redis |
76
+ | **Testcontainers** | 端到端测试 | Docker 容器 | ✅ 真实环境 ❌ 慢、需要 Docker |
77
+
78
+ **推荐**:
79
+ - 简单缓存逻辑:mock
80
+ - 复杂缓存逻辑:embedded-redis
81
+
82
+ **embedded-redis 配置示例**:
83
+ ```java
84
+ @Configuration
85
+ public class RedisTestConfig {
86
+ @Bean
87
+ public RedisServer redisServer() throws IOException {
88
+ RedisServer server = new RedisServer(6378);
89
+ server.start();
90
+ return server;
91
+ }
92
+ }
93
+ ```
94
+
95
+ ### 4. 外部 HTTP(第三方 API)
96
+
97
+ | 策略 | 适用场景 | 实现方式 | 优缺点 |
98
+ |------|---------|---------|--------|
99
+ | **MockWebServer** | HTTP 客户端测试 | OkHttp MockWebServer | ✅ 真实 HTTP 协议 ❌ 只测试客户端 |
100
+ | **WireMock** | 复杂 API 模拟 | WireMock | ✅ 强大的模拟能力 ❌ 学习成本 |
101
+ | **@MockBean** | Spring Cloud Feign | Mockito mock | ✅ 简单 ❌ 不测试真实 HTTP |
102
+
103
+ **推荐**:
104
+ - 简单 HTTP 客户端:MockWebServer
105
+ - 复杂 API 模拟:WireMock
106
+ - Feign 客户端:@MockBean
107
+
108
+ **MockWebServer 配置示例**:
109
+ ```java
110
+ @Test
111
+ void testCallExternalApi() throws Exception {
112
+ MockWebServer server = new MockWebServer();
113
+ server.enqueue(new MockResponse()
114
+ .setBody("{\"status\":\"ok\"}")
115
+ .setHeader("Content-Type", "application/json"));
116
+
117
+ // 调用被测方法
118
+ String result = externalService.callApi();
119
+
120
+ // 验证请求
121
+ RecordedRequest request = server.takeRequest();
122
+ assertEquals("/api/data", request.getPath());
123
+ assertEquals("ok", result);
124
+
125
+ server.shutdown();
126
+ }
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 三、分层隔离策略
132
+
133
+ ### Repository 层
134
+
135
+ **策略**:H2 内存库 + @Transactional
136
+
137
+ **理由**:
138
+ - Repository 层只测试 SQL 和映射逻辑
139
+ - H2 内存库提供快速、隔离的测试环境
140
+ - @Transactional 确保测试后数据回滚
141
+
142
+ **示例**:
143
+ ```java
144
+ @DataJpaTest
145
+ @Transactional
146
+ class UserRepositoryTest {
147
+ @Autowired
148
+ private UserRepository userRepository;
149
+
150
+ @Test
151
+ void testFindByEmail() {
152
+ // Arrange
153
+ User user = new User("John", "john@example.com");
154
+ userRepository.save(user);
155
+
156
+ // Act
157
+ Optional<User> found = userRepository.findByEmail("john@example.com");
158
+
159
+ // Assert
160
+ assertTrue(found.isPresent());
161
+ assertEquals("John", found.get().getName());
162
+ }
163
+ // 测试结束后自动回滚
164
+ }
165
+ ```
166
+
167
+ ### Service 层
168
+
169
+ **策略**:@Transactional(同步操作)或手动清理(异步操作)
170
+
171
+ **理由**:
172
+ - Service 层测试业务逻辑,需要真实依赖
173
+ - 同步操作用 @Transactional 自动回滚
174
+ - 异步操作需要手动清理(消息队列、缓存)
175
+
176
+ **示例(同步)**:
177
+ ```java
178
+ @SpringBootTest
179
+ @Transactional
180
+ class UserServiceTest {
181
+ @Autowired
182
+ private UserService userService;
183
+
184
+ @Autowired
185
+ private UserRepository userRepository;
186
+
187
+ @Test
188
+ void testCreateUser() {
189
+ // Arrange
190
+ CreateUserRequest request = new CreateUserRequest("John", "john@example.com");
191
+
192
+ // Act
193
+ User user = userService.createUser(request);
194
+
195
+ // Assert
196
+ assertNotNull(user.getId());
197
+ assertEquals("John", user.getName());
198
+ }
199
+ // 测试结束后自动回滚
200
+ }
201
+ ```
202
+
203
+ **示例(异步)**:
204
+ ```java
205
+ @SpringBootTest
206
+ class UserServiceAsyncTest {
207
+ @Autowired
208
+ private UserService userService;
209
+
210
+ @Autowired
211
+ private RabbitTemplate rabbitTemplate;
212
+
213
+ @AfterEach
214
+ void cleanup() {
215
+ // 手动清空消息队列
216
+ rabbitTemplate.execute(channel -> {
217
+ channel.queuePurge("user-events");
218
+ return null;
219
+ });
220
+ }
221
+
222
+ @Test
223
+ void testCreateUserSendsEvent() {
224
+ // Arrange
225
+ CreateUserRequest request = new CreateUserRequest("John", "john@example.com");
226
+
227
+ // Act
228
+ User user = userService.createUser(request);
229
+
230
+ // Assert
231
+ assertNotNull(user.getId());
232
+
233
+ // 验证消息发送
234
+ Message message = rabbitTemplate.receive("user-events", 1000);
235
+ assertNotNull(message);
236
+ }
237
+ }
238
+ ```
239
+
240
+ ### API 层
241
+
242
+ **策略**:MockMvc + @Transactional 或 Testcontainers
243
+
244
+ **理由**:
245
+ - API 层测试 HTTP 请求和响应
246
+ - 使用 MockMvc 模拟 HTTP 请求
247
+ - 数据库用 @Transactional 或 Testcontainers
248
+
249
+ **示例**:
250
+ ```java
251
+ @WebMvcTest(UserController.class)
252
+ @Transactional
253
+ class UserControllerTest {
254
+ @Autowired
255
+ private MockMvc mockMvc;
256
+
257
+ @MockBean
258
+ private UserService userService;
259
+
260
+ @Test
261
+ void testCreateUser() throws Exception {
262
+ // Arrange
263
+ User user = new User(1L, "John", "john@example.com");
264
+ when(userService.createUser(any())).thenReturn(user);
265
+
266
+ // Act & Assert
267
+ mockMvc.perform(post("/api/users")
268
+ .contentType(MediaType.APPLICATION_JSON)
269
+ .content("{\"name\":\"John\",\"email\":\"john@example.com\"}"))
270
+ .andExpect(status().isOk())
271
+ .andExpect(jsonPath("$.name").value("John"));
272
+ }
273
+ }
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 四、隔离级别选择指南
279
+
280
+ | 测试类型 | 隔离级别 | 推荐策略 |
281
+ |---------|---------|---------|
282
+ | **Repository 层** | L1 | H2 内存库 |
283
+ | **Service 层(同步)** | L2 | @Transactional |
284
+ | **Service 层(异步)** | L3 | 手动清理 |
285
+ | **API 层(简单)** | L2 | MockMvc + @Transactional |
286
+ | **API 层(复杂)** | L1 | MockMvc + H2 |
287
+ | **端到端** | L1 | Testcontainers |
288
+
289
+ ---
290
+
291
+ ## 五、常见问题和解决方案
292
+
293
+ ### 1. 异步操作测试
294
+
295
+ **问题**:@Transactional 不适用于异步操作(消息队列、异步方法)
296
+
297
+ **解决方案**:
298
+ - 使用 @AfterEach 手动清理
299
+ - 使用 Awaitility 等待异步操作完成
300
+ - 使用 embedded broker 替代 mock
301
+
302
+ ### 2. 外部依赖测试
303
+
304
+ **问题**:外部 API 不可用或不稳定
305
+
306
+ **解决方案**:
307
+ - 使用 MockWebServer/WireMock 模拟外部 API
308
+ - 使用 @MockBean mock Feign 客户端
309
+ - 使用 Testcontainers 运行真实服务
310
+
311
+ ### 3. 测试数据污染
312
+
313
+ **问题**:测试数据泄漏到其他测试
314
+
315
+ **解决方案**:
316
+ - 每个测试独立数据(Builder 模式)
317
+ - 使用 @Transactional 自动回滚
318
+ - 使用 @DirtContexts 标记需要重新加载上下文的测试
319
+
320
+ ### 4. 测试速度慢
321
+
322
+ **问题**:Testcontainers 启动慢
323
+
324
+ **解决方案**:
325
+ - 使用 @Testcontainers 的 reuse 模式
326
+ - 使用 H2 替代真实数据库(Repository 层)
327
+ - 使用 mock 替代真实外部服务
328
+
329
+ ---
330
+
331
+ ## 六、与 glaf4-test 的关系
332
+
333
+ 本隔离策略参考了 glaf4-test 的以下规范:
334
+ - **H2 替代 MySQL**:`MERGE INTO ... KEY(id)` 幂等写法、`MODE=MySQL;DATABASE_TO_UPPER=false`
335
+ - **rabbitmq-mock**:`MockConnectionFactory → CachingConnectionFactory → firstRabbitTemplate`
336
+ - **embedded-redis**:端口 6378、`@AutoConfigureBefore` Redisson config
337
+
338
+ **注意**:glaf4-test 的部分配置是 GLAF4 框架专用的(如 `gtmc.glaf4.*` 配置键),本规范已抽象为通用模式。
339
+
340
+ ---
341
+
342
+ ## 变更记录
343
+
344
+ | 日期 | 版本 | 变更内容 |
345
+ |------|------|---------|
346
+ | 2026-08-04 | v1.0 | 从 glaf4-test h2-rabbitmq-redis.md 抽取通用隔离策略 |