@the-bearded-bear/claude-craft 8.8.1 → 8.8.2
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/Dev/i18n/de/Angular/commands/check-compliance.md +218 -168
- package/Dev/i18n/de/Common/agents/refactoring-specialist.md +146 -69
- package/Dev/i18n/de/Common/commands/add-technology.md +166 -68
- package/Dev/i18n/de/Common/commands/setup-ci.md +216 -33
- package/Dev/i18n/de/Laravel/commands/check-compliance.md +223 -115
- package/Dev/i18n/de/Python/checklists/new-feature.md +319 -44
- package/Dev/i18n/de/React/rules/02-architecture.md +483 -322
- package/Dev/i18n/de/React/rules/03-coding-standards.md +584 -368
- package/Dev/i18n/de/Symfony/commands/check-compliance.md +186 -114
- package/Dev/i18n/de/Symfony/rules/07-testing-symfony.md +679 -10
- package/Dev/i18n/de/UIUX/commands/a11y-component.md +284 -26
- package/Dev/i18n/de/UIUX/commands/design-tokens.md +199 -35
- package/Dev/i18n/de/UIUX/commands/user-flow.md +179 -16
- package/Dev/i18n/de/VueJS/commands/check-compliance.md +227 -102
- package/Dev/i18n/es/Angular/commands/check-compliance.md +217 -167
- package/Dev/i18n/es/Common/commands/add-technology.md +158 -60
- package/Dev/i18n/es/Laravel/commands/check-compliance.md +223 -115
- package/Dev/i18n/es/React/commands/check-testing.md +263 -169
- package/Dev/i18n/es/ReactNative/commands/check-testing.md +256 -198
- package/Dev/i18n/es/Symfony/commands/check-compliance.md +189 -117
- package/Dev/i18n/es/Symfony/commands/check-testing.md +301 -102
- package/Dev/i18n/es/Symfony/commands/migration-plan.md +267 -34
- package/Dev/i18n/es/UIUX/commands/a11y-component.md +274 -16
- package/Dev/i18n/es/UIUX/commands/design-tokens.md +186 -22
- package/Dev/i18n/es/UIUX/commands/user-flow.md +173 -10
- package/Dev/i18n/es/VueJS/commands/check-compliance.md +227 -102
- package/Dev/i18n/fr/Angular/commands/check-compliance.md +217 -167
- package/Dev/i18n/fr/Common/commands/ralph-run.md +138 -60
- package/Dev/i18n/fr/Laravel/commands/check-compliance.md +223 -115
- package/Dev/i18n/fr/React/commands/check-architecture.md +370 -53
- package/Dev/i18n/fr/React/commands/check-code-quality.md +454 -64
- package/Dev/i18n/fr/React/commands/check-testing.md +476 -102
- package/Dev/i18n/fr/Symfony/commands/check-compliance.md +188 -116
- package/Dev/i18n/fr/VueJS/commands/check-compliance.md +227 -102
- package/Dev/i18n/pt/Angular/commands/check-compliance.md +225 -175
- package/Dev/i18n/pt/Common/agents/ralph-conductor.md +211 -30
- package/Dev/i18n/pt/Common/commands/add-technology.md +149 -51
- package/Dev/i18n/pt/Common/commands/ralph-run.md +239 -35
- package/Dev/i18n/pt/Flutter/commands/analyze-performance.md +331 -46
- package/Dev/i18n/pt/Flutter/commands/check-compliance.md +234 -29
- package/Dev/i18n/pt/Flutter/commands/generate-feature.md +526 -51
- package/Dev/i18n/pt/Flutter/commands/generate-widget.md +515 -27
- package/Dev/i18n/pt/Flutter/commands/golden-update.md +322 -46
- package/Dev/i18n/pt/Flutter/commands/localization-check.md +278 -37
- package/Dev/i18n/pt/Laravel/commands/check-compliance.md +212 -104
- package/Dev/i18n/pt/React/commands/accessibility-check.md +151 -42
- package/Dev/i18n/pt/React/commands/bundle-analyze.md +300 -25
- package/Dev/i18n/pt/React/commands/check-architecture.md +369 -34
- package/Dev/i18n/pt/React/commands/check-code-quality.md +440 -34
- package/Dev/i18n/pt/React/commands/check-compliance.md +232 -62
- package/Dev/i18n/pt/React/commands/check-security.md +370 -31
- package/Dev/i18n/pt/React/commands/check-testing.md +473 -43
- package/Dev/i18n/pt/React/commands/generate-component.md +454 -19
- package/Dev/i18n/pt/React/commands/generate-hook.md +425 -24
- package/Dev/i18n/pt/React/commands/storybook-story.md +520 -35
- package/Dev/i18n/pt/ReactNative/commands/app-size.md +358 -387
- package/Dev/i18n/pt/ReactNative/commands/check-code-quality.md +246 -75
- package/Dev/i18n/pt/ReactNative/commands/check-compliance.md +191 -85
- package/Dev/i18n/pt/ReactNative/commands/check-security.md +363 -115
- package/Dev/i18n/pt/ReactNative/commands/check-testing.md +269 -79
- package/Dev/i18n/pt/ReactNative/commands/generate-screen.md +491 -324
- package/Dev/i18n/pt/ReactNative/commands/native-module.md +539 -82
- package/Dev/i18n/pt/ReactNative/commands/store-prepare.md +429 -185
- package/Dev/i18n/pt/ReactNative/rules/02-architecture.md +1084 -31
- package/Dev/i18n/pt/Symfony/commands/check-compliance.md +195 -123
- package/Dev/i18n/pt/UIUX/commands/a11y-audit.md +208 -24
- package/Dev/i18n/pt/UIUX/commands/a11y-component.md +281 -23
- package/Dev/i18n/pt/UIUX/commands/design-tokens.md +197 -33
- package/Dev/i18n/pt/UIUX/commands/user-flow.md +183 -20
- package/Dev/i18n/pt/VueJS/commands/check-compliance.md +228 -103
- package/Dev/i18n/pt/Workflow/commands/analyze.md +147 -146
- package/Dev/i18n/pt/Workflow/commands/design.md +205 -204
- package/Dev/i18n/pt/Workflow/commands/implement.md +184 -184
- package/Project/i18n/de/Sprint/commands/dev.md +339 -86
- package/Project/i18n/es/Sprint/commands/dev.md +342 -91
- package/Project/i18n/pt/Sprint/commands/dev.md +343 -92
- package/bundles/cursor/.cursorrules +1 -1
- package/bundles/windsurf/.windsurfrules +1 -1
- package/package.json +1 -1
|
@@ -1,62 +1,492 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Verificação da Estratégia de Testes
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Verificação da Estratégia de Testes
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Verifique se a aplicação React possui cobertura de testes abrangente e segue as melhores práticas de teste.
|
|
8
8
|
|
|
9
9
|
## O Que Este Comando Faz
|
|
10
10
|
|
|
11
|
-
1. **
|
|
12
|
-
- Verificar cobertura de testes
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Verificar
|
|
16
|
-
- Analisar
|
|
17
|
-
|
|
18
|
-
2. **
|
|
19
|
-
- Cobertura de
|
|
20
|
-
-
|
|
21
|
-
- Tempo de
|
|
22
|
-
-
|
|
23
|
-
- Caminhos
|
|
24
|
-
|
|
25
|
-
3. **
|
|
26
|
-
-
|
|
27
|
-
- Testes
|
|
28
|
-
-
|
|
29
|
-
-
|
|
11
|
+
1. **Análise de Testes**
|
|
12
|
+
- Verificar a cobertura de testes
|
|
13
|
+
- Validar a qualidade dos testes
|
|
14
|
+
- Confirmar os padrões de teste utilizados
|
|
15
|
+
- Verificar a organização dos testes
|
|
16
|
+
- Analisar o desempenho dos testes
|
|
17
|
+
|
|
18
|
+
2. **Métricas Medidas**
|
|
19
|
+
- Cobertura de código (linhas, funções, branches)
|
|
20
|
+
- Quantidade de testes por tipo (unitário, integração, e2e)
|
|
21
|
+
- Tempo de execução dos testes
|
|
22
|
+
- Detecção de testes instáveis (flaky tests)
|
|
23
|
+
- Caminhos críticos sem cobertura
|
|
24
|
+
|
|
25
|
+
3. **Relatório Gerado**
|
|
26
|
+
- Relatório de cobertura
|
|
27
|
+
- Testes ausentes
|
|
28
|
+
- Pontuação de qualidade dos testes
|
|
29
|
+
- Recomendações
|
|
30
|
+
|
|
31
|
+
## Como Usar
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# Executar todos os testes com cobertura
|
|
35
|
+
npm run test:coverage
|
|
36
|
+
|
|
37
|
+
# Modo observação
|
|
38
|
+
npm run test:watch
|
|
39
|
+
|
|
40
|
+
# Modo UI
|
|
41
|
+
npm run test:ui
|
|
42
|
+
|
|
43
|
+
# Testes E2E
|
|
44
|
+
npm run test:e2e
|
|
45
|
+
```
|
|
30
46
|
|
|
31
47
|
## Modo Plano
|
|
32
48
|
|
|
33
|
-
> O modo plano é ativado automaticamente quando o escopo abrange vários módulos ou
|
|
49
|
+
> O modo plano é ativado automaticamente quando o escopo abrange vários módulos ou exige investigação transversal.
|
|
34
50
|
|
|
35
|
-
##
|
|
51
|
+
## Análise de Cobertura de Testes
|
|
52
|
+
|
|
53
|
+
### Metas de Cobertura
|
|
36
54
|
|
|
37
55
|
```json
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
56
|
+
// vitest.config.ts
|
|
57
|
+
export default defineConfig({
|
|
58
|
+
test: {
|
|
59
|
+
coverage: {
|
|
60
|
+
provider: 'v8',
|
|
61
|
+
reporter: ['text', 'json', 'html', 'lcov'],
|
|
62
|
+
lines: 80,
|
|
63
|
+
functions: 80,
|
|
64
|
+
branches: 75,
|
|
65
|
+
statements: 80,
|
|
66
|
+
exclude: [
|
|
67
|
+
'node_modules/',
|
|
68
|
+
'src/test/',
|
|
69
|
+
'**/*.test.{ts,tsx}',
|
|
70
|
+
'**/*.spec.{ts,tsx}',
|
|
71
|
+
'**/*.d.ts',
|
|
72
|
+
'vite.config.ts'
|
|
73
|
+
]
|
|
74
|
+
}
|
|
44
75
|
}
|
|
45
|
-
}
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Verificar Cobertura
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Gerar relatório de cobertura
|
|
83
|
+
npm run test:coverage
|
|
84
|
+
|
|
85
|
+
# Visualizar relatório HTML
|
|
86
|
+
open coverage/index.html
|
|
87
|
+
|
|
88
|
+
# Verificar limite específico
|
|
89
|
+
npm run test:coverage -- --coverage.lines=90
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Tipos de Testes
|
|
93
|
+
|
|
94
|
+
### 1. Testes Unitários (70% dos testes)
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// Button.test.tsx
|
|
98
|
+
import { render, screen } from '@testing-library/react';
|
|
99
|
+
import { userEvent } from '@testing-library/user-event';
|
|
100
|
+
import { Button } from './Button';
|
|
101
|
+
|
|
102
|
+
describe('Button', () => {
|
|
103
|
+
it('deve renderizar com texto', () => {
|
|
104
|
+
render(<Button>Clique aqui</Button>);
|
|
105
|
+
expect(screen.getByRole('button')).toHaveTextContent('Clique aqui');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('deve chamar onClick ao ser clicado', async () => {
|
|
109
|
+
const handleClick = vi.fn();
|
|
110
|
+
const user = userEvent.setup();
|
|
111
|
+
|
|
112
|
+
render(<Button onClick={handleClick}>Clique aqui</Button>);
|
|
113
|
+
await user.click(screen.getByRole('button'));
|
|
114
|
+
|
|
115
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('deve estar desabilitado quando a prop disabled for true', () => {
|
|
119
|
+
render(<Button disabled>Clique aqui</Button>);
|
|
120
|
+
expect(screen.getByRole('button')).toBeDisabled();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 2. Testes de Integração (20% dos testes)
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// UserManagement.integration.test.tsx
|
|
129
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
130
|
+
import { userEvent } from '@testing-library/user-event';
|
|
131
|
+
import { UserManagement } from './UserManagement';
|
|
132
|
+
|
|
133
|
+
describe('Integração UserManagement', () => {
|
|
134
|
+
it('deve concluir o fluxo completo de criação de usuário', async () => {
|
|
135
|
+
const user = userEvent.setup();
|
|
136
|
+
render(<UserManagement />);
|
|
137
|
+
|
|
138
|
+
// Aguardar carregamento
|
|
139
|
+
await waitFor(() => {
|
|
140
|
+
expect(screen.getByText('John Doe')).toBeInTheDocument();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
// Clicar no botão adicionar
|
|
144
|
+
await user.click(screen.getByRole('button', { name: /add user/i }));
|
|
145
|
+
|
|
146
|
+
// Preencher formulário
|
|
147
|
+
await user.type(screen.getByLabelText(/name/i), 'Novo Usuário');
|
|
148
|
+
await user.type(screen.getByLabelText(/email/i), 'novo@example.com');
|
|
149
|
+
|
|
150
|
+
// Enviar
|
|
151
|
+
await user.click(screen.getByRole('button', { name: /save/i }));
|
|
152
|
+
|
|
153
|
+
// Verificar
|
|
154
|
+
await waitFor(() => {
|
|
155
|
+
expect(screen.getByText('Novo Usuário')).toBeInTheDocument();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 3. Testes E2E (10% dos testes)
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// auth.spec.ts (Playwright)
|
|
165
|
+
import { test, expect } from '@playwright/test';
|
|
166
|
+
|
|
167
|
+
test.describe('Autenticação', () => {
|
|
168
|
+
test('deve fazer login com sucesso', async ({ page }) => {
|
|
169
|
+
await page.goto('/');
|
|
170
|
+
await page.click('text=Login');
|
|
171
|
+
|
|
172
|
+
await page.fill('input[name="email"]', 'user@example.com');
|
|
173
|
+
await page.fill('input[name="password"]', 'password123');
|
|
174
|
+
await page.click('button[type="submit"]');
|
|
175
|
+
|
|
176
|
+
await expect(page).toHaveURL('/dashboard');
|
|
177
|
+
await expect(page.locator('text=Welcome')).toBeVisible();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Verificações de Qualidade dos Testes
|
|
183
|
+
|
|
184
|
+
### 1. Padrão AAA
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
// ✅ BOM - Arrange, Act, Assert
|
|
188
|
+
it('deve incrementar o contador', async () => {
|
|
189
|
+
// Arrange (Preparar)
|
|
190
|
+
const user = userEvent.setup();
|
|
191
|
+
render(<Counter initialCount={0} />);
|
|
192
|
+
|
|
193
|
+
// Act (Agir)
|
|
194
|
+
await user.click(screen.getByRole('button', { name: /increment/i }));
|
|
195
|
+
|
|
196
|
+
// Assert (Verificar)
|
|
197
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 2. Testar Comportamento, Não Implementação
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
// ❌ RUIM - Testar implementação
|
|
205
|
+
it('deve chamar setState', () => {
|
|
206
|
+
const setStateSpy = vi.spyOn(React, 'useState');
|
|
207
|
+
// ...
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// ✅ BOM - Testar comportamento
|
|
211
|
+
it('deve exibir o contador incrementado', async () => {
|
|
212
|
+
const user = userEvent.setup();
|
|
213
|
+
render(<Counter />);
|
|
214
|
+
|
|
215
|
+
await user.click(screen.getByRole('button', { name: /increment/i }));
|
|
216
|
+
|
|
217
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### 3. Nomes de Teste Descritivos
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// ❌ RUIM - Nomes vagos
|
|
225
|
+
it('funciona');
|
|
226
|
+
it('teste 1');
|
|
227
|
+
it('deve renderizar');
|
|
228
|
+
|
|
229
|
+
// ✅ BOM - Nomes descritivos
|
|
230
|
+
it('deve exibir o nome do usuário quando os dados são carregados');
|
|
231
|
+
it('deve mostrar mensagem de erro quando o e-mail é inválido');
|
|
232
|
+
it('deve desabilitar o botão de envio enquanto o formulário está sendo submetido');
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 4. Prioridade de Consultas
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
// ✅ BOM - Consultas acessíveis (melhor opção)
|
|
239
|
+
screen.getByRole('button', { name: /submit/i });
|
|
240
|
+
screen.getByLabelText(/email/i);
|
|
241
|
+
screen.getByText(/welcome/i);
|
|
242
|
+
|
|
243
|
+
// ⚠️ OK - Consultas semânticas
|
|
244
|
+
screen.getByAltText(/profile/i);
|
|
245
|
+
screen.getByTitle(/close/i);
|
|
246
|
+
|
|
247
|
+
// ❌ EVITAR - IDs de teste (último recurso)
|
|
248
|
+
screen.getByTestId('custom-element');
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Organização dos Testes
|
|
252
|
+
|
|
253
|
+
### Estrutura de Pastas
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
src/
|
|
257
|
+
├── components/
|
|
258
|
+
│ └── Button/
|
|
259
|
+
│ ├── Button.tsx
|
|
260
|
+
│ ├── Button.test.tsx # Testes unitários
|
|
261
|
+
│ └── Button.stories.tsx # Storybook
|
|
262
|
+
│
|
|
263
|
+
├── features/
|
|
264
|
+
│ └── users/
|
|
265
|
+
│ ├── components/
|
|
266
|
+
│ │ └── UserList/
|
|
267
|
+
│ │ ├── UserList.tsx
|
|
268
|
+
│ │ └── UserList.test.tsx
|
|
269
|
+
│ ├── hooks/
|
|
270
|
+
│ │ └── useUsers.test.ts
|
|
271
|
+
│ └── UserManagement.integration.test.tsx # Integração
|
|
272
|
+
│
|
|
273
|
+
├── test/
|
|
274
|
+
│ ├── setup.ts # Configuração dos testes
|
|
275
|
+
│ ├── mocks/
|
|
276
|
+
│ │ └── handlers.ts # Handlers MSW
|
|
277
|
+
│ └── utils/
|
|
278
|
+
│ └── test-utils.tsx # Utilitários de teste
|
|
279
|
+
│
|
|
280
|
+
└── e2e/ # Testes E2E
|
|
281
|
+
├── auth.spec.ts
|
|
282
|
+
└── users.spec.ts
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Utilitários de Teste
|
|
286
|
+
|
|
287
|
+
```typescript
|
|
288
|
+
// test/utils/test-utils.tsx
|
|
289
|
+
import { render, RenderOptions } from '@testing-library/react';
|
|
290
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
291
|
+
import { BrowserRouter } from 'react-router-dom';
|
|
292
|
+
|
|
293
|
+
const AllProviders = ({ children }: { children: React.ReactNode }) => {
|
|
294
|
+
const queryClient = new QueryClient({
|
|
295
|
+
defaultOptions: {
|
|
296
|
+
queries: { retry: false },
|
|
297
|
+
mutations: { retry: false }
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
return (
|
|
302
|
+
<QueryClientProvider client={queryClient}>
|
|
303
|
+
<BrowserRouter>{children}</BrowserRouter>
|
|
304
|
+
</QueryClientProvider>
|
|
305
|
+
);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
export const renderWithProviders = (
|
|
309
|
+
ui: React.ReactElement,
|
|
310
|
+
options?: Omit<RenderOptions, 'wrapper'>
|
|
311
|
+
) => render(ui, { wrapper: AllProviders, ...options });
|
|
312
|
+
|
|
313
|
+
export * from '@testing-library/react';
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Problemas Comuns em Testes
|
|
317
|
+
|
|
318
|
+
### Problema 1: Testes Instáveis (Flaky Tests)
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
// ❌ RUIM - Condição de corrida
|
|
322
|
+
it('deve carregar dados', () => {
|
|
323
|
+
render(<DataComponent />);
|
|
324
|
+
expect(screen.getByText('Dados carregados')).toBeInTheDocument();
|
|
325
|
+
// Falha aleatoriamente se os dados demoram a carregar
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// ✅ BOM - Aguardar os dados
|
|
329
|
+
it('deve carregar dados', async () => {
|
|
330
|
+
render(<DataComponent />);
|
|
331
|
+
await waitFor(() => {
|
|
332
|
+
expect(screen.getByText('Dados carregados')).toBeInTheDocument();
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Problema 2: Avisos de Act Ausente
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// ❌ RUIM - Atualização de estado fora do act
|
|
341
|
+
it('deve atualizar o contador', () => {
|
|
342
|
+
const { result } = renderHook(() => useCounter());
|
|
343
|
+
result.current.increment(); // Aviso!
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
// ✅ BOM - Envolver no act
|
|
347
|
+
it('deve atualizar o contador', () => {
|
|
348
|
+
const { result } = renderHook(() => useCounter());
|
|
349
|
+
act(() => {
|
|
350
|
+
result.current.increment();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Problema 3: Limpeza Não Realizada
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
// ✅ BOM - Limpeza automática
|
|
359
|
+
import { cleanup } from '@testing-library/react';
|
|
360
|
+
|
|
361
|
+
afterEach(() => {
|
|
362
|
+
cleanup();
|
|
363
|
+
});
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
## MSW (Mock Service Worker)
|
|
367
|
+
|
|
368
|
+
### Configuração
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
// test/mocks/handlers.ts
|
|
372
|
+
import { http, HttpResponse } from 'msw';
|
|
373
|
+
|
|
374
|
+
export const handlers = [
|
|
375
|
+
http.get('/api/users', () => {
|
|
376
|
+
return HttpResponse.json([
|
|
377
|
+
{ id: '1', name: 'John Doe' },
|
|
378
|
+
{ id: '2', name: 'Jane Smith' }
|
|
379
|
+
]);
|
|
380
|
+
}),
|
|
381
|
+
|
|
382
|
+
http.post('/api/users', async ({ request }) => {
|
|
383
|
+
const newUser = await request.json();
|
|
384
|
+
return HttpResponse.json({ id: '3', ...newUser }, { status: 201 });
|
|
385
|
+
})
|
|
386
|
+
];
|
|
387
|
+
|
|
388
|
+
// test/mocks/server.ts
|
|
389
|
+
import { setupServer } from 'msw/node';
|
|
390
|
+
import { handlers } from './handlers';
|
|
391
|
+
|
|
392
|
+
export const server = setupServer(...handlers);
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Uso
|
|
396
|
+
|
|
397
|
+
```typescript
|
|
398
|
+
// test/setup.ts
|
|
399
|
+
import { beforeAll, afterEach, afterAll } from 'vitest';
|
|
400
|
+
import { server } from './mocks/server';
|
|
401
|
+
|
|
402
|
+
beforeAll(() => server.listen());
|
|
403
|
+
afterEach(() => server.resetHandlers());
|
|
404
|
+
afterAll(() => server.close());
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## Testes de Desempenho
|
|
408
|
+
|
|
409
|
+
```typescript
|
|
410
|
+
// Verificar desempenho de renderização
|
|
411
|
+
it('deve renderizar a lista de forma eficiente', () => {
|
|
412
|
+
const start = performance.now();
|
|
413
|
+
|
|
414
|
+
render(<LargeList items={items} />);
|
|
415
|
+
|
|
416
|
+
const duration = performance.now() - start;
|
|
417
|
+
expect(duration).toBeLessThan(100); // ms
|
|
418
|
+
});
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Relatórios de Teste
|
|
422
|
+
|
|
423
|
+
### Relatório de Cobertura
|
|
424
|
+
|
|
425
|
+
```bash
|
|
426
|
+
# Gerar relatório HTML
|
|
427
|
+
npm run test:coverage
|
|
428
|
+
|
|
429
|
+
# Visualizar relatório
|
|
430
|
+
open coverage/index.html
|
|
431
|
+
|
|
432
|
+
# CI: Enviar para o Codecov
|
|
433
|
+
bash <(curl -s https://codecov.io/bash)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Resultados dos Testes no CI
|
|
437
|
+
|
|
438
|
+
```yaml
|
|
439
|
+
# .github/workflows/test.yml
|
|
440
|
+
name: Tests
|
|
441
|
+
|
|
442
|
+
on: [push, pull_request]
|
|
443
|
+
|
|
444
|
+
jobs:
|
|
445
|
+
test:
|
|
446
|
+
runs-on: ubuntu-latest
|
|
447
|
+
steps:
|
|
448
|
+
- uses: actions/checkout@v3
|
|
449
|
+
- uses: actions/setup-node@v3
|
|
450
|
+
|
|
451
|
+
- name: Instalar dependências
|
|
452
|
+
run: npm ci
|
|
453
|
+
|
|
454
|
+
- name: Executar testes
|
|
455
|
+
run: npm run test:coverage
|
|
456
|
+
|
|
457
|
+
- name: Enviar cobertura
|
|
458
|
+
uses: codecov/codecov-action@v3
|
|
46
459
|
```
|
|
47
460
|
|
|
48
461
|
## Checklist de Testes
|
|
49
462
|
|
|
50
|
-
- [ ] Testes
|
|
51
|
-
- [ ] Testes
|
|
52
|
-
- [ ] Testes
|
|
53
|
-
- [ ] Testes de
|
|
54
|
-
- [ ] Testes E2E para fluxos
|
|
463
|
+
- [ ] Testes unitários para todos os componentes
|
|
464
|
+
- [ ] Testes unitários para todos os hooks
|
|
465
|
+
- [ ] Testes unitários para todos os utilitários
|
|
466
|
+
- [ ] Testes de integração para as features
|
|
467
|
+
- [ ] Testes E2E para os fluxos críticos
|
|
55
468
|
- [ ] Cobertura > 80%
|
|
56
|
-
- [ ] Sem testes
|
|
57
|
-
- [ ] Testes
|
|
58
|
-
- [ ] MSW para
|
|
59
|
-
- [ ]
|
|
60
|
-
- [ ] Testes seguem
|
|
61
|
-
- [ ] Testes
|
|
62
|
-
- [ ] Testes
|
|
469
|
+
- [ ] Sem testes instáveis (flaky tests)
|
|
470
|
+
- [ ] Testes rápidos (< 1s cada)
|
|
471
|
+
- [ ] MSW para simulação de API
|
|
472
|
+
- [ ] Utilitários de teste extraídos
|
|
473
|
+
- [ ] Testes seguem o padrão AAA
|
|
474
|
+
- [ ] Testes possuem nomes descritivos
|
|
475
|
+
- [ ] Testes utilizam consultas acessíveis
|
|
476
|
+
|
|
477
|
+
## Ferramentas
|
|
478
|
+
|
|
479
|
+
- **Vitest**: Executor de testes unitários
|
|
480
|
+
- **React Testing Library**: Testes de componentes
|
|
481
|
+
- **Playwright**: Testes E2E
|
|
482
|
+
- **MSW**: Simulação de API
|
|
483
|
+
- **Testing Library User Event**: Interações do usuário
|
|
484
|
+
- **Codecov**: Relatório de cobertura
|
|
485
|
+
|
|
486
|
+
## Recursos
|
|
487
|
+
|
|
488
|
+
- [React Testing Library](https://testing-library.com/react)
|
|
489
|
+
- [Documentação do Vitest](https://vitest.dev/)
|
|
490
|
+
- [Documentação do Playwright](https://playwright.dev/)
|
|
491
|
+
- [Documentação do MSW](https://mswjs.io/)
|
|
492
|
+
- [Melhores Práticas de Teste](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
|