rigorous_testing
16
总安装量
4
周安装量
#21467
全站排名
安装命令
npx skills add https://github.com/cityfish91159/maihouses --skill rigorous_testing
Agent 安装分布
opencode
4
codex
4
claude-code
3
antigravity
3
gemini-cli
3
windsurf
2
Skill 文档
Rigorous Testing Protocol
1. é»éæ³å
ãå¦ææ²æ¸¬è©¦ï¼å°±ä¸ç®å®æãã
- æ°¸é ä¸è¦åè¨ä¿®æ¹ææèä¸è·æ¸¬è©¦
- å¦æç¾ææ¸¬è©¦å¤±æï¼ä¿®å¾©ä»£ç¢¼èéä¿®æ¹æ¸¬è©¦ï¼é¤é測試æ¬èº«éæï¼
- æ¯å bug ä¿®å¾©å¿ é æåæ¸æ¸¬è©¦
2. æ¸¬è©¦ææ©
ä¿®æ¹åï¼å»ºç«åºæºï¼
# è·ç¸éæ¸¬è©¦æªæ¡ï¼ç¢ºèªç¶åçæ
npm run test <ç¸éæªæ¡>
éç¼ä¸ï¼TDD 循ç°ï¼
RED â å
寫失æç測試
GREEN â 寫æå°ä»£ç¢¼è®æ¸¬è©¦éé
REFACTOR â åªå代碼ï¼ä¿ææ¸¬è©¦éé
ä¿®æ¹å¾ï¼ç¢ºä¿ç¡åæ¸ï¼
# è·å®æ´æ¸¬è©¦å¥ä»¶
npm test
3. MaiHouses 測試å ç
å®å 測試 (Vitest)
- ç¨é: å·¥å ·å½æ¸ãhooksãç¨ç«çµä»¶
- Mock: 使ç¨
vi.mockæ¨¡æ¬ API - è·¯å¾:
src/**/__tests__/*.test.ts
// ç¯ä¾
import { describe, it, expect, vi } from 'vitest';
describe('åè½å稱', () => {
it('æè©²æ£ç¢ºèçææ
æ³', () => {
// Arrange
const input = 'test';
// Act
const result = myFunction(input);
// Assert
expect(result).toBe('expected');
});
});
æ´å測試 (API)
- ç¨é: Backend é輯 (
api/ç®é) - Mock: 使ç¨
node-mocks-httpæ¨¡æ¬ Request/Response - è·¯å¾:
api/**/__tests__/*.test.ts
E2E 測試 (Playwright)
- ç¨é: ééµç¨æ¶æµç¨ï¼ç»å ¥ãç¼æçï¼
- è·¯å¾:
tests/e2e/*.spec.ts
4. å¿ åæª¢æ¥æ¸ å®
æ¯æ¬¡ä¿®æ¹å¾
- è·éç¸éæ¸¬è©¦æªæ¡ï¼
- æææ¸¬è©¦ééï¼
- å¦æä¿®å¾© bugï¼ææ°å¢åæ¸æ¸¬è©¦ï¼
- TypeScript é¡å檢æ¥ééï¼ (
npm run typecheck)
æäº¤å
- 宿´æ¸¬è©¦å¥ä»¶ééï¼ (
npm test) - ç¡è·³éçæ¸¬è©¦ï¼
- 測試è¦èæ°å¢ç代碼ï¼
5. 測試å½åè¦ç¯
describe('模çµ/çµä»¶å稱', () => {
describe('åè½åé¡', () => {
it('æè©² [é æè¡çº] ç¶ [æ¢ä»¶]', () => {
// ...
});
});
});
// ç¯ä¾
describe('useComments', () => {
describe('toggleLike', () => {
it('æè©²æ£ç¢ºåææè®çæ
ç¶ç¨æ¶é»æ', () => {
// ...
});
it('æè©²å滾çæ
ç¶ API 失æ', () => {
// ...
});
});
});
6. å¸¸è¦æ¸¬è©¦æ¨¡å¼
Mock API å¼å«
vi.mock('../lib/supabase', () => ({
supabase: {
from: vi.fn(() => ({
select: vi.fn(() => ({
eq: vi.fn(() => Promise.resolve({ data: [], error: null })),
})),
})),
},
}));
Mock Hook
vi.mock('../hooks/useAuth', () => ({
useAuth: () => ({
user: { id: 'test-user' },
isLoggedIn: true,
}),
}));
æ¸¬è©¦ç°æ¥æä½
it('æè©²èçç°æ¥æä½', async () => {
const { result } = renderHook(() => useMyHook());
await act(async () => {
await result.current.asyncAction();
});
expect(result.current.state).toBe('expected');
});
測試é¯èª¤æ æ³
it('æè©²æ£ç¢ºèçé¯èª¤', async () => {
// Mock API è¿åé¯èª¤
vi.mocked(fetch).mockRejectedValueOnce(new Error('Network error'));
const { result } = renderHook(() => useMyHook());
await act(async () => {
await result.current.action();
});
expect(result.current.error).toBe('Network error');
});
7. æ éæé¤
測試æèµ·
- æª¢æ¥æªééç handles æ DB é£ç·
- ç¢ºèªææ Promise 齿 await
測試ä¸ç©©å® (Flaky)
- æª¢æ¥ async/await åé¡
- 檢æ¥å ±äº«çæ
- 使ç¨
waitForçå¾ ç°æ¥æ´æ°
Mock ä¸çæ
- ç¢ºèª mock å¨ import ä¹å
- æª¢æ¥ mock è·¯å¾æ¯å¦æ£ç¢º
- 使ç¨
vi.clearAllMocks()å¨beforeEach
8. 測試æä»¤éæ¥
# å·è¡æææ¸¬è©¦
npm test
# å·è¡å®ä¸æªæ¡
npx vitest run src/path/to/file.test.ts
# ç£è¦æ¨¡å¼
npm run test:watch
# æ¥çè¦èç
npx vitest run --coverage
# åªè·ç¬¦ååç¨±çæ¸¬è©¦
npx vitest run -t "測試å稱ééµå"
9. èå ¶ä» Skills æ´å
| éæ®µ | æ´å Skill | 說æ |
|---|---|---|
| 測試å | /read-before-edit |
å è®æç¾ææ¸¬è©¦ |
| 寫測試 | /code-validator |
ç¢ºä¿æ¸¬è©¦ä»£ç¢¼å質 |
| 測試失æ | /type-checker |
修復é¡ååé¡ |
| æäº¤å | /pre-commit-validator |
ç¢ºä¿æææ¸¬è©¦éé |
10. è¨ä½
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â â
â ð§ª æ²ææ¸¬è©¦ç代碼 = ä¸åå¨ç代碼 â
â â
â â
測試éé â 代碼æ£ç¢ºï¼ä½è³å°æåºæ¬ä¿éï¼ â
â â
â ð æ¸¬è©¦å¤±æ â 修復代碼ï¼ä¸æ¯åªé¤æ¸¬è©¦ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ