testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTesting Standards Skill
测试标准技能
Level 1: Quick Start (5 minutes)
一级:快速入门(5分钟)
What You'll Learn
你将学到
Implement effective testing strategies to ensure code quality, catch bugs early, and maintain confidence in changes.
实施有效的测试策略,确保代码质量,尽早发现bug,并对代码变更保持信心。
Core Principles
核心原则
- Test First: Write tests before implementation (TDD)
- Coverage: Aim for >80% code coverage
- Isolation: Tests should be independent and repeatable
- Speed: Keep unit tests fast (<100ms each)
- 测试先行:在实现代码前编写测试(TDD)
- 代码覆盖率:目标达到80%以上的代码覆盖率
- 独立性:测试应独立且可重复执行
- 速度:保持单元测试执行快速(每个测试<100毫秒)
Testing Pyramid
测试金字塔
/\
/ \ E2E Tests (Few)
/----\
/ Inte \
/ gration \ (Some)
/ Tests \
/------------\
/ Unit Tests \ (Many)
/--------------\ /\
/ \ E2E 测试(少量)
/----\
/ 集 成 \
/ 测 试 \(适量)
/ \
/------------\
/ 单元测试 \(大量)
/--------------\Quick Start Example
快速入门示例
typescript
// 1. Write the test first (RED)
describe("calculateDiscount", () => {
it("should apply 10% discount for premium users", () => {
const user = { tier: "premium" };
const order = { total: 100 };
const result = calculateDiscount(user, order);
expect(result).toBe(90);
});
});
// 2. Implement minimal code (GREEN)
function calculateDiscount(user, order) {
if (user.tier === "premium") {
return order.total * 0.9;
}
return order.total;
}
// 3. Refactor (REFACTOR)
function calculateDiscount(
user: User,
order: Order
): number {
const PREMIUM_DISCOUNT = 0.1;
return user.tier === "premium"
? order.total * (1 - PREMIUM_DISCOUNT)
: order.total;
}typescript
// 1. 先编写测试(红阶段)
describe("calculateDiscount", () => {
it("should apply 10% discount for premium users", () => {
const user = { tier: "premium" };
const order = { total: 100 };
const result = calculateDiscount(user, order);
expect(result).toBe(90);
});
});
// 2. 实现最简代码(绿阶段)
function calculateDiscount(user, order) {
if (user.tier === "premium") {
return order.total * 0.9;
}
return order.total;
}
// 3. 重构代码(重构阶段)
function calculateDiscount(
user: User,
order: Order
): number {
const PREMIUM_DISCOUNT = 0.1;
return user.tier === "premium"
? order.total * (1 - PREMIUM_DISCOUNT)
: order.total;
}Essential Checklist
必备检查清单
- Unit tests for all business logic
- Integration tests for critical paths
- Tests run in CI/CD pipeline
- Coverage >80%
- Tests are maintainable and readable
- 为所有业务逻辑编写单元测试
- 为关键路径编写集成测试
- 在CI/CD流水线中运行测试
- 代码覆盖率>80%
- 测试具备可维护性和可读性
Common Pitfalls
常见误区
- Testing implementation details instead of behavior
- Slow tests that discourage running them
- Flaky tests that fail intermittently
- Poor test isolation (shared state)
- 测试实现细节而非业务行为
- 测试执行缓慢,导致开发者不愿运行
- 不稳定的测试,间歇性失败
- 测试独立性差(共享状态)
Level 2: Implementation (30 minutes)
二级:实践落地(30分钟)
Deep Dive Topics
深入主题
1. Test-Driven Development (TDD)
1. 测试驱动开发(TDD)
Red-Green-Refactor Cycle:
typescript
// STEP 1: RED - Write failing test
describe("UserService", () => {
describe("createUser", () => {
it("should hash password before saving", async () => {
const userData = {
email: "test@example.com",
password: "SecurePass123!",
};
const service = new UserService(mockRepository, mockHasher);
await service.createUser(userData);
expect(mockHasher.hash).toHaveBeenCalledWith("SecurePass123!");
expect(mockRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
email: "test@example.com",
passwordHash: expect.any(String),
})
);
});
});
});
// STEP 2: GREEN - Minimal implementation
class UserService {
constructor(
private repository: UserRepository,
private hasher: PasswordHasher
) {}
async createUser(userData: UserData): Promise<User> {
const passwordHash = await this.hasher.hash(userData.password);
return this.repository.save({
...userData,
passwordHash,
});
}
}
// STEP 3: REFACTOR - Improve design
class UserService {
constructor(
private repository: UserRepository,
private hasher: PasswordHasher,
private validator: UserValidator
) {}
async createUser(userData: UserData): Promise<User> {
await this.validator.validate(userData);
const passwordHash = await this.hasher.hash(userData.password);
const user = new User({
email: userData.email,
passwordHash,
createdAt: new Date(),
});
return this.repository.save(user);
}
}NIST Mapping:
- @nist-controls: [si-10, si-11, au-2, au-3]
红-绿-重构循环:
typescript
// 步骤1:红阶段 - 编写失败的测试
describe("UserService", () => {
describe("createUser", () => {
it("should hash password before saving", async () => {
const userData = {
email: "test@example.com",
password: "SecurePass123!",
};
const service = new UserService(mockRepository, mockHasher);
await service.createUser(userData);
expect(mockHasher.hash).toHaveBeenCalledWith("SecurePass123!");
expect(mockRepository.save).toHaveBeenCalledWith(
expect.objectContaining({
email: "test@example.com",
passwordHash: expect.any(String),
})
);
});
});
});
// 步骤2:绿阶段 - 最简实现
class UserService {
constructor(
private repository: UserRepository,
private hasher: PasswordHasher
) {}
async createUser(userData: UserData): Promise<User> {
const passwordHash = await this.hasher.hash(userData.password);
return this.repository.save({
...userData,
passwordHash,
});
}
}
// 步骤3:重构阶段 - 优化设计
class UserService {
constructor(
private repository: UserRepository,
private hasher: PasswordHasher,
private validator: UserValidator
) {}
async createUser(userData: UserData): Promise<User> {
await this.validator.validate(userData);
const passwordHash = await this.hasher.hash(userData.password);
const user = new User({
email: userData.email,
passwordHash,
createdAt: new Date(),
});
return this.repository.save(user);
}
}NIST 映射:
- @nist-controls: [si-10, si-11, au-2, au-3]
2. Property-Based Testing
2. 基于属性的测试
typescript
import { fc } from "fast-check";
// Traditional example-based test
it("should reverse a reversed string back to original", () => {
expect(reverse(reverse("hello"))).toBe("hello");
expect(reverse(reverse("world"))).toBe("world");
// Limited to specific examples
});
// Property-based test - tests thousands of cases
it("reversing twice should return original string", () => {
fc.assert(
fc.property(fc.string(), (str) => {
expect(reverse(reverse(str))).toBe(str);
})
);
});
// Complex property testing
describe("calculateTotal", () => {
it("should always return non-negative totals", () => {
fc.assert(
fc.property(
fc.array(fc.record({ price: fc.nat(), quantity: fc.nat() })),
(items) => {
const total = calculateTotal(items);
expect(total).toBeGreaterThanOrEqual(0);
}
)
);
});
it("should be commutative (order doesn't matter)", () => {
fc.assert(
fc.property(fc.array(fc.record({ price: fc.nat(), quantity: fc.nat() })), (items) => {
const total1 = calculateTotal(items);
const total2 = calculateTotal([...items].reverse());
expect(total1).toBe(total2);
})
);
});
});typescript
import { fc } from "fast-check";
// 传统的基于示例的测试
it("should reverse a reversed string back to original", () => {
expect(reverse(reverse("hello"))).toBe("hello");
expect(reverse(reverse("world"))).toBe("world");
// 仅覆盖特定示例
});
// 基于属性的测试 - 测试数千种情况
it("reversing twice should return original string", () => {
fc.assert(
fc.property(fc.string(), (str) => {
expect(reverse(reverse(str))).toBe(str);
})
);
});
// 复杂的属性测试
describe("calculateTotal", () => {
it("should always return non-negative totals", () => {
fc.assert(
fc.property(
fc.array(fc.record({ price: fc.nat(), quantity: fc.nat() })),
(items) => {
const total = calculateTotal(items);
expect(total).toBeGreaterThanOrEqual(0);
}
)
);
});
it("should be commutative (order doesn't matter)", () => {
fc.assert(
fc.property(fc.array(fc.record({ price: fc.nat(), quantity: fc.nat() })), (items) => {
const total1 = calculateTotal(items);
const total2 = calculateTotal([...items].reverse());
expect(total1).toBe(total2);
})
);
});
});3. Integration Testing
3. 集成测试
typescript
// API Integration Test
describe("POST /api/users", () => {
let app: Express;
let db: Database;
beforeAll(async () => {
// Setup test database
db = await createTestDatabase();
app = createApp({ database: db });
});
afterAll(async () => {
await db.close();
});
beforeEach(async () => {
// Clean state between tests
await db.truncate("users");
});
it("should create a new user", async () => {
const response = await request(app)
.post("/api/users")
.send({
email: "test@example.com",
password: "SecurePass123!",
name: "Test User",
})
.expect(201);
expect(response.body).toMatchObject({
id: expect.any(String),
email: "test@example.com",
name: "Test User",
});
// Verify in database
const user = await db.query("SELECT * FROM users WHERE email = ?", [
"test@example.com",
]);
expect(user).toBeDefined();
expect(user.passwordHash).not.toBe("SecurePass123!"); // Should be hashed
});
it("should reject duplicate emails", async () => {
// Create first user
await request(app).post("/api/users").send({
email: "test@example.com",
password: "SecurePass123!",
});
// Attempt duplicate
await request(app)
.post("/api/users")
.send({
email: "test@example.com",
password: "AnotherPass456!",
})
.expect(409);
});
});typescript
// API 集成测试
describe("POST /api/users", () => {
let app: Express;
let db: Database;
beforeAll(async () => {
// 搭建测试数据库
db = await createTestDatabase();
app = createApp({ database: db });
});
afterAll(async () => {
await db.close();
});
beforeEach(async () => {
// 测试间清理状态
await db.truncate("users");
});
it("should create a new user", async () => {
const response = await request(app)
.post("/api/users")
.send({
email: "test@example.com",
password: "SecurePass123!",
name: "测试用户",
})
.expect(201);
expect(response.body).toMatchObject({
id: expect.any(String),
email: "test@example.com",
name: "测试用户",
});
// 在数据库中验证
const user = await db.query("SELECT * FROM users WHERE email = ?", [
"test@example.com",
]);
expect(user).toBeDefined();
expect(user.passwordHash).not.toBe("SecurePass123!"); // 应为哈希值
});
it("should reject duplicate emails", async () => {
// 创建第一个用户
await request(app).post("/api/users").send({
email: "test@example.com",
password: "SecurePass123!",
});
// 尝试创建重复用户
await request(app)
.post("/api/users")
.send({
email: "test@example.com",
password: "AnotherPass456!",
})
.expect(409);
});
});4. Security Testing
4. 安全测试
typescript
// Input validation tests
describe("Security: Input Validation", () => {
it("should reject SQL injection attempts", async () => {
const maliciousInput = "'; DROP TABLE users; --";
await request(app)
.get(`/api/users/search?name=${maliciousInput}`)
.expect(400);
});
it("should sanitize XSS attempts", async () => {
const xssPayload = '<script>alert("XSS")</script>';
const response = await request(app)
.post("/api/comments")
.send({ content: xssPayload })
.expect(201);
expect(response.body.content).not.toContain("<script>");
});
it("should enforce rate limiting", async () => {
const requests = Array(101)
.fill(null)
.map(() => request(app).get("/api/data"));
const responses = await Promise.all(requests);
const rateLimited = responses.filter((r) => r.status === 429);
expect(rateLimited.length).toBeGreaterThan(0);
});
});
// Authentication tests
describe("Security: Authentication", () => {
it("should require authentication for protected routes", async () => {
await request(app).get("/api/protected").expect(401);
});
it("should reject expired tokens", async () => {
const expiredToken = generateExpiredToken();
await request(app)
.get("/api/protected")
.set("Authorization", `Bearer ${expiredToken}`)
.expect(401);
});
});typescript
// 输入验证测试
describe("Security: Input Validation", () => {
it("should reject SQL injection attempts", async () => {
const maliciousInput = "'; DROP TABLE users; --";
await request(app)
.get(`/api/users/search?name=${maliciousInput}`)
.expect(400);
});
it("should sanitize XSS attempts", async () => {
const xssPayload = '<script>alert("XSS")</script>';
const response = await request(app)
.post("/api/comments")
.send({ content: xssPayload })
.expect(201);
expect(response.body.content).not.toContain("<script>");
});
it("should enforce rate limiting", async () => {
const requests = Array(101)
.fill(null)
.map(() => request(app).get("/api/data"));
const responses = await Promise.all(requests);
const rateLimited = responses.filter((r) => r.status === 429);
expect(rateLimited.length).toBeGreaterThan(0);
});
});
// 身份验证测试
describe("Security: Authentication", () => {
it("should require authentication for protected routes", async () => {
await request(app).get("/api/protected").expect(401);
});
it("should reject expired tokens", async () => {
const expiredToken = generateExpiredToken();
await request(app)
.get("/api/protected")
.set("Authorization", `Bearer ${expiredToken}`)
.expect(401);
});
});5. Performance Testing
5. 性能测试
typescript
// Benchmark testing
describe("Performance: calculateComplexMetric", () => {
it("should complete within 100ms for 1000 items", async () => {
const items = generateTestData(1000);
const start = performance.now();
await calculateComplexMetric(items);
const duration = performance.now() - start;
expect(duration).toBeLessThan(100);
});
it("should scale linearly with input size", async () => {
const sizes = [100, 200, 400, 800];
const timings: number[] = [];
for (const size of sizes) {
const items = generateTestData(size);
const start = performance.now();
await calculateComplexMetric(items);
timings.push(performance.now() - start);
}
// Check that doubling input approximately doubles time
expect(timings[1] / timings[0]).toBeCloseTo(2, 0.5);
expect(timings[2] / timings[1]).toBeCloseTo(2, 0.5);
});
});
// Load testing with autocannon
import autocannon from "autocannon";
describe("Load Testing", () => {
it("should handle 1000 req/s with <200ms p95 latency", async () => {
const result = await autocannon({
url: "http://localhost:3000/api/health",
connections: 100,
duration: 10,
pipelining: 10,
});
expect(result.requests.average).toBeGreaterThan(1000);
expect(result.latency.p95).toBeLessThan(200);
});
});typescript
// 基准测试
describe("Performance: calculateComplexMetric", () => {
it("should complete within 100ms for 1000 items", async () => {
const items = generateTestData(1000);
const start = performance.now();
await calculateComplexMetric(items);
const duration = performance.now() - start;
expect(duration).toBeLessThan(100);
});
it("should scale linearly with input size", async () => {
const sizes = [100, 200, 400, 800];
const timings: number[] = [];
for (const size of sizes) {
const items = generateTestData(size);
const start = performance.now();
await calculateComplexMetric(items);
timings.push(performance.now() - start);
}
// 验证输入量翻倍时,耗时大致翻倍
expect(timings[1] / timings[0]).toBeCloseTo(2, 0.5);
expect(timings[2] / timings[1]).toBeCloseTo(2, 0.5);
});
});
// 使用autocannon进行负载测试
import autocannon from "autocannon";
describe("Load Testing", () => {
it("should handle 1000 req/s with <200ms p95 latency", async () => {
const result = await autocannon({
url: "http://localhost:3000/api/health",
connections: 100,
duration: 10,
pipelining: 10,
});
expect(result.requests.average).toBeGreaterThan(1000);
expect(result.latency.p95).toBeLessThan(200);
});
});6. Mutation Testing
6. 突变测试
typescript
// Original code
function isAdult(age: number): boolean {
return age >= 18;
}
// Mutation 1: Change >= to >
// function isAdult(age: number): boolean {
// return age > 18;
// }
// This test would catch mutation 1
it("should consider 18 as adult", () => {
expect(isAdult(18)).toBe(true);
});
// Mutation 2: Change 18 to 17
// function isAdult(age: number): boolean {
// return age >= 17;
// }
// This test would catch mutation 2
it("should not consider 17 as adult", () => {
expect(isAdult(17)).toBe(false);
});
// Run mutation testing
// npm install --save-dev stryker
// npx stryker runtypescript
// 原始代码
function isAdult(age: number): boolean {
return age >= 18;
}
// 突变1:将>=改为>
// function isAdult(age: number): boolean {
// return age > 18;
// }
// 该测试可以捕获突变1
it("should consider 18 as adult", () => {
expect(isAdult(18)).toBe(true);
});
// 突变2:将18改为17
// function isAdult(age: number): boolean {
// return age >= 17;
// }
// 该测试可以捕获突变2
it("should not consider 17 as adult", () => {
expect(isAdult(17)).toBe(false);
});
// 运行突变测试
// npm install --save-dev stryker
// npx stryker runTest Organization
测试组织方式
typescript
// Arrange-Act-Assert (AAA) Pattern
describe("OrderService", () => {
describe("calculateTotal", () => {
it("should apply discount to eligible orders", () => {
// ARRANGE - Setup test data
const order = {
items: [
{ price: 100, quantity: 2 },
{ price: 50, quantity: 1 },
],
discountCode: "SAVE10",
};
const service = new OrderService();
// ACT - Execute the behavior
const total = service.calculateTotal(order);
// ASSERT - Verify the outcome
expect(total).toBe(225); // (200 + 50) * 0.9
});
});
});typescript
// 安排-执行-断言(AAA)模式
describe("OrderService", () => {
describe("calculateTotal", () => {
it("should apply discount to eligible orders", () => {
// 安排 - 准备测试数据
const order = {
items: [
{ price: 100, quantity: 2 },
{ price: 50, quantity: 1 },
],
discountCode: "SAVE10",
};
const service = new OrderService();
// 执行 - 触发业务行为
const total = service.calculateTotal(order);
// 断言 - 验证结果
expect(total).toBe(225); // (200 + 50) * 0.9
});
});
});Integration Points
集成关联
- Links to Coding Standards for testable code design
- Links to Security Practices for security testing
- Links to NIST Compliance for SI-10, SI-11 controls
- 链接到编码标准以实现可测试的代码设计
- 链接到安全实践以开展安全测试
- 链接到NIST合规性以参考SI-10、SI-11控制要求
Level 3: Mastery (Extended Learning)
三级:精通进阶(拓展学习)
Advanced Topics
高级主题
1. Contract Testing
1. 契约测试
typescript
// Provider contract (API server)
import { Pact } from "@pact-foundation/pact";
describe("User API Provider", () => {
const provider = new Pact({
consumer: "UserService",
provider: "UserAPI",
});
beforeAll(() => provider.setup());
afterAll(() => provider.finalize());
it("should provide user by ID", async () => {
await provider.addInteraction({
state: "user 123 exists",
uponReceiving: "a request for user 123",
withRequest: {
method: "GET",
path: "/users/123",
},
willRespondWith: {
status: 200,
body: {
id: "123",
name: "John Doe",
email: "john@example.com",
},
},
});
await provider.verify();
});
});typescript
// 提供者契约(API服务器)
import { Pact } from "@pact-foundation/pact";
describe("User API Provider", () => {
const provider = new Pact({
consumer: "UserService",
provider: "UserAPI",
});
beforeAll(() => provider.setup());
afterAll(() => provider.finalize());
it("should provide user by ID", async () => {
await provider.addInteraction({
state: "user 123 exists",
uponReceiving: "a request for user 123",
withRequest: {
method: "GET",
path: "/users/123",
},
willRespondWith: {
status: 200,
body: {
id: "123",
name: "John Doe",
email: "john@example.com",
},
},
});
await provider.verify();
});
});2. Chaos Engineering
2. 混沌工程
typescript
// Simulate failures to test resilience
class ChaosMonkey {
private failureRate: number;
constructor(failureRate: number = 0.1) {
this.failureRate = failureRate;
}
async injectFailure<T>(operation: () => Promise<T>): Promise<T> {
if (Math.random() < this.failureRate) {
throw new Error("Simulated failure");
}
return operation();
}
}
describe("Resilience Testing", () => {
it("should retry failed operations", async () => {
const chaos = new ChaosMonkey(0.5); // 50% failure rate
let attempts = 0;
const result = await retry(
async () => {
attempts++;
return chaos.injectFailure(() => fetchData());
},
{ maxAttempts: 3, delay: 100 }
);
expect(result).toBeDefined();
expect(attempts).toBeGreaterThan(1);
});
});typescript
// 模拟故障以测试系统韧性
class ChaosMonkey {
private failureRate: number;
constructor(failureRate: number = 0.1) {
this.failureRate = failureRate;
}
async injectFailure<T>(operation: () => Promise<T>): Promise<T> {
if (Math.random() < this.failureRate) {
throw new Error("Simulated failure");
}
return operation();
}
}
describe("Resilience Testing", () => {
it("should retry failed operations", async () => {
const chaos = new ChaosMonkey(0.5); // 50%故障概率
let attempts = 0;
const result = await retry(
async () => {
attempts++;
return chaos.injectFailure(() => fetchData());
},
{ maxAttempts: 3, delay: 100 }
);
expect(result).toBeDefined();
expect(attempts).toBeGreaterThan(1);
});
});3. Visual Regression Testing
3. 视觉回归测试
typescript
import { test, expect } from "@playwright/test";
test("homepage should match snapshot", async ({ page }) => {
await page.goto("https://example.com");
// Take screenshot and compare with baseline
await expect(page).toHaveScreenshot("homepage.png", {
maxDiffPixels: 100,
});
});
test("button hover state", async ({ page }) => {
await page.goto("https://example.com");
await page.hover("button.primary");
await expect(page.locator("button.primary")).toHaveScreenshot(
"button-hover.png"
);
});typescript
import { test, expect } from "@playwright/test";
test("homepage should match snapshot", async ({ page }) => {
await page.goto("https://example.com");
// 截图并与基准图对比
await expect(page).toHaveScreenshot("homepage.png", {
maxDiffPixels: 100,
});
});
test("button hover state", async ({ page }) => {
await page.goto("https://example.com");
await page.hover("button.primary");
await expect(page.locator("button.primary")).toHaveScreenshot(
"button-hover.png"
);
});Resources
参考资源
Essential Reading
必读资料
Testing Frameworks
测试框架
- Unit Testing: Jest, Vitest, pytest, JUnit
- Integration Testing: Supertest, TestContainers
- E2E Testing: Playwright, Cypress, Selenium
- Property Testing: fast-check, Hypothesis, QuickCheck
- Mutation Testing: Stryker, PIT, mutmut
- 单元测试:Jest、Vitest、pytest、JUnit
- 集成测试:Supertest、TestContainers
- 端到端测试:Playwright、Cypress、Selenium
- 属性测试:fast-check、Hypothesis、QuickCheck
- 突变测试:Stryker、PIT、mutmut
Tools and Services
工具与服务
- CI/CD: GitHub Actions, GitLab CI, CircleCI
- Coverage: Istanbul, Coverage.py, JaCoCo
- Load Testing: k6, Artillery, Gatling
- Contract Testing: Pact, Spring Cloud Contract
- CI/CD:GitHub Actions、GitLab CI、CircleCI
- 覆盖率工具:Istanbul、Coverage.py、JaCoCo
- 负载测试:k6、Artillery、Gatling
- 契约测试:Pact、Spring Cloud Contract
Templates
模板
Test Suite Template
测试套件模板
typescript
describe("FeatureName", () => {
// Setup and teardown
beforeAll(async () => {
// One-time setup
});
afterAll(async () => {
// One-time cleanup
});
beforeEach(() => {
// Reset state before each test
});
afterEach(() => {
// Cleanup after each test
});
// Happy path tests
describe("when conditions are normal", () => {
it("should perform expected behavior", () => {
// Test implementation
});
});
// Edge cases
describe("when edge conditions occur", () => {
it("should handle edge case gracefully", () => {
// Test implementation
});
});
// Error cases
describe("when errors occur", () => {
it("should handle errors appropriately", () => {
// Test implementation
});
});
});typescript
describe("FeatureName", () => {
// 前置和后置操作
beforeAll(async () => {
// 一次性前置准备
});
afterAll(async () => {
// 一次性清理
});
beforeEach(() => {
// 每个测试前重置状态
});
afterEach(() => {
// 每个测试后清理
});
// 正常流程测试
describe("when conditions are normal", () => {
it("should perform expected behavior", () => {
// 测试实现
});
});
// 边界情况测试
describe("when edge conditions occur", () => {
it("should handle edge case gracefully", () => {
// 测试实现
});
});
// 错误情况测试
describe("when errors occur", () => {
it("should handle errors appropriately", () => {
// 测试实现
});
});
});Scripts
脚本
See for:
./scripts/- Test coverage reporters
- Mutation testing runners
- Performance benchmark tools
- Test data generators
查看目录获取:
./scripts/- 测试覆盖率报告工具
- 突变测试运行器
- 性能基准测试工具
- 测试数据生成器
Examples
示例
Basic Usage
基础用法
python
// TODO: Add basic example for testing
// This example demonstrates core functionalitypython
// TODO: 添加测试基础示例
// 该示例展示核心功能Advanced Usage
高级用法
python
// TODO: Add advanced example for testing
// This example shows production-ready patternspython
// TODO: 添加测试高级示例
// 该示例展示生产就绪模式Integration Example
集成示例
python
// TODO: Add integration example showing how testing
// works with other systems and servicesSee for complete working examples.
examples/testing/python
// TODO: 添加集成示例,展示测试如何与其他系统和服务协作查看目录获取完整可运行示例。
examples/testing/Integration Points
集成关联
This skill integrates with:
本技能可与以下内容集成:
Upstream Dependencies
上游依赖
- Tools: Common development tools and frameworks
- Prerequisites: Basic understanding of general concepts
- 工具:常见开发工具与框架
- 前置要求:对通用概念的基本理解
Downstream Consumers
下游应用
- Applications: Production systems requiring testing functionality
- CI/CD Pipelines: Automated testing and deployment workflows
- Monitoring Systems: Observability and logging platforms
- 应用系统:需要测试功能的生产系统
- CI/CD流水线:自动化测试与部署工作流
- 监控系统:可观测性与日志平台
Related Skills
相关技能
- See other skills in this category
- 查看本分类下的其他技能
Common Integration Patterns
常见集成模式
- Development Workflow: How this skill fits into daily development
- Production Deployment: Integration with production systems
- Monitoring & Alerting: Observability integration points
- 开发工作流:本技能如何融入日常开发
- 生产部署:与生产系统的集成方式
- 监控与告警:可观测性集成点
Common Pitfalls
常见误区
Pitfall 1: Insufficient Testing
误区1:测试不充分
Problem: Not testing edge cases and error conditions leads to production bugs
Solution: Implement comprehensive test coverage including:
- Happy path scenarios
- Error handling and edge cases
- Integration points with external systems
Prevention: Enforce minimum code coverage (80%+) in CI/CD pipeline
问题:未测试边界情况和错误处理,导致生产环境出现bug
解决方案:实现全面的测试覆盖,包括:
- 正常流程场景
- 错误处理与边界情况
- 与外部系统的集成点
预防措施:在CI/CD流水线中强制要求最低代码覆盖率(80%+)
Pitfall 2: Hardcoded Configuration
误区2:硬编码配置
Problem: Hardcoding values makes applications inflexible and environment-dependent
Solution: Use environment variables and configuration management:
- Separate config from code
- Use environment-specific configuration files
- Never commit secrets to version control
Prevention: Use tools like dotenv, config validators, and secret scanners
问题:硬编码配置值导致应用灵活性差,依赖特定环境
解决方案:使用环境变量和配置管理工具:
- 将配置与代码分离
- 使用环境特定的配置文件
- 绝不将敏感信息提交到版本控制系统
预防措施:使用dotenv、配置验证器和敏感信息扫描工具
Pitfall 3: Ignoring Security Best Practices
误区3:忽视安全最佳实践
Problem: Security vulnerabilities from not following established security patterns
Solution: Follow security guidelines:
- Input validation and sanitization
- Proper authentication and authorization
- Encrypted data transmission (TLS/SSL)
- Regular security audits and updates
Prevention: Use security linters, SAST tools, and regular dependency updates
Best Practices:
- Follow established patterns and conventions for testing
- Keep dependencies up to date and scan for vulnerabilities
- Write comprehensive documentation and inline comments
- Use linting and formatting tools consistently
- Implement proper error handling and logging
- Regular code reviews and pair programming
- Monitor production metrics and set up alerts
问题:未遵循既定安全模式,导致安全漏洞
解决方案:遵循安全指南:
- 输入验证与清理
- 正确的身份验证与授权
- 加密数据传输(TLS/SSL)
- 定期安全审计与更新
预防措施:使用安全代码检查工具、SAST工具,并定期更新依赖
最佳实践:
- 遵循既定的测试模式与规范
- 保持依赖更新并扫描漏洞
- 编写全面的文档与内联注释
- 持续使用代码检查与格式化工具
- 实现完善的错误处理与日志记录
- 定期代码评审与结对编程
- 监控生产指标并设置告警
Bundled Resources
配套资源
- Full TESTING_STANDARDS.md
- UNIFIED_STANDARDS.md
- Test configuration templates in
./templates/ - Testing utility scripts in
./scripts/ - Example test suites in
./resources/
- 完整TESTING_STANDARDS.md
- UNIFIED_STANDARDS.md
- 目录下的测试配置模板
./templates/ - 目录下的测试实用脚本
./scripts/ - 目录下的示例测试套件
./resources/