Guides test strategy, TDD/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.
Instrucciones de origen · Vista previa de solo lectura
name
designing-tests
description
Guides test strategy, TDD/BDD approaches, test coverage planning, and testing best practices. Use when designing test suites, improving coverage, or choosing testing approaches.
license
MIT
compatibility
opencode
metadata
{"category":"quality","audience":"developers"}
Designing Tests
Strategies and patterns for designing effective, maintainable test suites.
┌─────────────────────────────────┐
│ │
▼ │
┌─────────┐ ┌─────────┐ ┌────────┴──┐
│ RED │───▶│ GREEN │───▶│ REFACTOR │
│ Write │ │ Make │ │ Clean │
│ failing │ │ it │ │ up │
│ test │ │ pass │ │ code │
└─────────┘ └─────────┘ └───────────┘
TDD Best Practices
Write the test first - Don't write production code without a failing test
Write the minimal test - One behavior per test
Write the minimal code - Just enough to pass
Refactor ruthlessly - Clean up after green
Run tests frequently - After every small change
TDD Example Flow
# Step 1: RED - Write failing testdeftest_calculate_total_with_discount():
order = Order(items=[Item(price=100)])
order.apply_discount(10) # 10%assert order.total() == 90# Step 2: GREEN - Minimal implementationclassOrder:
def__init__(self, items):
self.items = items
self.discount = 0defapply_discount(self, percent):
self.discount = percent
deftotal(self):
subtotal = sum(i.price for i inself.items)
return subtotal * (100 - self.discount) / 100# Step 3: REFACTOR - Clean up (if needed)
Behavior-Driven Development (BDD)
Gherkin Syntax
Feature: Shopping Cart
As a customer
I want to add items to my cart
So that I can purchase them later
Scenario: Add item to empty cart
Given I have an empty cart
When I add a product "Widget" priced at $10
Then my cart should contain 1 item
And my cart total should be $10
Scenario: Apply discount code
Given I have a cart with total $100
When I apply discount code "SAVE10"
Then my cart total should be $90
BDD Benefits
Tests as documentation
Shared language with stakeholders
Focus on behavior, not implementation
Easy to understand test intent
Test Design Patterns
Arrange-Act-Assert (AAA)
deftest_user_registration():
# Arrange - Set up preconditions
user_data = {"email": "test@example.com", "password": "secure123"}
user_service = UserService(mock_repository)
# Act - Perform the action
result = user_service.register(user_data)
# Assert - Verify the outcomeassert result.success isTrueassert result.user.email == "test@example.com"
Given-When-Then (BDD style)
deftest_order_cancellation():
# Given - a confirmed order
order = create_confirmed_order()
# When - the customer cancels it
order.cancel()
# Then - the order is cancelled and refund initiatedassert order.status == "cancelled"assert order.refund_initiated isTrue
Testing implementation, not behavior - Tests break on refactor
Large test methods - Hard to debug, unclear intent
Excessive mocking - Tests don't reflect reality
Shared mutable state - Tests affect each other
Ignoring test failures - Broken windows effect
Testing private methods - Coupling to implementation
No assertion - Tests that can't fail
Copy-paste tests - Maintenance nightmare
Quick Reference
PYRAMID:
Unit (70%) → Integration (20%) → E2E (10%)
TDD CYCLE:
Red → Green → Refactor
PATTERNS:
AAA: Arrange-Act-Assert
Builder: Fluent test data creation
Page Object: E2E abstraction
MOCK WHEN:
External APIs, Database (unit), Time, Random
COVERAGE:
70-80% line, focus on business logic
NAMING:
test_[what]_[condition]_[expected]