A TypeScript project with Jest for testing and code coverage. Contains three example modules: Bank, Payment and Subscription (with inheritance).
src/
├── bank/
│ └── bank.ts
├── payment/
│ └── payment.ts
└── subscription/
├── subscription.ts
├── basic-plan.ts
└── premium-plan.ts
test/
├── bank/
│ └── bank.test.ts
├── payment/
│ ├── payment.test.ts # Full suite: TC-001 to TC-025 (31 executions)
│ ├── TC_payment.md # Test case tables for the full suite
│ ├── minimalpayment.test.ts # Minimal suite: 11 test cases
│ └── minimalpayment.md # Test case tables for the minimal suite
└── subscription/
└── subscription.test.ts
npm installnpm test— run testsnpm run test:coverage— run tests with coverage reportnpm run format— format code (no semicolons)
- Bank: Add withdraw tests to increase coverage (see TODO in
test/bank/bank.test.ts) - Subscription: Added
getPricetests for BasicPlan and PremiumPlan (including discount for 12+ months) to increase coverage (see TODOs intest/subscription/subscription.test.ts) - PaymentService: Implemented PaymentService with strict type validation and 100% test coverage (TC-001 through TC-025).
There are two suites on purpose:
- Full suite (
payment.test.ts): the original design from boundary value analysis and equivalence partitioning, including runtime type checks (strings,undefined, objects, arrays, booleans, functions). - Minimal suite (
minimalpayment.test.ts): 11 test cases. 9 were selected with Stryker mutation testing: each one kills at least one mutant no other test kills, and together they reach the same mutation score as the full suite (38/39; the survivor is an equivalent mutant). The other 2 (TC-012, TC-017) cover spec requirements Stryker does not generate mutants for: the lower bound of the discount range and discounts applied to the current amount.
The comparison shows that most of the full suite is redundant against Stryker's mutants. Stryker only applies syntactic mutations, though, so the full suite still catches realistic bugs the minimal suite misses (e.g. using global isFinite instead of Number.isFinite). A high mutation score does not mean every requirement is tested. See minimalpayment.md for the reasoning behind each test.
Stryker configuration and reports live in the payment2-mutation branch.
Run npm run test:coverage to see the coverage report.
Coverage thresholds are configured in jest.config.js.
HTML report is generated in coverage/lcov-report/index.html.