跳到主要内容

测试驱动开发

收藏0

红绿重构循环的实战规范:什么算好测试、测试该写在哪个接口缝、三个反模式与循环法则,含 mock 与测试写法两篇参考。

让 AI 安装

星光尘缘最新版本 0.1.0更新于 2026-11-09下载 0 次

tests.md

2.2 KB查看源码

Good and Bad Tests#

Good Tests#

Integration-style: Test through real interfaces, not mocks of internal parts.

// GOOD: Tests observable behavior
test("user can checkout with valid cart", async () => {
  const cart = createCart();
  cart.add(product);
  const result = await checkout(cart, paymentMethod);
  expect(result.status).toBe("confirmed");
});

Characteristics:

  • Tests behavior users/callers care about
  • Uses public API only
  • Survives internal refactors
  • Describes WHAT, not HOW
  • One logical assertion per test

Bad Tests#

Implementation-detail tests: Coupled to internal structure.

// BAD: Tests implementation details
test("checkout calls paymentService.process", async () => {
  const mockPayment = jest.mock(paymentService);
  await checkout(cart, payment);
  expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
});

Red flags:

  • Mocking internal collaborators
  • Testing private methods
  • Asserting on call counts/order
  • Test breaks when refactoring without behavior change
  • Test name describes HOW not WHAT
  • Verifying through external means instead of interface
// BAD: Bypasses interface to verify
test("createUser saves to database", async () => {
  await createUser({ name: "Alice" });
  const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
  expect(row).toBeDefined();
});

// GOOD: Verifies through interface
test("createUser makes user retrievable", async () => {
  const user = await createUser({ name: "Alice" });
  const retrieved = await getUser(user.id);
  expect(retrieved.name).toBe("Alice");
});

Tautological tests: Expected value restates the implementation, so the test passes by construction.

// BAD: Expected value is recomputed the way the code computes it
test("calculateTotal sums line items", () => {
  const items = [{ price: 10 }, { price: 5 }];
  const expected = items.reduce((sum, i) => sum + i.price, 0);
  expect(calculateTotal(items)).toBe(expected);
});

// GOOD: Expected value is an independent, known literal
test("calculateTotal sums line items", () => {
  expect(calculateTotal([{ price: 10 }, { price: 5 }])).toBe(15);
});

文件内容是平台检查时读出的文本,只供查看。平台不会运行包里的任何脚本或程序。