@su-record/vibe 2.7.14 → 2.7.16
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.
- package/.env.example +37 -37
- package/CLAUDE.md +134 -126
- package/LICENSE +21 -21
- package/README.md +449 -449
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/docs/api-documenter.md +99 -99
- package/agents/docs/changelog-writer.md +93 -93
- package/agents/e2e-tester.md +294 -294
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/junior-mentor.md +141 -141
- package/agents/planning/requirements-analyst.md +84 -84
- package/agents/planning/ux-advisor.md +83 -83
- package/agents/qa/acceptance-tester.md +86 -86
- package/agents/qa/edge-case-finder.md +93 -93
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui/ui-a11y-auditor.md +93 -93
- package/agents/ui/ui-antipattern-detector.md +94 -94
- package/agents/ui/ui-dataviz-advisor.md +69 -69
- package/agents/ui/ui-design-system-gen.md +57 -57
- package/agents/ui/ui-industry-analyzer.md +49 -49
- package/agents/ui/ui-layout-architect.md +65 -65
- package/agents/ui/ui-stack-implementer.md +68 -68
- package/agents/ui/ux-compliance-reviewer.md +81 -81
- package/agents/ui-previewer.md +258 -258
- package/commands/vibe.analyze.md +11 -13
- package/commands/vibe.review.md +43 -1
- package/commands/vibe.run.md +2124 -2078
- package/commands/vibe.spec.md +9 -4
- package/commands/vibe.spec.review.md +569 -565
- package/commands/vibe.utils.md +413 -413
- package/commands/vibe.verify.md +33 -8
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/commands/evolution.js +12 -12
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +51 -55
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/init.js +5 -5
- package/dist/cli/commands/remove.js +14 -14
- package/dist/cli/commands/sentinel.js +27 -27
- package/dist/cli/commands/skills.js +5 -5
- package/dist/cli/commands/slack.js +10 -10
- package/dist/cli/commands/telegram.js +12 -12
- package/dist/cli/detect.js +32 -32
- package/dist/cli/index.js +51 -51
- package/dist/cli/llm/claude-commands.js +16 -16
- package/dist/cli/llm/config.js +18 -18
- package/dist/cli/llm/gemini-commands.js +16 -16
- package/dist/cli/llm/gpt-commands.js +19 -19
- package/dist/cli/llm/help.js +21 -21
- package/dist/cli/postinstall/constants.d.ts.map +1 -1
- package/dist/cli/postinstall/constants.js +7 -8
- package/dist/cli/postinstall/constants.js.map +1 -1
- package/dist/cli/postinstall/cursor-agents.js +32 -32
- package/dist/cli/postinstall/cursor-rules.js +83 -83
- package/dist/cli/postinstall/cursor-skills.js +743 -743
- package/dist/cli/setup/Provisioner.js +42 -42
- package/dist/infra/lib/DeepInit.js +24 -24
- package/dist/infra/lib/IterationTracker.js +11 -11
- package/dist/infra/lib/PythonParser.js +108 -108
- package/dist/infra/lib/ReviewRace.js +96 -96
- package/dist/infra/lib/SkillFrontmatter.js +28 -28
- package/dist/infra/lib/SkillQualityGate.js +9 -9
- package/dist/infra/lib/SkillRepository.js +159 -159
- package/dist/infra/lib/UltraQA.js +99 -99
- package/dist/infra/lib/autonomy/AuditStore.js +41 -41
- package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
- package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
- package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
- package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
- package/dist/infra/lib/embedding/VectorStore.js +22 -22
- package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
- package/dist/infra/lib/evolution/DescriptionOptimizer.js +21 -21
- package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
- package/dist/infra/lib/evolution/InsightStore.js +90 -90
- package/dist/infra/lib/evolution/RollbackManager.js +5 -5
- package/dist/infra/lib/evolution/SkillBenchmark.js +23 -23
- package/dist/infra/lib/evolution/SkillEvalRunner.js +50 -50
- package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
- package/dist/infra/lib/evolution/UsageTracker.js +28 -28
- package/dist/infra/lib/gemini/orchestration.js +5 -5
- package/dist/infra/lib/gpt/orchestration.js +4 -4
- package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/infra/lib/memory/MemorySearch.js +57 -57
- package/dist/infra/lib/memory/MemoryStorage.js +181 -181
- package/dist/infra/lib/memory/ObservationStore.js +28 -28
- package/dist/infra/lib/memory/ReflectionStore.js +30 -30
- package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
- package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
- package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
- package/dist/infra/orchestrator/AgentManager.js +12 -12
- package/dist/infra/orchestrator/AgentRegistry.js +65 -65
- package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
- package/dist/infra/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/dist/tools/semantic/astGrep.test.js +6 -6
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/hooks/gemini-hooks.json +73 -73
- package/hooks/hooks.json +137 -137
- package/hooks/scripts/code-check.js +77 -70
- package/hooks/scripts/context-save.js +212 -212
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +475 -475
- package/hooks/scripts/post-edit.js +32 -32
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/prompt-dispatcher.js +185 -185
- package/hooks/scripts/sentinel-guard.js +104 -104
- package/hooks/scripts/session-start.js +106 -106
- package/hooks/scripts/stop-notify.js +209 -209
- package/hooks/scripts/utils.js +100 -100
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +121 -121
- package/skills/agents-md/SKILL.md +120 -120
- package/skills/arch-guard/SKILL.md +180 -180
- package/skills/brand-assets/SKILL.md +146 -146
- package/skills/capability-loop/SKILL.md +167 -167
- package/skills/characterization-test/SKILL.md +206 -206
- package/skills/commerce-patterns/SKILL.md +63 -59
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +13 -48
- package/skills/e2e-commerce/SKILL.md +61 -57
- package/skills/exec-plan/SKILL.md +147 -147
- package/skills/frontend-design/SKILL.md +12 -73
- package/skills/git-worktree/SKILL.md +72 -72
- package/skills/handoff/SKILL.md +109 -109
- package/skills/parallel-research/SKILL.md +87 -87
- package/skills/priority-todos/SKILL.md +63 -63
- package/skills/seo-checklist/SKILL.md +57 -57
- package/skills/techdebt/SKILL.md +122 -122
- package/skills/tool-fallback/SKILL.md +103 -103
- package/skills/typescript-advanced-types/SKILL.md +66 -66
- package/skills/ui-ux-pro-max/SKILL.md +221 -206
- package/skills/vercel-react-best-practices/SKILL.md +59 -59
- package/skills/video-production/SKILL.md +51 -51
- package/vibe/config.json +29 -29
- package/vibe/constitution.md +227 -227
- package/vibe/rules/principles/communication-guide.md +98 -98
- package/vibe/rules/principles/development-philosophy.md +52 -52
- package/vibe/rules/principles/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/performance.md +236 -236
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/git-workflow.md +237 -237
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/rules/standards/security.md +305 -305
- package/vibe/rules/writing/document-style.md +74 -74
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
- package/vibe/ui-ux-data/charts.csv +26 -26
- package/vibe/ui-ux-data/colors.csv +97 -97
- package/vibe/ui-ux-data/icons.csv +101 -101
- package/vibe/ui-ux-data/landing.csv +31 -31
- package/vibe/ui-ux-data/products.csv +96 -96
- package/vibe/ui-ux-data/react-performance.csv +45 -45
- package/vibe/ui-ux-data/stacks/astro.csv +54 -54
- package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
- package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
- package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
- package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
- package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
- package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
- package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
- package/vibe/ui-ux-data/stacks/react.csv +54 -54
- package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
- package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
- package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
- package/vibe/ui-ux-data/stacks/vue.csv +50 -50
- package/vibe/ui-ux-data/styles.csv +68 -68
- package/vibe/ui-ux-data/typography.csv +57 -57
- package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
- package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
- package/vibe/ui-ux-data/version.json +31 -31
- package/vibe/ui-ux-data/web-interface.csv +31 -31
|
@@ -1,440 +1,440 @@
|
|
|
1
|
-
# Testing Strategy for the AI Era
|
|
2
|
-
|
|
3
|
-
## Core Principles
|
|
4
|
-
|
|
5
|
-
```markdown
|
|
6
|
-
✅ Single Responsibility (SRP)
|
|
7
|
-
✅ Don't Repeat Yourself (DRY)
|
|
8
|
-
✅ Reusability
|
|
9
|
-
✅ Low Complexity
|
|
10
|
-
✅ Contract-First Design
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Test Priorities in AI-Driven Development
|
|
14
|
-
|
|
15
|
-
### 1. Contract Testing (Highest Priority) ⭐⭐⭐
|
|
16
|
-
|
|
17
|
-
**Concept**: **Define contracts with types/schemas** before writing code
|
|
18
|
-
|
|
19
|
-
**Reason**: Since AI implements following contracts, type safety is automatically guaranteed
|
|
20
|
-
|
|
21
|
-
#### Python (Pydantic)
|
|
22
|
-
|
|
23
|
-
```python
|
|
24
|
-
# Contract definition (AI implements following this)
|
|
25
|
-
from pydantic import BaseModel, Field, EmailStr
|
|
26
|
-
|
|
27
|
-
class CreateUserRequest(BaseModel):
|
|
28
|
-
"""User creation contract"""
|
|
29
|
-
email: EmailStr
|
|
30
|
-
username: str = Field(min_length=3, max_length=50)
|
|
31
|
-
password: str = Field(min_length=8)
|
|
32
|
-
age: int = Field(ge=0, le=150)
|
|
33
|
-
|
|
34
|
-
class UserResponse(BaseModel):
|
|
35
|
-
"""User response contract"""
|
|
36
|
-
id: str
|
|
37
|
-
email: str
|
|
38
|
-
username: str
|
|
39
|
-
created_at: str
|
|
40
|
-
|
|
41
|
-
# AI cannot violate this contract (auto-validated)
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
#### TypeScript
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
// Contract definition
|
|
48
|
-
interface CreateUserRequest {
|
|
49
|
-
email: string;
|
|
50
|
-
username: string; // 3-50 chars
|
|
51
|
-
password: string; // min 8 chars
|
|
52
|
-
age: number; // 0-150
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface UserResponse {
|
|
56
|
-
id: string;
|
|
57
|
-
email: string;
|
|
58
|
-
username: string;
|
|
59
|
-
createdAt: string;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Runtime validation with Zod
|
|
63
|
-
import { z } from 'zod';
|
|
64
|
-
|
|
65
|
-
const createUserSchema = z.object({
|
|
66
|
-
email: z.string().email(),
|
|
67
|
-
username: z.string().min(3).max(50),
|
|
68
|
-
password: z.string().min(8),
|
|
69
|
-
age: z.number().min(0).max(150),
|
|
70
|
-
});
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
#### Dart (Flutter)
|
|
74
|
-
|
|
75
|
-
```dart
|
|
76
|
-
// Contract definition
|
|
77
|
-
class CreateUserRequest {
|
|
78
|
-
const CreateUserRequest({
|
|
79
|
-
required this.email,
|
|
80
|
-
required this.username,
|
|
81
|
-
required this.password,
|
|
82
|
-
required this.age,
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
final String email;
|
|
86
|
-
final String username; // 3-50 chars
|
|
87
|
-
final String password; // min 8 chars
|
|
88
|
-
final int age; // 0-150
|
|
89
|
-
|
|
90
|
-
// JSON serialization (contract enforcement)
|
|
91
|
-
Map<String, dynamic> toJson() => {
|
|
92
|
-
'email': email,
|
|
93
|
-
'username': username,
|
|
94
|
-
'password': password,
|
|
95
|
-
'age': age,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### 2. Integration Testing (High) ⭐⭐⭐
|
|
101
|
-
|
|
102
|
-
**Concept**: **Test real scenarios** where multiple modules work together
|
|
103
|
-
|
|
104
|
-
**Reason**: Discovers module interaction errors that AI may have missed
|
|
105
|
-
|
|
106
|
-
```python
|
|
107
|
-
# ✅ Integration test: Real business flow
|
|
108
|
-
@pytest.mark.asyncio
|
|
109
|
-
async def test_user_registration_flow():
|
|
110
|
-
"""
|
|
111
|
-
Scenario: New user registration
|
|
112
|
-
1. Check email duplication
|
|
113
|
-
2. Create user
|
|
114
|
-
3. Send welcome email
|
|
115
|
-
4. Create default settings
|
|
116
|
-
"""
|
|
117
|
-
# Given: New user information
|
|
118
|
-
request = CreateUserRequest(
|
|
119
|
-
email="new@example.com",
|
|
120
|
-
username="newuser",
|
|
121
|
-
password="password123",
|
|
122
|
-
age=25,
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
# When: Call registration API
|
|
126
|
-
response = await client.post("/api/users", json=request.dict())
|
|
127
|
-
|
|
128
|
-
# Then: User creation succeeds
|
|
129
|
-
assert response.status_code == 201
|
|
130
|
-
data = response.json()
|
|
131
|
-
assert data["email"] == "new@example.com"
|
|
132
|
-
|
|
133
|
-
# And: Welcome email sent
|
|
134
|
-
assert email_service.sent_count == 1
|
|
135
|
-
|
|
136
|
-
# And: Default settings created
|
|
137
|
-
settings = await get_user_settings(data["id"])
|
|
138
|
-
assert settings is not None
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
```typescript
|
|
142
|
-
// ✅ Integration test: React component + API
|
|
143
|
-
import { render, screen, waitFor } from '@testing-library/react';
|
|
144
|
-
import userEvent from '@testing-library/user-event';
|
|
145
|
-
import { UserRegistration } from './UserRegistration';
|
|
146
|
-
|
|
147
|
-
test('user can register successfully', async () => {
|
|
148
|
-
// Given: Render registration form
|
|
149
|
-
render(<UserRegistration />);
|
|
150
|
-
|
|
151
|
-
// When: User fills form
|
|
152
|
-
await userEvent.type(screen.getByLabelText('Email'), 'new@example.com');
|
|
153
|
-
await userEvent.type(screen.getByLabelText('Username'), 'newuser');
|
|
154
|
-
await userEvent.type(screen.getByLabelText('Password'), 'password123');
|
|
155
|
-
await userEvent.click(screen.getByRole('button', { name: 'Sign Up' }));
|
|
156
|
-
|
|
157
|
-
// Then: Success message displayed
|
|
158
|
-
await waitFor(() => {
|
|
159
|
-
expect(screen.getByText('Welcome!')).toBeInTheDocument();
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
### 3. Property-Based Testing (Medium) ⭐⭐
|
|
165
|
-
|
|
166
|
-
**Concept**: **Automatically generate inputs** across entire input range to test
|
|
167
|
-
|
|
168
|
-
**Reason**: Automatically discovers edge cases AI didn't think of
|
|
169
|
-
|
|
170
|
-
```python
|
|
171
|
-
# ✅ Property-based testing (Hypothesis)
|
|
172
|
-
from hypothesis import given, strategies as st
|
|
173
|
-
|
|
174
|
-
@given(
|
|
175
|
-
age=st.integers(min_value=0, max_value=150),
|
|
176
|
-
email=st.emails(),
|
|
177
|
-
username=st.text(min_size=3, max_size=50),
|
|
178
|
-
)
|
|
179
|
-
def test_user_creation_with_any_valid_input(age, email, username):
|
|
180
|
-
"""User creation possible with any valid input"""
|
|
181
|
-
user = create_user(email=email, username=username, age=age)
|
|
182
|
-
assert user.age == age
|
|
183
|
-
assert user.email == email
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
```typescript
|
|
187
|
-
// ✅ Property-based testing (fast-check)
|
|
188
|
-
import fc from 'fast-check';
|
|
189
|
-
|
|
190
|
-
test('discount calculation always returns valid percentage', () => {
|
|
191
|
-
fc.assert(
|
|
192
|
-
fc.property(
|
|
193
|
-
fc.float({ min: 0, max: 10000 }), // price
|
|
194
|
-
fc.float({ min: 0, max: 1 }), // discount rate
|
|
195
|
-
(price, rate) => {
|
|
196
|
-
const discount = calculateDiscount(price, rate);
|
|
197
|
-
return discount >= 0 && discount <= price;
|
|
198
|
-
}
|
|
199
|
-
)
|
|
200
|
-
);
|
|
201
|
-
});
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
### 4. Unit Testing (Low, Selective) ⭐
|
|
205
|
-
|
|
206
|
-
**Concept**: Test individual functions/methods
|
|
207
|
-
|
|
208
|
-
**When to write**: **Only for complex business logic** selectively
|
|
209
|
-
|
|
210
|
-
```python
|
|
211
|
-
# ✅ Unit Test: Complex business rules
|
|
212
|
-
def test_tier_selection_score_calculation():
|
|
213
|
-
"""
|
|
214
|
-
Selection score calculation (complex weights)
|
|
215
|
-
- Feed ×1.15
|
|
216
|
-
- OCR ×1.2
|
|
217
|
-
- Likes ×1.0
|
|
218
|
-
- Bookmarks ×1.0
|
|
219
|
-
- Partnerships ×1.5
|
|
220
|
-
"""
|
|
221
|
-
score = calculate_selection_score(
|
|
222
|
-
feeds=10, # 10 × 1.15 = 11.5
|
|
223
|
-
ocr_count=5, # 5 × 1.2 = 6
|
|
224
|
-
likes=20, # 20 × 1.0 = 20
|
|
225
|
-
bookmarks=8, # 8 × 1.0 = 8
|
|
226
|
-
partnerships=2, # 2 × 1.5 = 3
|
|
227
|
-
)
|
|
228
|
-
assert score == 48.5
|
|
229
|
-
|
|
230
|
-
# ❌ Unnecessary Unit Test: Simple CRUD
|
|
231
|
-
def test_get_user_by_id():
|
|
232
|
-
"""Integration Test is sufficient"""
|
|
233
|
-
user = get_user("user-123")
|
|
234
|
-
assert user.id == "user-123" # Meaningless
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### 5. E2E Testing (Scenario Verification) ⭐⭐
|
|
238
|
-
|
|
239
|
-
**Concept**: Test complete scenarios from user perspective
|
|
240
|
-
|
|
241
|
-
**When**: Only selectively for major user flows
|
|
242
|
-
|
|
243
|
-
```typescript
|
|
244
|
-
// ✅ E2E Test: Playwright/Cypress
|
|
245
|
-
test('user can complete full registration flow', async ({ page }) => {
|
|
246
|
-
// 1. Visit homepage
|
|
247
|
-
await page.goto('https://app.example.com');
|
|
248
|
-
|
|
249
|
-
// 2. Click sign up
|
|
250
|
-
await page.click('text=Sign Up');
|
|
251
|
-
|
|
252
|
-
// 3. Fill form
|
|
253
|
-
await page.fill('input[name="email"]', 'test@example.com');
|
|
254
|
-
await page.fill('input[name="username"]', 'testuser');
|
|
255
|
-
await page.fill('input[name="password"]', 'password123');
|
|
256
|
-
|
|
257
|
-
// 4. Submit
|
|
258
|
-
await page.click('button[type="submit"]');
|
|
259
|
-
|
|
260
|
-
// 5. Verify redirect to dashboard
|
|
261
|
-
await expect(page).toHaveURL('/dashboard');
|
|
262
|
-
await expect(page.locator('h1')).toContainText('Welcome, testuser!');
|
|
263
|
-
});
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
## Test Priority Decision Tree
|
|
267
|
-
|
|
268
|
-
```
|
|
269
|
-
When developing new features:
|
|
270
|
-
|
|
271
|
-
1. Did you define contracts?
|
|
272
|
-
No → Write contracts first (Pydantic/Zod/Dart class)
|
|
273
|
-
Yes → ⬇️
|
|
274
|
-
|
|
275
|
-
2. Do multiple modules collaborate?
|
|
276
|
-
Yes → Write Integration Test ⭐⭐⭐
|
|
277
|
-
No → ⬇️
|
|
278
|
-
|
|
279
|
-
3. Is it complex business logic? (complexity > 10)
|
|
280
|
-
Yes → Write Unit Test ⭐
|
|
281
|
-
No → ⬇️
|
|
282
|
-
|
|
283
|
-
4. Is it a core user flow?
|
|
284
|
-
Yes → Write E2E Test ⭐⭐
|
|
285
|
-
No → Done ✅
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## TDD Alternative for AI Era: ATDD (AI-Test-Driven Development)
|
|
289
|
-
|
|
290
|
-
```markdown
|
|
291
|
-
# New development flow
|
|
292
|
-
|
|
293
|
-
1. **Clarify requirements** (Developer)
|
|
294
|
-
"Premium users get 10% discount"
|
|
295
|
-
|
|
296
|
-
2. **Define contracts** (Developer)
|
|
297
|
-
interface DiscountRequest {
|
|
298
|
-
userId: string;
|
|
299
|
-
orderTotal: number;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
interface DiscountResponse {
|
|
303
|
-
originalPrice: number;
|
|
304
|
-
discountedPrice: number;
|
|
305
|
-
discountRate: number;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
3. **Write test scenarios** (Developer or AI)
|
|
309
|
-
test('premium user gets 10% discount', () => {
|
|
310
|
-
// Given: Premium user, 100 order
|
|
311
|
-
// When: Calculate discount
|
|
312
|
-
// Then: 90 (10% discount)
|
|
313
|
-
})
|
|
314
|
-
|
|
315
|
-
4. **AI implements** (AI)
|
|
316
|
-
- Generate code following contracts
|
|
317
|
-
- Write code that passes tests
|
|
318
|
-
|
|
319
|
-
5. **Integration test** (Automated)
|
|
320
|
-
- Verify complete scenarios in CI/CD
|
|
321
|
-
|
|
322
|
-
6. **Refactoring** (AI + Developer)
|
|
323
|
-
- Remove complexity, duplication
|
|
324
|
-
- Verify SRP compliance
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
## Language-specific Tools
|
|
328
|
-
|
|
329
|
-
### Python
|
|
330
|
-
|
|
331
|
-
```bash
|
|
332
|
-
# Contract Testing
|
|
333
|
-
pip install pydantic
|
|
334
|
-
|
|
335
|
-
# Integration Testing
|
|
336
|
-
pip install pytest pytest-asyncio httpx
|
|
337
|
-
|
|
338
|
-
# Property-Based Testing
|
|
339
|
-
pip install hypothesis
|
|
340
|
-
|
|
341
|
-
# Coverage
|
|
342
|
-
pip install pytest-cov
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### TypeScript/JavaScript
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
# Contract Testing
|
|
349
|
-
npm install zod
|
|
350
|
-
|
|
351
|
-
# Integration Testing
|
|
352
|
-
npm install @testing-library/react @testing-library/user-event
|
|
353
|
-
|
|
354
|
-
# Property-Based Testing
|
|
355
|
-
npm install fast-check
|
|
356
|
-
|
|
357
|
-
# E2E Testing
|
|
358
|
-
npm install playwright
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### Dart/Flutter
|
|
362
|
-
|
|
363
|
-
```bash
|
|
364
|
-
# Integration Testing
|
|
365
|
-
flutter pub add integration_test
|
|
366
|
-
|
|
367
|
-
# Widget Testing
|
|
368
|
-
flutter test
|
|
369
|
-
|
|
370
|
-
# E2E Testing (Flutter Driver)
|
|
371
|
-
flutter drive --target=test_driver/app.dart
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
## Anti-patterns
|
|
375
|
-
|
|
376
|
-
```python
|
|
377
|
-
# ❌ Testing implementation details (fragile)
|
|
378
|
-
def test_internal_cache_structure():
|
|
379
|
-
service = UserService()
|
|
380
|
-
assert service._cache == {} # Depends on internal implementation
|
|
381
|
-
|
|
382
|
-
# ✅ Testing public API (robust)
|
|
383
|
-
def test_user_data_is_cached_after_first_call():
|
|
384
|
-
service = UserService()
|
|
385
|
-
user1 = service.get_user("123")
|
|
386
|
-
user2 = service.get_user("123")
|
|
387
|
-
assert user1 is user2 # Only verify behavior
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
```typescript
|
|
391
|
-
// ❌ Unit tests for every function (excessive)
|
|
392
|
-
test('add function adds two numbers', () => {
|
|
393
|
-
expect(add(1, 2)).toBe(3); // Meaningless
|
|
394
|
-
});
|
|
395
|
-
|
|
396
|
-
// ✅ Only test complex logic
|
|
397
|
-
test('calculate shipping cost with multiple conditions', () => {
|
|
398
|
-
const cost = calculateShipping({
|
|
399
|
-
weight: 10,
|
|
400
|
-
distance: 500,
|
|
401
|
-
isPremium: true,
|
|
402
|
-
isExpress: false,
|
|
403
|
-
});
|
|
404
|
-
expect(cost).toBe(45); // Verify complex rules
|
|
405
|
-
});
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
## Test Coverage Goals
|
|
409
|
-
|
|
410
|
-
```markdown
|
|
411
|
-
# Realistic goals
|
|
412
|
-
|
|
413
|
-
- Contract Coverage: 100% (All APIs have schema definitions)
|
|
414
|
-
- Integration Coverage: 80% (Major business flows)
|
|
415
|
-
- Unit Coverage: Selective (Complex logic only)
|
|
416
|
-
- E2E Coverage: 20-30% (Core user flows)
|
|
417
|
-
|
|
418
|
-
# ❌ Avoid
|
|
419
|
-
- 100% Unit Test Coverage (waste of time)
|
|
420
|
-
- Unit Tests for simple CRUD (Integration is sufficient)
|
|
421
|
-
- Manual testing all edge cases (use Property-based)
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
## Key Summary
|
|
425
|
-
|
|
426
|
-
```markdown
|
|
427
|
-
AI Era Testing Strategy:
|
|
428
|
-
|
|
429
|
-
1. ✅ Contract-First (types/schemas first)
|
|
430
|
-
2. ✅ Integration Testing (real scenarios)
|
|
431
|
-
3. ⚠️ Unit Testing (complex logic only)
|
|
432
|
-
4. ❌ Traditional TDD (inefficient in AI era)
|
|
433
|
-
|
|
434
|
-
Goals:
|
|
435
|
-
- Single Responsibility (SRP)
|
|
436
|
-
- No Duplication (DRY)
|
|
437
|
-
- Reusability
|
|
438
|
-
- Low Complexity
|
|
439
|
-
- Fast Feedback
|
|
440
|
-
```
|
|
1
|
+
# Testing Strategy for the AI Era
|
|
2
|
+
|
|
3
|
+
## Core Principles
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
✅ Single Responsibility (SRP)
|
|
7
|
+
✅ Don't Repeat Yourself (DRY)
|
|
8
|
+
✅ Reusability
|
|
9
|
+
✅ Low Complexity
|
|
10
|
+
✅ Contract-First Design
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Test Priorities in AI-Driven Development
|
|
14
|
+
|
|
15
|
+
### 1. Contract Testing (Highest Priority) ⭐⭐⭐
|
|
16
|
+
|
|
17
|
+
**Concept**: **Define contracts with types/schemas** before writing code
|
|
18
|
+
|
|
19
|
+
**Reason**: Since AI implements following contracts, type safety is automatically guaranteed
|
|
20
|
+
|
|
21
|
+
#### Python (Pydantic)
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# Contract definition (AI implements following this)
|
|
25
|
+
from pydantic import BaseModel, Field, EmailStr
|
|
26
|
+
|
|
27
|
+
class CreateUserRequest(BaseModel):
|
|
28
|
+
"""User creation contract"""
|
|
29
|
+
email: EmailStr
|
|
30
|
+
username: str = Field(min_length=3, max_length=50)
|
|
31
|
+
password: str = Field(min_length=8)
|
|
32
|
+
age: int = Field(ge=0, le=150)
|
|
33
|
+
|
|
34
|
+
class UserResponse(BaseModel):
|
|
35
|
+
"""User response contract"""
|
|
36
|
+
id: str
|
|
37
|
+
email: str
|
|
38
|
+
username: str
|
|
39
|
+
created_at: str
|
|
40
|
+
|
|
41
|
+
# AI cannot violate this contract (auto-validated)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
#### TypeScript
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Contract definition
|
|
48
|
+
interface CreateUserRequest {
|
|
49
|
+
email: string;
|
|
50
|
+
username: string; // 3-50 chars
|
|
51
|
+
password: string; // min 8 chars
|
|
52
|
+
age: number; // 0-150
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface UserResponse {
|
|
56
|
+
id: string;
|
|
57
|
+
email: string;
|
|
58
|
+
username: string;
|
|
59
|
+
createdAt: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Runtime validation with Zod
|
|
63
|
+
import { z } from 'zod';
|
|
64
|
+
|
|
65
|
+
const createUserSchema = z.object({
|
|
66
|
+
email: z.string().email(),
|
|
67
|
+
username: z.string().min(3).max(50),
|
|
68
|
+
password: z.string().min(8),
|
|
69
|
+
age: z.number().min(0).max(150),
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Dart (Flutter)
|
|
74
|
+
|
|
75
|
+
```dart
|
|
76
|
+
// Contract definition
|
|
77
|
+
class CreateUserRequest {
|
|
78
|
+
const CreateUserRequest({
|
|
79
|
+
required this.email,
|
|
80
|
+
required this.username,
|
|
81
|
+
required this.password,
|
|
82
|
+
required this.age,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
final String email;
|
|
86
|
+
final String username; // 3-50 chars
|
|
87
|
+
final String password; // min 8 chars
|
|
88
|
+
final int age; // 0-150
|
|
89
|
+
|
|
90
|
+
// JSON serialization (contract enforcement)
|
|
91
|
+
Map<String, dynamic> toJson() => {
|
|
92
|
+
'email': email,
|
|
93
|
+
'username': username,
|
|
94
|
+
'password': password,
|
|
95
|
+
'age': age,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 2. Integration Testing (High) ⭐⭐⭐
|
|
101
|
+
|
|
102
|
+
**Concept**: **Test real scenarios** where multiple modules work together
|
|
103
|
+
|
|
104
|
+
**Reason**: Discovers module interaction errors that AI may have missed
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
# ✅ Integration test: Real business flow
|
|
108
|
+
@pytest.mark.asyncio
|
|
109
|
+
async def test_user_registration_flow():
|
|
110
|
+
"""
|
|
111
|
+
Scenario: New user registration
|
|
112
|
+
1. Check email duplication
|
|
113
|
+
2. Create user
|
|
114
|
+
3. Send welcome email
|
|
115
|
+
4. Create default settings
|
|
116
|
+
"""
|
|
117
|
+
# Given: New user information
|
|
118
|
+
request = CreateUserRequest(
|
|
119
|
+
email="new@example.com",
|
|
120
|
+
username="newuser",
|
|
121
|
+
password="password123",
|
|
122
|
+
age=25,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# When: Call registration API
|
|
126
|
+
response = await client.post("/api/users", json=request.dict())
|
|
127
|
+
|
|
128
|
+
# Then: User creation succeeds
|
|
129
|
+
assert response.status_code == 201
|
|
130
|
+
data = response.json()
|
|
131
|
+
assert data["email"] == "new@example.com"
|
|
132
|
+
|
|
133
|
+
# And: Welcome email sent
|
|
134
|
+
assert email_service.sent_count == 1
|
|
135
|
+
|
|
136
|
+
# And: Default settings created
|
|
137
|
+
settings = await get_user_settings(data["id"])
|
|
138
|
+
assert settings is not None
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// ✅ Integration test: React component + API
|
|
143
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
144
|
+
import userEvent from '@testing-library/user-event';
|
|
145
|
+
import { UserRegistration } from './UserRegistration';
|
|
146
|
+
|
|
147
|
+
test('user can register successfully', async () => {
|
|
148
|
+
// Given: Render registration form
|
|
149
|
+
render(<UserRegistration />);
|
|
150
|
+
|
|
151
|
+
// When: User fills form
|
|
152
|
+
await userEvent.type(screen.getByLabelText('Email'), 'new@example.com');
|
|
153
|
+
await userEvent.type(screen.getByLabelText('Username'), 'newuser');
|
|
154
|
+
await userEvent.type(screen.getByLabelText('Password'), 'password123');
|
|
155
|
+
await userEvent.click(screen.getByRole('button', { name: 'Sign Up' }));
|
|
156
|
+
|
|
157
|
+
// Then: Success message displayed
|
|
158
|
+
await waitFor(() => {
|
|
159
|
+
expect(screen.getByText('Welcome!')).toBeInTheDocument();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 3. Property-Based Testing (Medium) ⭐⭐
|
|
165
|
+
|
|
166
|
+
**Concept**: **Automatically generate inputs** across entire input range to test
|
|
167
|
+
|
|
168
|
+
**Reason**: Automatically discovers edge cases AI didn't think of
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
# ✅ Property-based testing (Hypothesis)
|
|
172
|
+
from hypothesis import given, strategies as st
|
|
173
|
+
|
|
174
|
+
@given(
|
|
175
|
+
age=st.integers(min_value=0, max_value=150),
|
|
176
|
+
email=st.emails(),
|
|
177
|
+
username=st.text(min_size=3, max_size=50),
|
|
178
|
+
)
|
|
179
|
+
def test_user_creation_with_any_valid_input(age, email, username):
|
|
180
|
+
"""User creation possible with any valid input"""
|
|
181
|
+
user = create_user(email=email, username=username, age=age)
|
|
182
|
+
assert user.age == age
|
|
183
|
+
assert user.email == email
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// ✅ Property-based testing (fast-check)
|
|
188
|
+
import fc from 'fast-check';
|
|
189
|
+
|
|
190
|
+
test('discount calculation always returns valid percentage', () => {
|
|
191
|
+
fc.assert(
|
|
192
|
+
fc.property(
|
|
193
|
+
fc.float({ min: 0, max: 10000 }), // price
|
|
194
|
+
fc.float({ min: 0, max: 1 }), // discount rate
|
|
195
|
+
(price, rate) => {
|
|
196
|
+
const discount = calculateDiscount(price, rate);
|
|
197
|
+
return discount >= 0 && discount <= price;
|
|
198
|
+
}
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### 4. Unit Testing (Low, Selective) ⭐
|
|
205
|
+
|
|
206
|
+
**Concept**: Test individual functions/methods
|
|
207
|
+
|
|
208
|
+
**When to write**: **Only for complex business logic** selectively
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# ✅ Unit Test: Complex business rules
|
|
212
|
+
def test_tier_selection_score_calculation():
|
|
213
|
+
"""
|
|
214
|
+
Selection score calculation (complex weights)
|
|
215
|
+
- Feed ×1.15
|
|
216
|
+
- OCR ×1.2
|
|
217
|
+
- Likes ×1.0
|
|
218
|
+
- Bookmarks ×1.0
|
|
219
|
+
- Partnerships ×1.5
|
|
220
|
+
"""
|
|
221
|
+
score = calculate_selection_score(
|
|
222
|
+
feeds=10, # 10 × 1.15 = 11.5
|
|
223
|
+
ocr_count=5, # 5 × 1.2 = 6
|
|
224
|
+
likes=20, # 20 × 1.0 = 20
|
|
225
|
+
bookmarks=8, # 8 × 1.0 = 8
|
|
226
|
+
partnerships=2, # 2 × 1.5 = 3
|
|
227
|
+
)
|
|
228
|
+
assert score == 48.5
|
|
229
|
+
|
|
230
|
+
# ❌ Unnecessary Unit Test: Simple CRUD
|
|
231
|
+
def test_get_user_by_id():
|
|
232
|
+
"""Integration Test is sufficient"""
|
|
233
|
+
user = get_user("user-123")
|
|
234
|
+
assert user.id == "user-123" # Meaningless
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### 5. E2E Testing (Scenario Verification) ⭐⭐
|
|
238
|
+
|
|
239
|
+
**Concept**: Test complete scenarios from user perspective
|
|
240
|
+
|
|
241
|
+
**When**: Only selectively for major user flows
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// ✅ E2E Test: Playwright/Cypress
|
|
245
|
+
test('user can complete full registration flow', async ({ page }) => {
|
|
246
|
+
// 1. Visit homepage
|
|
247
|
+
await page.goto('https://app.example.com');
|
|
248
|
+
|
|
249
|
+
// 2. Click sign up
|
|
250
|
+
await page.click('text=Sign Up');
|
|
251
|
+
|
|
252
|
+
// 3. Fill form
|
|
253
|
+
await page.fill('input[name="email"]', 'test@example.com');
|
|
254
|
+
await page.fill('input[name="username"]', 'testuser');
|
|
255
|
+
await page.fill('input[name="password"]', 'password123');
|
|
256
|
+
|
|
257
|
+
// 4. Submit
|
|
258
|
+
await page.click('button[type="submit"]');
|
|
259
|
+
|
|
260
|
+
// 5. Verify redirect to dashboard
|
|
261
|
+
await expect(page).toHaveURL('/dashboard');
|
|
262
|
+
await expect(page.locator('h1')).toContainText('Welcome, testuser!');
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## Test Priority Decision Tree
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
When developing new features:
|
|
270
|
+
|
|
271
|
+
1. Did you define contracts?
|
|
272
|
+
No → Write contracts first (Pydantic/Zod/Dart class)
|
|
273
|
+
Yes → ⬇️
|
|
274
|
+
|
|
275
|
+
2. Do multiple modules collaborate?
|
|
276
|
+
Yes → Write Integration Test ⭐⭐⭐
|
|
277
|
+
No → ⬇️
|
|
278
|
+
|
|
279
|
+
3. Is it complex business logic? (complexity > 10)
|
|
280
|
+
Yes → Write Unit Test ⭐
|
|
281
|
+
No → ⬇️
|
|
282
|
+
|
|
283
|
+
4. Is it a core user flow?
|
|
284
|
+
Yes → Write E2E Test ⭐⭐
|
|
285
|
+
No → Done ✅
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## TDD Alternative for AI Era: ATDD (AI-Test-Driven Development)
|
|
289
|
+
|
|
290
|
+
```markdown
|
|
291
|
+
# New development flow
|
|
292
|
+
|
|
293
|
+
1. **Clarify requirements** (Developer)
|
|
294
|
+
"Premium users get 10% discount"
|
|
295
|
+
|
|
296
|
+
2. **Define contracts** (Developer)
|
|
297
|
+
interface DiscountRequest {
|
|
298
|
+
userId: string;
|
|
299
|
+
orderTotal: number;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
interface DiscountResponse {
|
|
303
|
+
originalPrice: number;
|
|
304
|
+
discountedPrice: number;
|
|
305
|
+
discountRate: number;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
3. **Write test scenarios** (Developer or AI)
|
|
309
|
+
test('premium user gets 10% discount', () => {
|
|
310
|
+
// Given: Premium user, 100 order
|
|
311
|
+
// When: Calculate discount
|
|
312
|
+
// Then: 90 (10% discount)
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
4. **AI implements** (AI)
|
|
316
|
+
- Generate code following contracts
|
|
317
|
+
- Write code that passes tests
|
|
318
|
+
|
|
319
|
+
5. **Integration test** (Automated)
|
|
320
|
+
- Verify complete scenarios in CI/CD
|
|
321
|
+
|
|
322
|
+
6. **Refactoring** (AI + Developer)
|
|
323
|
+
- Remove complexity, duplication
|
|
324
|
+
- Verify SRP compliance
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## Language-specific Tools
|
|
328
|
+
|
|
329
|
+
### Python
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Contract Testing
|
|
333
|
+
pip install pydantic
|
|
334
|
+
|
|
335
|
+
# Integration Testing
|
|
336
|
+
pip install pytest pytest-asyncio httpx
|
|
337
|
+
|
|
338
|
+
# Property-Based Testing
|
|
339
|
+
pip install hypothesis
|
|
340
|
+
|
|
341
|
+
# Coverage
|
|
342
|
+
pip install pytest-cov
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### TypeScript/JavaScript
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# Contract Testing
|
|
349
|
+
npm install zod
|
|
350
|
+
|
|
351
|
+
# Integration Testing
|
|
352
|
+
npm install @testing-library/react @testing-library/user-event
|
|
353
|
+
|
|
354
|
+
# Property-Based Testing
|
|
355
|
+
npm install fast-check
|
|
356
|
+
|
|
357
|
+
# E2E Testing
|
|
358
|
+
npm install playwright
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### Dart/Flutter
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
# Integration Testing
|
|
365
|
+
flutter pub add integration_test
|
|
366
|
+
|
|
367
|
+
# Widget Testing
|
|
368
|
+
flutter test
|
|
369
|
+
|
|
370
|
+
# E2E Testing (Flutter Driver)
|
|
371
|
+
flutter drive --target=test_driver/app.dart
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## Anti-patterns
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
# ❌ Testing implementation details (fragile)
|
|
378
|
+
def test_internal_cache_structure():
|
|
379
|
+
service = UserService()
|
|
380
|
+
assert service._cache == {} # Depends on internal implementation
|
|
381
|
+
|
|
382
|
+
# ✅ Testing public API (robust)
|
|
383
|
+
def test_user_data_is_cached_after_first_call():
|
|
384
|
+
service = UserService()
|
|
385
|
+
user1 = service.get_user("123")
|
|
386
|
+
user2 = service.get_user("123")
|
|
387
|
+
assert user1 is user2 # Only verify behavior
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// ❌ Unit tests for every function (excessive)
|
|
392
|
+
test('add function adds two numbers', () => {
|
|
393
|
+
expect(add(1, 2)).toBe(3); // Meaningless
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// ✅ Only test complex logic
|
|
397
|
+
test('calculate shipping cost with multiple conditions', () => {
|
|
398
|
+
const cost = calculateShipping({
|
|
399
|
+
weight: 10,
|
|
400
|
+
distance: 500,
|
|
401
|
+
isPremium: true,
|
|
402
|
+
isExpress: false,
|
|
403
|
+
});
|
|
404
|
+
expect(cost).toBe(45); // Verify complex rules
|
|
405
|
+
});
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Test Coverage Goals
|
|
409
|
+
|
|
410
|
+
```markdown
|
|
411
|
+
# Realistic goals
|
|
412
|
+
|
|
413
|
+
- Contract Coverage: 100% (All APIs have schema definitions)
|
|
414
|
+
- Integration Coverage: 80% (Major business flows)
|
|
415
|
+
- Unit Coverage: Selective (Complex logic only)
|
|
416
|
+
- E2E Coverage: 20-30% (Core user flows)
|
|
417
|
+
|
|
418
|
+
# ❌ Avoid
|
|
419
|
+
- 100% Unit Test Coverage (waste of time)
|
|
420
|
+
- Unit Tests for simple CRUD (Integration is sufficient)
|
|
421
|
+
- Manual testing all edge cases (use Property-based)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Key Summary
|
|
425
|
+
|
|
426
|
+
```markdown
|
|
427
|
+
AI Era Testing Strategy:
|
|
428
|
+
|
|
429
|
+
1. ✅ Contract-First (types/schemas first)
|
|
430
|
+
2. ✅ Integration Testing (real scenarios)
|
|
431
|
+
3. ⚠️ Unit Testing (complex logic only)
|
|
432
|
+
4. ❌ Traditional TDD (inefficient in AI era)
|
|
433
|
+
|
|
434
|
+
Goals:
|
|
435
|
+
- Single Responsibility (SRP)
|
|
436
|
+
- No Duplication (DRY)
|
|
437
|
+
- Reusability
|
|
438
|
+
- Low Complexity
|
|
439
|
+
- Fast Feedback
|
|
440
|
+
```
|