Claude Code Plugins

Community-maintained marketplace

Feedback

test-coverage-boost

@j0KZ/mcp-agents
0
0

Increase test coverage from 0% to 80%+ in ANY project, ANY testing framework

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name test-coverage-boost
description Increase test coverage from 0% to 80%+ in ANY project, ANY testing framework

Test Coverage Boost - From Zero to Hero Testing

🎯 When to Use This Skill

Use when you need to:

  • Add tests to untested code
  • Increase coverage for CI/CD requirements
  • Prepare for major refactoring
  • Meet team coverage goals (usually 70-80%)
  • Fix flaky or broken tests
  • Implement TDD practices

⚡ Quick Coverage Check

Check Current Coverage:

# JavaScript (Jest/Vitest)
npm test -- --coverage

# Python
pytest --cov=. --cov-report=html

# Go
go test -cover ./...

# Java
mvn clean test jacoco:report

# Ruby
bundle exec rspec --coverage

# .NET
dotnet test /p:CollectCoverage=true

📊 The Coverage Ladder (0% → 80%)

Level 0: No Tests (0% coverage)

Level 1: Critical Path (20% coverage)

Level 2: Happy Path (40% coverage)

Level 3: Edge Cases (60% coverage)

Level 4: Error Handling (80% coverage)

Level 5: Full Coverage (95%+)

🎯 Strategic Test Writing (80/20 Rule)

WITH MCP (Test Generator):

"Generate tests for the most critical untested functions"
"Create tests to reach 80% coverage for [module]"

WITHOUT MCP - Priority Order:

1. Test Business Critical Code First (20% effort → 80% value)

// Priority 1: Money/Payment handling
test('calculateTotal should handle discounts correctly', () => {
  expect(calculateTotal(100, 0.2)).toBe(80); // 20% discount
  expect(calculateTotal(100, 0)).toBe(100);   // No discount
  expect(calculateTotal(100, 1)).toBe(0);     // 100% discount
});

// Priority 2: Authentication/Authorization
test('user should not access admin functions', () => {
  const user = { role: 'user' };
  expect(() => adminFunction(user)).toThrow('Unauthorized');
});

// Priority 3: Data validation
test('email validator should reject invalid emails', () => {
  expect(validateEmail('notanemail')).toBe(false);
  expect(validateEmail('test@example.com')).toBe(true);
});

2. The Test Writing Formula

// Universal Test Structure (AAA Pattern)
test('should [expected behavior] when [condition]', () => {
  // Arrange - Set up test data
  const input = { /* test data */ };
  const expected = { /* expected result */ };

  // Act - Execute the function
  const result = functionUnderTest(input);

  // Assert - Verify the result
  expect(result).toEqual(expected);
});

📝 Test Patterns by Code Type

1. Pure Functions (Easiest to Test)

// Function to test
function addTax(price, taxRate) {
  return price * (1 + taxRate);
}

// Tests
describe('addTax', () => {
  test('should add tax correctly', () => {
    expect(addTax(100, 0.1)).toBe(110);
  });

  test('should handle zero tax', () => {
    expect(addTax(100, 0)).toBe(100);
  });

  test('should handle negative price', () => {
    expect(addTax(-100, 0.1)).toBe(-110);
  });
});

2. Async Functions

// Function to test
async function fetchUser(id) {
  const response = await api.get(`/users/${id}`);
  return response.data;
}

// Tests
describe('fetchUser', () => {
  test('should fetch user successfully', async () => {
    // Mock the API
    api.get = jest.fn().mockResolvedValue({
      data: { id: 1, name: 'John' }
    });

    const user = await fetchUser(1);
    expect(user.name).toBe('John');
  });

  test('should handle API errors', async () => {
    api.get = jest.fn().mockRejectedValue(new Error('Network error'));

    await expect(fetchUser(1)).rejects.toThrow('Network error');
  });
});

3. Classes/Objects

// Class to test
class ShoppingCart {
  constructor() {
    this.items = [];
  }

  addItem(item) {
    this.items.push(item);
  }

  getTotal() {
    return this.items.reduce((sum, item) => sum + item.price, 0);
  }
}

// Tests
describe('ShoppingCart', () => {
  let cart;

  beforeEach(() => {
    cart = new ShoppingCart();
  });

  test('should start empty', () => {
    expect(cart.items).toHaveLength(0);
  });

  test('should add items', () => {
    cart.addItem({ name: 'Book', price: 10 });
    expect(cart.items).toHaveLength(1);
  });

  test('should calculate total', () => {
    cart.addItem({ name: 'Book', price: 10 });
    cart.addItem({ name: 'Pen', price: 2 });
    expect(cart.getTotal()).toBe(12);
  });
});

4. API Endpoints

// Express endpoint
app.get('/api/users/:id', async (req, res) => {
  const user = await User.findById(req.params.id);
  if (!user) return res.status(404).json({ error: 'Not found' });
  res.json(user);
});

// Tests
describe('GET /api/users/:id', () => {
  test('should return user when exists', async () => {
    const response = await request(app)
      .get('/api/users/1')
      .expect(200);

    expect(response.body).toHaveProperty('id', 1);
  });

  test('should return 404 when user not found', async () => {
    const response = await request(app)
      .get('/api/users/999')
      .expect(404);

    expect(response.body.error).toBe('Not found');
  });
});

🚀 Rapid Coverage Improvement Strategy

Day 1: Foundation (0% → 20%)

# 1. Setup test infrastructure
npm install --save-dev jest @types/jest

# 2. Create test script
# package.json
"scripts": {
  "test": "jest",
  "test:coverage": "jest --coverage",
  "test:watch": "jest --watch"
}

# 3. Write first test for main function
echo "describe('app', () => {
  test('should start', () => {
    expect(true).toBe(true);
  });
});" > app.test.js

Day 2: Critical Paths (20% → 40%)

// Test the money flow
test('payment processing flow', async () => {
  // Test the entire payment pipeline
});

// Test user authentication
test('login flow', async () => {
  // Test login process end-to-end
});

Day 3: Happy Paths (40% → 60%)

// Test successful scenarios
test('user can create account', () => {});
test('user can update profile', () => {});
test('user can delete account', () => {});

Day 4: Edge Cases (60% → 70%)

// Test boundaries and limits
test('handles maximum input size', () => {});
test('handles empty input', () => {});
test('handles special characters', () => {});

Day 5: Error Cases (70% → 80%)

// Test error handling
test('handles network timeout', () => {});
test('handles invalid data', () => {});
test('handles concurrent access', () => {});

🎯 Coverage Improvement Techniques

1. Find Untested Code

# Generate coverage report
npm test -- --coverage

# Open HTML report
open coverage/index.html  # Mac
xdg-open coverage/index.html  # Linux
start coverage/index.html  # Windows

# Red lines = untested code

2. Test the Untestable

Mocking External Dependencies:

// Mock database
jest.mock('./database', () => ({
  query: jest.fn(),
  connect: jest.fn()
}));

// Mock file system
jest.mock('fs', () => ({
  readFile: jest.fn((path, callback) => {
    callback(null, 'mock file content');
  })
}));

// Mock HTTP requests
jest.mock('axios');
axios.get.mockResolvedValue({ data: 'test' });

Testing Private Methods:

// Option 1: Test through public interface
class Calculator {
  #privateMethod() { return 42; }
  publicMethod() { return this.#privateMethod(); }
}

test('private method via public', () => {
  const calc = new Calculator();
  expect(calc.publicMethod()).toBe(42);
});

// Option 2: Extract to separate testable function
function complexLogic(input) { /* ... */ }
export { complexLogic };  // Test directly

3. Parameterized Tests (Test Multiple Cases)

// Jest
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 2, 4],
])('add(%i, %i) = %i', (a, b, expected) => {
  expect(add(a, b)).toBe(expected);
});

// Python pytest
@pytest.mark.parametrize("input,expected", [
  (1, 2),
  (2, 4),
  (3, 6),
])
def test_double(input, expected):
    assert double(input) == expected

📊 Coverage Goals by Project Type

Web Application

  • Controllers/Routes: 90%+ (critical paths)
  • Business Logic: 85%+ (core features)
  • Utilities: 95%+ (pure functions)
  • UI Components: 70%+ (focus on logic)
  • Database Models: 80%+ (validations)

API Service

  • Endpoints: 95%+ (all routes)
  • Middleware: 90%+ (auth, validation)
  • Services: 85%+ (business logic)
  • Error Handlers: 100% (critical)

Library/Package

  • Public API: 100% (all exports)
  • Core Logic: 95%+ (main features)
  • Edge Cases: 90%+ (robustness)
  • Examples: 100% (documentation)

💡 Pro Tips

Speed Up Test Writing:

# Generate test boilerplate
# VS Code: Install "Jest Snippets" extension
# Type: "desc" → describe block
# Type: "test" → test block
# Type: "exp" → expect statement

Test Data Builders:

// Create reusable test data
class UserBuilder {
  constructor() {
    this.user = {
      id: 1,
      name: 'Test User',
      email: 'test@example.com'
    };
  }

  withName(name) {
    this.user.name = name;
    return this;
  }

  withEmail(email) {
    this.user.email = email;
    return this;
  }

  build() {
    return this.user;
  }
}

// Usage
const user = new UserBuilder()
  .withName('John')
  .withEmail('john@example.com')
  .build();

Coverage Exclusions:

// Istanbul ignore comments
/* istanbul ignore next */  // Ignore next line
/* istanbul ignore if */    // Ignore if block
/* istanbul ignore else */  // Ignore else block

// Jest coverage config
// package.json
"jest": {
  "coveragePathIgnorePatterns": [
    "node_modules",
    "test-fixtures",
    ".mock.js"
  ],
  "coverageThreshold": {
    "global": {
      "branches": 80,
      "functions": 80,
      "lines": 80,
      "statements": 80
    }
  }
}

🎯 Success Checklist

Your tests are good when:

  • ✅ Coverage > 80%
  • ✅ Tests run fast (< 1 minute)
  • ✅ Tests are deterministic (no flakiness)
  • ✅ Tests are readable (clear descriptions)
  • ✅ Tests catch real bugs
  • ✅ CI/CD pipeline includes tests
  • ✅ Team writes tests for new features

Remember: 80% coverage with good tests > 100% coverage with bad tests! 🎯