senior-qa
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSenior QA Engineer
资深QA工程师
Test automation, coverage analysis, and quality assurance patterns for React and Next.js applications.
面向React和Next.js应用的测试自动化、覆盖率分析及质量保障方案。
Table of Contents
目录
Quick Start
快速开始
bash
undefinedbash
undefinedGenerate Jest test stubs for React components
Generate Jest test stubs for React components
python scripts/test_suite_generator.py src/components/ --output tests/
python scripts/test_suite_generator.py src/components/ --output tests/
Analyze test coverage from Jest/Istanbul reports
Analyze test coverage from Jest/Istanbul reports
python scripts/coverage_analyzer.py coverage/coverage-final.json --threshold 80
python scripts/coverage_analyzer.py coverage/coverage-final.json --threshold 80
Scaffold Playwright E2E tests for Next.js routes
Scaffold Playwright E2E tests for Next.js routes
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/
---python scripts/e2e_test_scaffolder.py src/app/ --output e2e/
---Tools Overview
工具概览
1. Test Suite Generator
1. 测试套件生成器
Scans React/TypeScript components and generates Jest + React Testing Library test stubs with proper structure.
Input: Source directory containing React components
Output: Test files with describe blocks, render tests, interaction tests
Usage:
bash
undefined扫描React/TypeScript组件,生成结构规范的Jest + React Testing Library测试桩文件。
输入: 包含React组件的源码目录
输出: 带有describe块、渲染测试、交互测试的测试文件
用法:
bash
undefinedBasic usage - scan components and generate tests
Basic usage - scan components and generate tests
python scripts/test_suite_generator.py src/components/ --output tests/
python scripts/test_suite_generator.py src/components/ --output tests/
Output:
Output:
Scanning: src/components/
Scanning: src/components/
Found 24 React components
Found 24 React components
Generated tests:
Generated tests:
tests/Button.test.tsx (render, click handler, disabled state)
tests/Button.test.tsx (render, click handler, disabled state)
tests/Modal.test.tsx (render, open/close, keyboard events)
tests/Modal.test.tsx (render, open/close, keyboard events)
tests/Form.test.tsx (render, validation, submission)
tests/Form.test.tsx (render, validation, submission)
...
...
Summary: 24 test files, 87 test cases
Summary: 24 test files, 87 test cases
Include accessibility tests
Include accessibility tests
python scripts/test_suite_generator.py src/ --output tests/ --include-a11y
python scripts/test_suite_generator.py src/ --output tests/ --include-a11y
Generate with custom template
Generate with custom template
python scripts/test_suite_generator.py src/ --template custom-template.tsx
**Supported Patterns:**
- Functional components with hooks
- Components with Context providers
- Components with data fetching
- Form components with validation
---python scripts/test_suite_generator.py src/ --template custom-template.tsx
**支持的模式:**
- 带hooks的函数式组件
- 带Context提供者的组件
- 带数据获取的组件
- 带验证的表单组件
---2. Coverage Analyzer
2. 覆盖率分析器
Parses Jest/Istanbul coverage reports and identifies gaps, uncovered branches, and provides actionable recommendations.
Input: Coverage report (JSON or LCOV format)
Output: Coverage analysis with recommendations
Usage:
bash
undefined解析Jest/Istanbul覆盖率报告,识别测试缺口、未覆盖分支,并提供可执行的改进建议。
输入: 覆盖率报告(JSON或LCOV格式)
输出: 包含改进建议的覆盖率分析结果
用法:
bash
undefinedAnalyze coverage report
Analyze coverage report
python scripts/coverage_analyzer.py coverage/coverage-final.json
python scripts/coverage_analyzer.py coverage/coverage-final.json
Output:
Output:
=== Coverage Analysis Report ===
=== Coverage Analysis Report ===
Overall: 72.4% (target: 80%)
Overall: 72.4% (target: 80%)
BY TYPE:
BY TYPE:
Statements: 74.2%
Statements: 74.2%
Branches: 68.1%
Branches: 68.1%
Functions: 71.8%
Functions: 71.8%
Lines: 73.5%
Lines: 73.5%
CRITICAL GAPS (uncovered business logic):
CRITICAL GAPS (uncovered business logic):
src/services/payment.ts:45-67 - Payment processing
src/services/payment.ts:45-67 - Payment processing
src/hooks/useAuth.ts:23-41 - Authentication flow
src/hooks/useAuth.ts:23-41 - Authentication flow
RECOMMENDATIONS:
RECOMMENDATIONS:
1. Add tests for payment service error handling
1. Add tests for payment service error handling
2. Cover authentication edge cases
2. Cover authentication edge cases
3. Test form validation branches
3. Test form validation branches
Files below threshold (80%):
Files below threshold (80%):
src/components/Checkout.tsx: 45%
src/components/Checkout.tsx: 45%
src/services/api.ts: 62%
src/services/api.ts: 62%
Enforce threshold (exit 1 if below)
Enforce threshold (exit 1 if below)
python scripts/coverage_analyzer.py coverage/ --threshold 80 --strict
python scripts/coverage_analyzer.py coverage/ --threshold 80 --strict
Generate HTML report
Generate HTML report
python scripts/coverage_analyzer.py coverage/ --format html --output report.html
---python scripts/coverage_analyzer.py coverage/ --format html --output report.html
---3. E2E Test Scaffolder
3. E2E测试搭建工具
Scans Next.js pages/app directory and generates Playwright test files with common interactions.
Input: Next.js pages or app directory
Output: Playwright test files organized by route
Usage:
bash
undefined扫描Next.js页面/app目录,生成包含常见交互逻辑的Playwright测试文件。
输入: Next.js pages或app目录
输出: 按路由组织的Playwright测试文件
用法:
bash
undefinedScaffold E2E tests for Next.js App Router
Scaffold E2E tests for Next.js App Router
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/
Output:
Output:
Scanning: src/app/
Scanning: src/app/
Found 12 routes
Found 12 routes
Generated E2E tests:
Generated E2E tests:
e2e/home.spec.ts (navigation, hero section)
e2e/home.spec.ts (navigation, hero section)
e2e/auth/login.spec.ts (form submission, validation)
e2e/auth/login.spec.ts (form submission, validation)
e2e/auth/register.spec.ts (registration flow)
e2e/auth/register.spec.ts (registration flow)
e2e/dashboard.spec.ts (authenticated routes)
e2e/dashboard.spec.ts (authenticated routes)
e2e/products/[id].spec.ts (dynamic routes)
e2e/products/[id].spec.ts (dynamic routes)
...
...
Generated: playwright.config.ts
Generated: playwright.config.ts
Generated: e2e/fixtures/auth.ts
Generated: e2e/fixtures/auth.ts
Include Page Object Model classes
Include Page Object Model classes
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/ --include-pom
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/ --include-pom
Generate for specific routes
Generate for specific routes
python scripts/e2e_test_scaffolder.py src/app/ --routes "/login,/dashboard,/checkout"
---python scripts/e2e_test_scaffolder.py src/app/ --routes "/login,/dashboard,/checkout"
---QA Workflows
QA工作流
Unit Test Generation Workflow
单元测试生成工作流
Use when setting up tests for new or existing React components.
Step 1: Scan project for untested components
bash
python scripts/test_suite_generator.py src/components/ --scan-onlyStep 2: Generate test stubs
bash
python scripts/test_suite_generator.py src/components/ --output __tests__/Step 3: Review and customize generated tests
typescript
// __tests__/Button.test.tsx (generated)
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from '../src/components/Button';
describe('Button', () => {
it('renders with label', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click</Button>);
fireEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
// TODO: Add your specific test cases
});Step 4: Run tests and check coverage
bash
npm test -- --coverage
python scripts/coverage_analyzer.py coverage/coverage-final.json适用于为新的或已有的React组件搭建测试用例时。
步骤1:扫描项目中的未测试组件
bash
python scripts/test_suite_generator.py src/components/ --scan-only步骤2:生成测试桩文件
bash
python scripts/test_suite_generator.py src/components/ --output __tests__/步骤3:审阅并自定义生成的测试用例
typescript
// __tests__/Button.test.tsx (generated)
import { render, screen, fireEvent } from '@testing-library/react';
import { Button } from '../src/components/Button';
describe('Button', () => {
it('renders with label', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button', { name: /click me/i })).toBeInTheDocument();
});
it('calls onClick when clicked', () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click</Button>);
fireEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
// TODO: Add your specific test cases
});步骤4:运行测试并检查覆盖率
bash
npm test -- --coverage
python scripts/coverage_analyzer.py coverage/coverage-final.jsonCoverage Analysis Workflow
覆盖率分析工作流
Use when improving test coverage or preparing for release.
Step 1: Generate coverage report
bash
npm test -- --coverage --coverageReporters=jsonStep 2: Analyze coverage gaps
bash
python scripts/coverage_analyzer.py coverage/coverage-final.json --threshold 80Step 3: Identify critical paths
bash
python scripts/coverage_analyzer.py coverage/ --critical-pathsStep 4: Generate missing test stubs
bash
python scripts/test_suite_generator.py src/ --uncovered-only --output __tests__/Step 5: Verify improvement
bash
npm test -- --coverage
python scripts/coverage_analyzer.py coverage/ --compare previous-coverage.json适用于提升测试覆盖率或为发布做准备时。
步骤1:生成覆盖率报告
bash
npm test -- --coverage --coverageReporters=json步骤2:分析覆盖率缺口
bash
python scripts/coverage_analyzer.py coverage/coverage-final.json --threshold 80步骤3:识别关键路径
bash
python scripts/coverage_analyzer.py coverage/ --critical-paths步骤4:生成缺失的测试桩文件
bash
python scripts/test_suite_generator.py src/ --uncovered-only --output __tests__/步骤5:验证改进效果
bash
npm test -- --coverage
python scripts/coverage_analyzer.py coverage/ --compare previous-coverage.jsonE2E Test Setup Workflow
E2E测试搭建工作流
Use when setting up Playwright for a Next.js project.
Step 1: Initialize Playwright (if not installed)
bash
npm init playwright@latestStep 2: Scaffold E2E tests from routes
bash
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/Step 3: Configure authentication fixtures
typescript
// e2e/fixtures/auth.ts (generated)
import { test as base } from '@playwright/test';
export const test = base.extend({
authenticatedPage: async ({ page }, use) => {
await page.goto('/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password');
await page.click('button[type="submit"]');
await page.waitForURL('/dashboard');
await use(page);
},
});Step 4: Run E2E tests
bash
npx playwright test
npx playwright show-reportStep 5: Add to CI pipeline
yaml
undefined适用于为Next.js项目配置Playwright时。
步骤1:初始化Playwright(若未安装)
bash
npm init playwright@latest步骤2:根据路由搭建E2E测试
bash
python scripts/e2e_test_scaffolder.py src/app/ --output e2e/步骤3:配置认证fixtures
typescript
// e2e/fixtures/auth.ts (generated)
import { test as base } from '@playwright/test';
export const test = base.extend({
authenticatedPage: async ({ page }, use) => {
await page.goto('/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password');
await page.click('button[type="submit"]');
await page.waitForURL('/dashboard');
await use(page);
},
});步骤4:运行E2E测试
bash
npx playwright test
npx playwright show-report步骤5:添加到CI流水线
yaml
undefined.github/workflows/e2e.yml
.github/workflows/e2e.yml
- name: Run E2E tests run: npx playwright test
- name: Upload report uses: actions/upload-artifact@v3 with: name: playwright-report path: playwright-report/
---- name: Run E2E tests run: npx playwright test
- name: Upload report uses: actions/upload-artifact@v3 with: name: playwright-report path: playwright-report/
---Reference Documentation
参考文档
| File | Contains | Use When |
|---|---|---|
| Test pyramid, testing types, coverage targets, CI/CD integration | Designing test strategy |
| Page Object Model, mocking (MSW), fixtures, async patterns | Writing test code |
| Testable code, flaky tests, debugging, quality metrics | Improving test quality |
| 文件 | 内容 | 使用场景 |
|---|---|---|
| 测试金字塔、测试类型、覆盖率目标、CI/CD集成 | 设计测试策略时 |
| Page Object Model、Mocking(MSW)、fixtures、异步模式 | 编写测试代码时 |
| 可测试代码、不稳定测试、调试、质量指标 | 提升测试质量时 |
Common Patterns Quick Reference
常用模式速查
React Testing Library Queries
React Testing Library 查询方式
typescript
// Preferred (accessible)
screen.getByRole('button', { name: /submit/i })
screen.getByLabelText(/email/i)
screen.getByPlaceholderText(/search/i)
// Fallback
screen.getByTestId('custom-element')typescript
// Preferred (accessible)
screen.getByRole('button', { name: /submit/i })
screen.getByLabelText(/email/i)
screen.getByPlaceholderText(/search/i)
// Fallback
screen.getByTestId('custom-element')Async Testing
异步测试
typescript
// Wait for element
await screen.findByText(/loaded/i);
// Wait for removal
await waitForElementToBeRemoved(() => screen.queryByText(/loading/i));
// Wait for condition
await waitFor(() => {
expect(mockFn).toHaveBeenCalled();
});typescript
// Wait for element
await screen.findByText(/loaded/i);
// Wait for removal
await waitForElementToBeRemoved(() => screen.queryByText(/loading/i));
// Wait for condition
await waitFor(() => {
expect(mockFn).toHaveBeenCalled();
});Mocking with MSW
使用MSW进行Mocking
typescript
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
rest.get('/api/users', (req, res, ctx) => {
return res(ctx.json([{ id: 1, name: 'John' }]));
})
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());typescript
import { rest } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
rest.get('/api/users', (req, res, ctx) => {
return res(ctx.json([{ id: 1, name: 'John' }]));
})
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());Playwright Locators
Playwright 定位器
typescript
// Preferred
page.getByRole('button', { name: 'Submit' })
page.getByLabel('Email')
page.getByText('Welcome')
// Chaining
page.getByRole('listitem').filter({ hasText: 'Product' })typescript
// Preferred
page.getByRole('button', { name: 'Submit' })
page.getByLabel('Email')
page.getByText('Welcome')
// Chaining
page.getByRole('listitem').filter({ hasText: 'Product' })Coverage Thresholds (jest.config.js)
覆盖率阈值(jest.config.js)
javascript
module.exports = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};javascript
module.exports = {
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
};Common Commands
常用命令
bash
undefinedbash
undefinedJest
Jest
npm test # Run all tests
npm test -- --watch # Watch mode
npm test -- --coverage # With coverage
npm test -- Button.test.tsx # Single file
npm test # Run all tests
npm test -- --watch # Watch mode
npm test -- --coverage # With coverage
npm test -- Button.test.tsx # Single file
Playwright
Playwright
npx playwright test # Run all E2E tests
npx playwright test --ui # UI mode
npx playwright test --debug # Debug mode
npx playwright codegen # Generate tests
npx playwright test # Run all E2E tests
npx playwright test --ui # UI mode
npx playwright test --debug # Debug mode
npx playwright codegen # Generate tests
Coverage
Coverage
npm test -- --coverage --coverageReporters=lcov,json
python scripts/coverage_analyzer.py coverage/coverage-final.json
undefinednpm test -- --coverage --coverageReporters=lcov,json
python scripts/coverage_analyzer.py coverage/coverage-final.json
undefined