Guides the red-green-refactor TDD workflow: write a failing test first, implement the minimum code to make it pass, then refactor while keeping tests green. Use when a user asks to practice TDD, write tests first, follow red-green-refactor, do test-driven development, write failing tests before code, or phrases like 'make the test pass', 'test coverage', or 'unit tests before implementation'.
Install with Tessl CLI
npx tessl i github:rohitg00/skillkit --skill red-green-refactor90
Does it follow best practices?
If you maintain this skill, you can automatically optimize it using the tessl CLI to improve its score:
npx tessl skill review --optimize ./path/to/skillValidation for skill structure
You are following the RED-GREEN-REFACTOR cycle for test-driven development. Every new feature, bug fix, or behavior change starts with a failing test.
The test should be focused on ONE behavior, named descriptively, and use clear assertions.
Executable example (Jest):
// calculateTotal.test.js
const { calculateTotal } = require('./calculateTotal');
describe('calculateTotal', () => {
it('should apply 10% discount when total exceeds 100', () => {
const items = [{ price: 60 }, { price: 60 }]; // total = 120
expect(calculateTotal(items)).toBe(108); // 120 * 0.90
});
});Running this now produces: Cannot find module './calculateTotal' — correct RED state.
Write the minimum code needed to pass the test. Don't add anything extra.
// calculateTotal.js
function calculateTotal(items) {
const total = items.reduce((sum, item) => sum + item.price, 0);
return total > 100 ? total * 0.9 : total;
}
module.exports = { calculateTotal };Run the test — it passes. GREEN achieved. Stop here; resist adding more logic.
With a passing test as your safety net, clean up the implementation. Run tests after every change.
// calculateTotal.js — refactored for clarity
const DISCOUNT_THRESHOLD = 100;
const DISCOUNT_RATE = 0.9;
function calculateTotal(items) {
const subtotal = items.reduce((sum, { price }) => sum + price, 0);
return subtotal > DISCOUNT_THRESHOLD ? subtotal * DISCOUNT_RATE : subtotal;
}
module.exports = { calculateTotal };Test still passes — GREEN maintained. Constants now communicate intent.
Next requirement: apply a 15% discount when total exceeds 200.
RED — write the failing test first:
it('should apply 15% discount when total exceeds 200', () => {
const items = [{ price: 110 }, { price: 110 }]; // total = 220
expect(calculateTotal(items)).toBe(187); // 220 * 0.85
});GREEN — extend the implementation minimally:
function calculateTotal(items) {
const subtotal = items.reduce((sum, { price }) => sum + price, 0);
if (subtotal > 200) return subtotal * 0.85;
if (subtotal > 100) return subtotal * 0.9;
return subtotal;
}REFACTOR — remove duplication with a tiered structure:
const DISCOUNT_TIERS = [
{ threshold: 200, rate: 0.85 },
{ threshold: 100, rate: 0.9 },
];
function calculateTotal(items) {
const subtotal = items.reduce((sum, { price }) => sum + price, 0);
const tier = DISCOUNT_TIERS.find(({ threshold }) => subtotal > threshold);
return tier ? subtotal * tier.rate : subtotal;
}Both tests pass — ready for the next cycle.
7c8ba72
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.