
Test Driven Dev
- 1 installs
- 87 repo stars
- Updated July 22, 2026
- alibaba/opc-starter
test-driven-dev is a Claude Code skill that manages test-driven development for the OPC-Starter project across unit, Playwright E2E, and demo-mode tests.
About
This skill defines the test-driven-development conventions for the OPC-Starter project. It covers running unit tests, Playwright E2E tests, and demo-mode tests with typewriter effects, plus maintaining a TEST_PLAN document. A developer uses it when adding a feature to write priority-tagged test cases and keep authentication, registration, and demo suites current.
- Test-driven-development workflow for the OPC-Starter project
- Runs unit, Playwright E2E, and demo-mode tests
- Provides a priority-tagged test checklist for new pages and forms
Test Driven Dev by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,750 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
test-driven-dev capabilities & compatibility
- Capabilities
- e2e testing · unit testing · test planning · demo recording
- Works with
- playwright
- Use cases
- testing
What test-driven-dev says it does
login.spec.ts # 登录测试 (14 个)
**新功能 → 先写测试** 或功能完成后立即补充
npx skills add https://github.com/alibaba/opc-starter --skill test-driven-devAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 87 |
| Last updated | July 22, 2026 |
| Repository | alibaba/opc-starter ↗ |
What it does
Write and run unit, Playwright E2E, and demo-mode tests for the OPC-Starter project.
Who is it for?
Writing and organizing Playwright E2E and demo tests when adding features to OPC-Starter
Skip if: Projects other than OPC-Starter, since paths and npm scripts are project-specific
When should I use this skill?
You are adding a feature and need to write or run tests for OPC-Starter
What you get
Priority-tagged unit and E2E tests plus updated demo cases and TEST_PLAN.md for the new feature.
- Priority-tagged test cases
- Updated demo-mode tests
- Updated TEST_PLAN.md
By the numbers
- Existing suites: login 14 tests, register 17 tests, demo-auth 5 tests
- 4 priority tiers P0-P3 for grouping tests
Files
OPC-Starter 测试驱动开发规范
快速命令
# 单元测试
cd app && npm run test
# E2E 全量
cd app && npm run test:e2e
# 认证专项(有浏览器窗口)
cd app && npm run test:e2e:auth
# 演示模式(打字机效果)
cd app && npm run test:e2e:demo
# UI 调试模式
cd app && npm run test:e2e:ui
# 查看报告
cd app && npm run test:e2e:report---
核心原则
1. 新功能 → 先写测试 或功能完成后立即补充 2. 演示测试独立维护 → tests/e2e/demo/ 目录,带打字机效果 3. 可重复执行 → 注册测试用 Date.now() 生成唯一邮箱,beforeEach 清理状态 4. 测试状态更新 → 完成用例后更新 tests/TEST_PLAN.md
---
目录结构
app/tests/
├── e2e/
│ ├── auth/
│ │ ├── login.spec.ts # 登录测试 (14 个)
│ │ └── register.spec.ts # 注册测试 (17 个)
│ ├── demo/
│ │ └── demo-auth.spec.ts # 演示测试 (5 个)
│ ├── dashboard.spec.ts # fixme
│ ├── profile.spec.ts # fixme
│ ├── persons.spec.ts # fixme
│ └── settings.spec.ts # fixme
└── support/
├── fixtures/auth.fixture.ts
└── helpers/
├── test-helpers.ts
└── demo-helpers.ts # 打字机/高亮效果---
新增功能测试 Checklist
新增页面
test('[P1] 应该能够访问页面', ...) // 必须
test('[P1] 应该显示主要内容', ...) // 必须
test('[P1] 核心交互测试', ...) // 建议
test('[P2] 导航到其他页面', ...) // 建议新增表单
test('[P0] 成功提交', ...) // 必须
test('[P1] 空字段被阻止', ...) // 必须
test('[P1] 无效格式被阻止', ...) // 必须
test('[P1] 显示错误提示', ...) // 建议
// 同步在 demo/ 目录添加演示用例新增演示用例模板
import { test, expect } from '@playwright/test';
import { fillFormWithEffect, clickWithEffect, highlightElement } from '../../support/helpers/demo-helpers';
test.use({ launchOptions: { slowMo: 50 }, video: 'on' });
test.describe('🎬 演示模式 - [功能名]', () => {
test.beforeEach(async ({ page }) => {
await page.context().clearCookies();
await page.evaluate(() => { try { localStorage.clear(); } catch {} });
});
test('🎬 演示:[场景名]', async ({ page }) => {
await page.goto('/path');
await page.waitForLoadState('networkidle');
await fillFormWithEffect(page, [
{ selector: '#field1', value: '值1' },
{ selector: '#field2', value: '值2' },
]);
await highlightElement(page, 'button[type="submit"]', 500);
await clickWithEffect(page, 'button[type="submit"]', { pause: 1000 });
});
});---
演示辅助函数速查
| 函数 | 用途 | 关键参数 |
|---|---|---|
typeWithEffect(page, selector, text) | 打字机效果输入 | delay: 40 |
highlightElement(page, selector, duration) | 红色边框高亮 | duration: 500 |
clickWithEffect(page, selector) | 高亮后点击 | pause: 300 |
fillFormWithEffect(page, fields[]) | 表单批量填充 | fields 数组 |
演示速度配置在 tests/support/helpers/demo-helpers.ts → DEMO_CONFIG
---
测试用例文件结构
// 1. 引入
import { test, expect } from '@playwright/test';
// 2. 测试数据
const TEST_USER = { email: 'test@example.com', password: '888888' };
// 3. 辅助函数
async function clearAuthState(page) { ... }
// 4. 测试套件 - 按优先级分组
test.describe('[P0] 核心流程', () => { ... });
test.describe('[P1] 验证逻辑', () => { ... });
test.describe('[P2] 用户体验', () => { ... });
test.describe('[P3] 边界情况', () => { ... });---
运行器配置
Playwright 配置:app/playwright.config.ts 演示速度参数:tests/support/helpers/demo-helpers.ts 测试规划文档:tests/TEST_PLAN.md
详细说明见 references/testing-patterns.md
测试模式参考文档
1. 测试用例命名规范
[优先级] 描述| 级别 | 含义 | 示例 |
|---|---|---|
| P0 | 核心流程,必须通过 | [P0] 使用正确凭证登录成功 |
| P1 | 重要验证,应该通过 | [P1] 错误密码显示错误提示 |
| P2 | 用户体验,建议通过 | [P2] 密码字段是密码类型 |
| P3 | 边界情况 | [P3] 刚好 6 字符密码可以注册 |
---
2. 测试套件分组模式
test.describe('[P0] 功能名 - 核心流程', () => {
// P0 用例
});
test.describe('[P1] 功能名 - 表单验证', () => {
// P1 用例
});
test.describe('[P1] 功能名 - 导航', () => {
// 导航跳转相关
});
test.describe('[P2] 功能名 - 用户体验', () => {
// P2 用例
});
test.describe('[P3] 功能名 - 边界情况', () => {
// P3 用例
});---
3. 状态清理模式
// beforeEach 标准清理(未导航时)
test.beforeEach(async ({ page }) => {
await page.context().clearCookies();
await page.evaluate(() => {
try {
localStorage.clear();
sessionStorage.clear();
} catch {
// 忽略跨域错误
}
});
});
// 已有页面时的清理(先导航再清理)
test.beforeEach(async ({ page }) => {
await page.goto('/login');
await page.context().clearCookies();
await page.evaluate(() => { try { localStorage.clear(); } catch {} });
});---
4. 可重复执行保证
// 注册测试:使用唯一邮箱
const generateUniqueEmail = () => `test${Date.now()}@test.com`;
test('注册新用户', async ({ page }) => {
const email = generateUniqueEmail(); // 每次不同
await fillRegisterForm(page, '昵称', email, 'Password123', 'Password123');
// ...
});---
5. 等待策略
// 等待页面稳定
await page.waitForLoadState('networkidle');
// 等待元素可见
await expect(page.locator('#element')).toBeVisible({ timeout: 10000 });
// 等待 URL 变化
await expect(page).toHaveURL(/.*dashboard.*/, { timeout: 15000 });
// 等待文本出现
await expect(page.locator('text=成功')).toBeVisible({ timeout: 10000 });---
6. fixme 模式
暂时无法运行的测试(如依赖测试用户):
// 整组 fixme
test.describe.fixme('[P1] 需要真实用户', () => {
// 激活条件:在 Supabase 创建 test@example.com
});
// 单个 fixme
test.fixme('[P0] 依赖真实登录', async ({ page }) => {
// FIXME: 需要确认 test@example.com 用户存在
});激活方式:移除 .fixme 即可启用。
---
7. 演示测试 vs 功能测试 区别
| 维度 | 功能测试 | 演示测试 |
|---|---|---|
| 目录 | tests/e2e/ | tests/e2e/demo/ |
| 速度 | 快 | 慢(打字机效果) |
| 断言 | 严格 | 宽松 |
| 视频 | 失败时录制 | 始终录制 |
| 目的 | 验证功能 | 展示效果 |
| 重复性 | 幂等 | 幂等(唯一邮箱) |
---
8. 测试规划文档维护
每次增加/完成测试后,更新 tests/TEST_PLAN.md 中的状态:
| 符号 | 含义 |
|---|---|
| ✅ | 已完成,正常运行 |
| ⏸ | fixme,暂时跳过 |
| 🚧 | 进行中 |
| 未创建 | 还没有文件 |