5.8 KiB
Executable File
5.8 KiB
Executable File
超级Loop(E2E Loop)
定义
超级Loop是在核心Loop基础上增加E2E测试验证的扩展循环,确保前后端联动的正确性。
核心思想:通过E2E测试纳入更大的Loop范围,验证完整的用户流程。
核心流程
开始进入循环
↓
[Chat] 进入Plan模式
↓
装载需求规格/界面原型,给出指令进行Plan
↓
[Chat] 符合要求,退出Plan模式,开始执行?
↓ 是
[模型] 读取Plan,按照Loop规则进行实现
↓
[模型] 满足Loop准出要求?
↓ 否 → 重复多次/白天持续很久/夜间
↓ 是
[模型] 退出循环
↓
(给予ByPass权限)
7个步骤
1. Plan等待确认
在docs/plans下根据模版创建Plan。
# Plan: 实现用户注册功能(含前端)
## 目标
实现用户注册功能,包括后端API和前端页面
## 任务列表
- [ ] 1. 实现POST /api/v1/users API
- [ ] 2. 实现注册页面 /register
- [ ] 3. 实现表单验证
- [ ] 4. 实现注册成功跳转
- [ ] 5. 编写API测试
- [ ] 6. 编写E2E测试
## 验收标准
- 所有API测试通过
- 所有E2E测试通过
- 前端页面视觉效果符合设计稿
2. 编写测试用例
在docs/test-cases下编写E2E测试用例。
# docs/test-cases/register.md
## 测试用例
### TC-001: 成功注册
1. 访问 /register 页面
2. 输入用户名 testuser
3. 输入邮箱 test@example.com
4. 输入密码 Password123
5. 确认密码 Password123
6. 点击注册按钮
7. 验证跳转到 /login
8. 验证提示"注册成功"
### TC-002: 用户名已存在
1. 访问 /register 页面
2. 输入已存在的用户名 existinguser
3. 点击注册按钮
4. 验证提示"用户名已存在"
3. 编写API测试
根据Plan实现API测试,运行成功并断言失败。
@Test
void testRegister() {
CreateUserRequest request = new CreateUserRequest();
request.setUsername("testuser");
request.setEmail("test@example.com");
request.setPassword("Password123");
Response<UserResponse> response = userClient.create(request);
assertEquals(201, response.getCode());
assertNotNull(response.getData().getId());
}
4. 编写实现
编写后端和前端实现代码。
后端实现:
@PostMapping("/users")
public Response<UserResponse> createUser(@RequestBody CreateUserRequest request) {
return Response.success(userAppService.create(request));
}
前端实现:
function RegisterPage() {
const [form] = Form.useForm();
const handleSubmit = async (values) => {
await axios.post('/api/v1/users', values);
message.success('注册成功');
navigate('/login');
};
return (
<Form form={form} onFinish={handleSubmit}>
<Form.Item name="username" rules={[{ required: true }]}>
<Input placeholder="用户名" />
</Form.Item>
<Button type="primary" htmlType="submit">注册</Button>
</Form>
);
}
5. 运行API测试
运行测试,并修复失败的测试和其他错误。
mvn test -Dtest=UserApiTest
6. 浏览器调试
使用Playwright调试前端,确认视觉效果和交互功能。
test('注册页面视觉效果', async ({ page }) => {
await page.goto('/register');
// 截图验证视觉效果
const screenshot = await page.screenshot();
// 调用AI视觉模型验证
// 验证表单验证
await page.fill('[name="email"]', 'invalid-email');
await page.click('button[type="submit"]');
await expect(page.getByText('请输入有效的邮箱')).toBeVisible();
});
7. 编写E2E测试
编写Playwright E2E测试,覆盖本轮需求的测试场景。
test('完整的注册流程', async ({ page }) => {
await page.goto('/register');
await page.getByLabel('用户名').fill('testuser');
await page.getByLabel('邮箱').fill('test@example.com');
await page.getByLabel('密码').fill('Password123');
await page.getByLabel('确认密码').fill('Password123');
await page.getByRole('button', { name: '注册' }).click();
await expect(page).toHaveURL(/\/login/);
await expect(page.getByText('注册成功')).toBeVisible();
});
超级Loop vs 核心Loop
| 维度 | 核心Loop | 超级Loop |
|---|---|---|
| 测试范围 | API测试 | API测试 + E2E测试 |
| 验证层次 | 后端逻辑 | 前后端联动 |
| 复杂度 | 中等 | 高 |
| 运行时间 | 几分钟 | 几十分钟到几小时 |
| Token消耗 | 中等 | 高 |
| 适用场景 | 后端开发 | 全栈开发 |
适用场景
- 全栈开发:需要同时开发前后端
- 复杂交互:需要验证前后端联动
- 用户体验:需要验证视觉效果
- 完整流程:需要验证完整的用户流程
优势
- 全面验证:验证前后端联动的正确性
- 用户体验:验证视觉效果和交互
- 完整流程:验证完整的用户流程
- 质量保障:E2E测试保证质量
挑战
- 成本高:运行时间长,Token消耗大
- 维护成本:E2E测试需要持续维护
- 调试复杂:需要调试前后端
- 环境依赖:依赖完整的环境
最佳实践
- 先写测试用例:明确验收标准
- API测试先通过:确保后端逻辑正确
- 浏览器调试:验证前端视觉效果
- E2E测试覆盖:确保前后端联动正确
- 成本控制:仅在必要时使用
相关概念
- 核心Loop:超级Loop基于核心Loop
- Loop工程:超级Loop是Loop工程的扩展
- 测试策略金字塔:超级Loop使用的测试策略
- Playwright:超级Loop使用的E2E测试工具
- Browser_Use:超级Loop可能使用的浏览器自动化工具