Initial commit
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# Risk-Based Testing - Practical Examples
|
||||
|
||||
This file contains detailed examples of applying Minimum Viable Testing philosophy to real Stories.
|
||||
|
||||
**Purpose:** Learning and reference (not loaded during skill execution).
|
||||
|
||||
**When to use:** Study these examples to understand how to trim test plans from excessive coverage-driven testing to minimal risk-based testing.
|
||||
|
||||
---
|
||||
|
||||
## Example 1: User Login Story (Minimal Approach)
|
||||
|
||||
**Acceptance Criteria:**
|
||||
1. User can login with valid credentials → JWT token returned
|
||||
2. Invalid credentials rejected → 401 error
|
||||
3. Rate limiting after 5 failed attempts → 429 error
|
||||
|
||||
**Risk Assessment:**
|
||||
|
||||
| Scenario | Business Impact | Probability | Priority | Test Type |
|
||||
|----------|-----------------|-------------|----------|-----------|
|
||||
| Valid login works | 4 (core flow) | 3 (standard auth) | **12** | E2E (baseline) |
|
||||
| Invalid credentials rejected | 5 (security) | 3 | **15** | E2E (baseline) |
|
||||
| Rate limiting works | 5 (security, brute force) | 4 (concurrency) | **20** | SKIP - E2E negative covers auth error |
|
||||
| SQL injection attempt blocked | 5 (security breach) | 2 (Prisma escapes) | 10 | SKIP - framework behavior |
|
||||
| JWT token format valid | 4 (breaks API calls) | 2 (library tested) | 8 | SKIP - library behavior |
|
||||
| Password hashing uses bcrypt | 5 (security) | 1 (copy-paste code) | 5 | SKIP - library behavior |
|
||||
| Custom password strength rules | 5 (security policy) | 4 (complex regex) | **20** | Unit (OUR logic) |
|
||||
|
||||
**Test Plan (Minimum Viable Testing):**
|
||||
|
||||
**E2E Tests (2 baseline):**
|
||||
1. **Positive:** User enters valid email/password → 200 OK + JWT token → token works for protected API call
|
||||
2. **Negative:** User enters invalid password → 401 Unauthorized → clear error message shown
|
||||
|
||||
**Integration Tests (0):**
|
||||
- None needed - 2 baseline E2E tests cover full stack (endpoint → service → database)
|
||||
|
||||
**Unit Tests (1 - OUR business logic only):**
|
||||
1. `validatePasswordStrength()` - OUR custom regex (12+ chars, special symbols, numbers) with 5 edge cases
|
||||
|
||||
**Total: 3 tests (within realistic goal 2-7)**
|
||||
|
||||
**What changed from 6 → 3 tests:**
|
||||
- ❌ E2E rate limiting test - REMOVED (Priority 20 but tests Redis library, not OUR logic)
|
||||
- ❌ Integration SQL injection test - REMOVED (testing Prisma escaping, not OUR code)
|
||||
- ❌ Integration rate limiter test - REMOVED (testing Redis counter, not OUR code)
|
||||
|
||||
**Why 3 tests sufficient:**
|
||||
- 2 baseline E2E cover all Acceptance Criteria (valid login + error handling)
|
||||
- 1 Unit test covers OUR custom password policy (not library behavior)
|
||||
- Rate limiting, SQL escaping, JWT generation = framework/library behavior (trust the library)
|
||||
|
||||
**Avoided tests (with rationale):**
|
||||
- ❌ Unit test `hashPassword()` - bcrypt library behavior, Priority 5
|
||||
- ❌ Unit test `generateJWT()` - jsonwebtoken library behavior, Priority 8
|
||||
- ❌ Unit test `validateEmail()` format - covered by E2E negative test
|
||||
- ❌ Integration test JWT token decoding - jsonwebtoken library behavior
|
||||
- ❌ Integration test rate limiting - Redis library behavior
|
||||
- ❌ Integration test SQL injection - Prisma library behavior
|
||||
|
||||
---
|
||||
|
||||
## Example 2: Product Search Story (Minimal Approach)
|
||||
|
||||
**Acceptance Criteria:**
|
||||
1. User can search products by name → results displayed
|
||||
2. User can filter by category → filtered results
|
||||
3. Empty search returns all products
|
||||
|
||||
**Risk Assessment:**
|
||||
|
||||
| Scenario | Business Impact | Probability | Priority | Test Type |
|
||||
|----------|-----------------|-------------|----------|-----------|
|
||||
| Search returns correct results | 4 (core feature) | 3 (SQL query) | **12** | E2E (baseline positive) |
|
||||
| Invalid search returns empty | 3 (UX feedback) | 3 | 9 | E2E (baseline negative) |
|
||||
| Category filter works | 3 (partial feature) | 3 | 9 | SKIP - covered by positive E2E |
|
||||
| Empty search shows all | 2 (minor UX) | 2 | 4 | SKIP - Priority too low |
|
||||
| Pagination works | 3 (UX issue if breaks) | 4 (off-by-one errors) | 12 | SKIP - UI pagination, not business logic |
|
||||
| Search handles special chars | 3 (breaks search) | 4 (SQL injection risk) | 12 | SKIP - Prisma/PostgreSQL behavior |
|
||||
| Results sorted by relevance | 2 (minor UX) | 3 | 6 | SKIP - Priority too low |
|
||||
| Unicode search | 3 (breaks for non-EN) | 4 | 12 | SKIP - database engine behavior |
|
||||
|
||||
**Test Plan (Minimum Viable Testing):**
|
||||
|
||||
**E2E Tests (2 baseline):**
|
||||
1. **Positive:** User types "laptop" in search → sees products with "laptop" in name/description
|
||||
2. **Negative:** User types "nonexistent999" → sees "No results found" message
|
||||
|
||||
**Integration Tests (0):**
|
||||
- None needed - special character escaping is Prisma/PostgreSQL behavior, not OUR logic
|
||||
|
||||
**Unit Tests (0):**
|
||||
- No complex business logic - simple database search query
|
||||
|
||||
**Total: 2 tests (minimum baseline)**
|
||||
|
||||
**What changed from 7 → 2 tests:**
|
||||
- ❌ E2E pagination test - REMOVED (UI pagination library, not OUR business logic)
|
||||
- ❌ Integration special chars test - REMOVED (Prisma query builder escaping, not OUR code)
|
||||
- ❌ Integration Unicode test - REMOVED (PostgreSQL LIKE operator, not OUR code)
|
||||
- ❌ Integration 1000-char string test - REMOVED (input validation middleware, not search logic)
|
||||
- ❌ Integration 500 error test - REMOVED (error handling middleware, not search logic)
|
||||
|
||||
**Why 2 tests sufficient:**
|
||||
- 2 baseline E2E cover both Acceptance Criteria (successful search + no results case)
|
||||
- No complex business logic to isolate - just database query (trust Prisma + PostgreSQL)
|
||||
- Pagination, special characters, Unicode, error handling = framework/library/database behavior
|
||||
|
||||
**Avoided tests (with rationale):**
|
||||
- ❌ E2E empty search - Priority 4 (manual testing sufficient)
|
||||
- ❌ E2E category filter - covered by baseline positive test (can search + filter simultaneously)
|
||||
- ❌ E2E pagination - testing UI pagination library, not OUR code
|
||||
- ❌ Unit test `buildSearchQuery()` - covered by E2E that executes query
|
||||
- ❌ Unit test sorting - Priority 6 (nice-to-have, not critical)
|
||||
- ❌ Integration test database `LIKE` query - testing PostgreSQL, not OUR code
|
||||
- ❌ Integration test special character escaping - testing Prisma, not OUR code
|
||||
|
||||
---
|
||||
|
||||
## Example 3: Payment Processing Story (Minimal Approach)
|
||||
|
||||
**Acceptance Criteria:**
|
||||
1. User can pay with credit card → order confirmed
|
||||
2. Failed payment shows error message
|
||||
3. Payment amount matches cart total
|
||||
|
||||
**Risk Assessment:**
|
||||
|
||||
| Scenario | Business Impact | Probability | Priority | Test Type |
|
||||
|----------|-----------------|-------------|----------|-----------|
|
||||
| Successful payment flow | 5 (money) | 3 (Stripe API) | **15** | E2E (baseline positive) |
|
||||
| Failed payment handled | 5 (money) | 4 (network issues) | **20** | E2E (baseline negative) |
|
||||
| Amount calculation correct | 5 (money) | 4 (complex math) | **20** | Unit (OUR calculation logic) |
|
||||
| Tax calculation by region | 5 (money) | 5 (complex rules) | **25** | Unit (OUR tax rules) |
|
||||
| Discount calculation | 5 (money) | 4 (business rules) | **20** | Unit (OUR discount logic) |
|
||||
| Currency conversion | 5 (money) | 5 (API + math) | **25** | SKIP - E2E covers, no complex OUR logic |
|
||||
| Refund processing | 5 (money) | 3 | **15** | SKIP - E2E positive covers payment flow |
|
||||
| Duplicate payment prevented | 5 (money) | 4 (race condition) | **20** | SKIP - Stripe API idempotency, not OUR code |
|
||||
| Transaction rollback on error | 5 (data corruption) | 4 (distributed transaction) | **20** | SKIP - database transaction manager, not OUR code |
|
||||
| Stripe API 500 error | 5 (money) | 3 | **15** | SKIP - E2E negative covers error handling |
|
||||
| Webhook processing | 5 (money) | 3 | **15** | SKIP - Stripe webhook mechanism, not complex OUR logic |
|
||||
|
||||
**Test Plan (Minimum Viable Testing):**
|
||||
|
||||
**E2E Tests (2 baseline):**
|
||||
1. **Positive:** User adds items to cart → proceeds to checkout → enters valid card → payment succeeds → order created in DB
|
||||
2. **Negative:** User enters invalid card → Stripe rejects → error message shown → order NOT created
|
||||
|
||||
**Integration Tests (0):**
|
||||
- None needed - currency conversion uses external API (trust API), transaction rollback is database behavior, Stripe idempotency is Stripe behavior
|
||||
|
||||
**Unit Tests (3 - OUR complex business logic only):**
|
||||
1. `calculateTotal()` - OUR calculation: items total + tax (by region) + shipping - discount → correct amount (5 edge cases)
|
||||
2. `calculateTax()` - OUR tax rules: different rates by country/state, special product categories (5 edge cases)
|
||||
3. `applyDiscount()` - OUR discount logic: percentage discount, fixed amount discount, minimum order threshold (5 edge cases)
|
||||
|
||||
**Total: 5 tests (within realistic goal 2-7)**
|
||||
|
||||
**What changed from 13 → 5 tests:**
|
||||
- ❌ E2E refund test - REMOVED (Stripe API refund mechanism, covered by positive E2E)
|
||||
- ❌ Integration Stripe 500 error test - REMOVED (covered by baseline negative E2E)
|
||||
- ❌ Integration duplicate payment test - REMOVED (Stripe idempotency keys, not OUR code)
|
||||
- ❌ Integration currency conversion test - REMOVED (external API behavior, not complex OUR logic)
|
||||
- ❌ Integration transaction rollback test - REMOVED (database transaction manager, not OUR code)
|
||||
- ❌ Integration webhook test - REMOVED (Stripe webhook mechanism, not complex OUR logic)
|
||||
- ❌ Unit test `convertCurrency()` - REMOVED (external API call, no complex OUR calculation)
|
||||
- ❌ Unit test shipping calculation - MERGED into `calculateTotal()` (part of same calculation)
|
||||
|
||||
**Why 5 tests sufficient:**
|
||||
- 2 baseline E2E cover all Acceptance Criteria (successful payment + failed payment)
|
||||
- 3 Unit tests cover OUR complex financial calculations (money = Priority 25)
|
||||
- Currency conversion, transaction rollback, Stripe idempotency, webhooks = external services/framework behavior (trust them)
|
||||
|
||||
**Avoided tests (with rationale):**
|
||||
- ❌ Integration test currency conversion - external API behavior, not OUR math
|
||||
- ❌ Integration test transaction rollback - database transaction manager behavior
|
||||
- ❌ Integration test Stripe idempotency - Stripe API feature, not OUR code
|
||||
- ❌ Integration test Stripe 500 error - covered by baseline E2E negative test
|
||||
- ❌ Integration test webhook - Stripe mechanism, not complex OUR logic
|
||||
- ❌ E2E refund test - Stripe API refund, not different from payment flow
|
||||
- ❌ Unit test free shipping threshold - part of `calculateTotal()` unit test
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Last Updated:** 2025-11-14
|
||||
Reference in New Issue
Block a user