用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Objective-Arts/lens-dist --skill test-strategy命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | test-strategy |
| description | Test pyramid, testing strategy, and when to use which test type |
Apply Martin Fowler's testing philosophy for balanced, effective test suites.
/\
/ \ E2E / UI Tests
/ \ (few, slow, brittle)
/──────\
/ \ Integration Tests
/ \ (some, moderate speed)
/────────────\
/ \ Unit Tests
/ \ (many, fast, stable)
/──────────────────\
Key Insight: More tests at the bottom, fewer at the top.
| Level | Speed | Cost to Write | Cost to Maintain | Confidence |
|---|---|---|---|---|
| Unit | Fast (ms) | Low | Low | Component works |
| Integration | Medium (s) | Medium | Medium | Components work together |
| E2E | Slow (min) | High | High | System works for user |
──────────────
/ \ Manual Testing
/────────────────\
/ \ E2E Tests
/────────────────────\
/ \ Integration
──────────────────────── Unit (few)
Problem: Slow feedback, high maintenance, flaky tests.
Test a single unit (class, function) in isolation.
// Unit test - no external dependencies
@Test
void calculateDiscount_goldCustomer_returns15Percent() {
DiscountCalculator calc = new DiscountCalculator();
double discount = calc.calculate(100.0, CustomerType.GOLD);
assertEquals(15.0, discount, 0.01);
}
Characteristics:
Test how components work together.
// Integration test - tests real database interaction
@Test
void userRepository_savesAndRetrieves() {
UserRepository repo = new UserRepository(testDatabase);
User user = new User("alice@test.com");
repo.save(user);
User found = repo.findByEmail("alice@test.com");
assertEquals("alice@test.com", found.getEmail());
}
Characteristics:
Test complete user journeys through the system.
// E2E test - tests full user flow
@Test
void userCanCompleteCheckout() {
browser.navigateTo("/products");
browser.click("#add-to-cart-widget-1");
browser.click("#checkout");
browser.fillForm("#payment-form", validCard);
browser.click("#submit-order");
assertThat(browser.getCurrentUrl()).contains("/order-confirmation");
assertThat(browser.getText("#confirmation")).contains("Order placed");
}
Characteristics:
// Good unit test candidates
class PriceCalculator { /* pure logic */ }
class EmailValidator { /* validation rules */ }
class DateFormatter { /* transformations */ }
// Good integration test candidates
class UserRepository { /* database access */ }
class PaymentGateway { /* external API */ }
class OrderService { /* orchestrates multiple components */ }
// Good E2E test candidates
- Complete checkout flow
- User registration and login
- Search and filter results
- Critical business workflows
WRONG: E2E test for validation logic
────────────────────────────────────
browser.fillInput("#email", "invalid");
browser.click("#submit");
expect(browser.getText(".error")).toBe("Invalid email");
// Slow, brittle, overkill for simple validation
RIGHT: Unit test for validation logic
────────────────────────────────────
@Test
void validate_invalidEmail_returnsFalse() {
assertFalse(EmailValidator.isValid("invalid"));
}
// Fast, focused, easy to maintain
If unit tests cover the logic ──► Don't repeat in integration
If integration tests cover the flow ──► Don't repeat in E2E
Solitary (London School): Mock all collaborators
@Test
void orderService_appliesDiscount() {
DiscountService mockDiscount = mock(DiscountService.class);
when(mockDiscount.calculate(any())).thenReturn(10.0);
OrderService orders = new OrderService(mockDiscount);
Order order = orders.create(items);
assertEquals(90.0, order.getTotal());
}
Sociable (Detroit School): Use real collaborators when simple
@Test
void orderService_appliesDiscount() {
DiscountService realDiscount = new DiscountService(); // Simple, no I/O
OrderService orders = new OrderService(realDiscount);
Order order = orders.create(items);
assertEquals(90.0, order.getTotal());
}
Fowler's View: Both are valid. Use solitary when collaborators are complex or slow. Use sociable when collaborators are simple and fast.
// Option 1: In-memory database (fast)
@BeforeEach
void setUp() {
database = new H2Database(); // In-memory
}
// Option 2: Test containers (realistic)
@Container
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>();
// Option 3: Transaction rollback
@Transactional
@Test
void test() {
// Changes rolled back after test
}
// Option 1: Mock the client
PaymentClient mockClient = mock(PaymentClient.class);
// Option 2: Fake server (WireMock, MockServer)
@BeforeEach
void setUp() {
stubFor(post("/charge")
.willReturn(ok().withBody("{\"status\":\"success\"}")));
}
// Option 3: Contract tests (Pact)
@Pact(consumer = "OrderService")
RequestResponsePact chargeCard(PactDslWithProvider builder) {
return builder
.given("valid card")
.uponReceiving("charge request")
.path("/charge")
.method("POST")
.willRespondWith()
.status(200)
.build();
}
On every commit:
├── Unit tests (< 5 min)
└── Fast integration tests (< 10 min)
On PR/merge:
├── Full integration tests (< 30 min)
└── E2E smoke tests (< 15 min)
Nightly:
└── Full E2E suite (hours OK)
# Quick feedback during development
mvn test -Dgroups=unit
# Before push
mvn test -Dgroups=unit,integration
# Full suite
mvn test
| Question | Answer |
|---|---|
| How to test business logic? | Unit test |
| How to test database queries? | Integration test |
| How to test API contracts? | Integration test with mocks |
| How to test user flows? | E2E test (sparingly) |
| How to test validation? | Unit test |
| How to test error handling? | Unit + integration |
| Tests too slow? | Move down the pyramid |
| Tests too brittle? | Move down the pyramid |
| Missing bugs in production? | Add integration tests |