seb1n/testing
Generate, execute, and analyze tests for codebases, covering unit, integration, and end-to-end testing with coverage reporting.
npx skills add https://github.com/seb1n/awesome-ai-agent-skills --skill Testing
This skill enables an AI agent to systematically generate, run, and evaluate tests for a given codebase. It covers the full testing lifecycle — from analyzing source code and identifying meaningful test cases, through writing and executing tests, to measuring coverage and recommending improvements. The agent supports unit tests, integration tests, and end-to-end tests across multiple languages and frameworks.
pytest --cov, jest --coverage). Parse the coverage report to identify uncovered lines, branches, and functions. Flag any critical code paths — error handlers, security checks, data validation — that lack coverage.| Language | Framework | Runner Command |
|------------|-----------------|---------------------------------|
| Python | pytest | pytest --cov=src -v |
| JavaScript | Jest | npx jest --coverage --verbose |
| TypeScript | Jest / Vitest | npx vitest run --coverage |
| Java | JUnit 5 | mvn test |
| Go | testing (stdlib) | go test -cover ./... |
| Rust | cargo test | cargo test |
Provide one or more of the following inputs:
src/utils/parser.py).Given this source file src/cart.py:
class ShoppingCart:
def __init__(self):
self.items = []
def add_item(self, name: str, price: float, quantity: int = 1):
if price < 0:
raise ValueError("Price cannot be negative")
if quantity < 1:
raise ValueError("Quantity must be at least 1")
self.items.append({"name": name, "price": price, "quantity": quantity})
def total(self) -> float:
return sum(item["price"] * item["quantity"] for item in self.items)
def remove_item(self, name: str):
self.items = [item for item in self.items if item["name"] != name]
The agent generates tests/test_cart.py:
import pytest
from src.cart import ShoppingCart
@pytest.fixture
def cart():
return ShoppingCart()
def test_add_item_and_total(cart):
cart.add_item("Widget", 9.99, 2)
assert cart.total() == pytest.approx(19.98)
def test_empty_cart_total_is_zero(cart):
assert cart.total() == 0.0
def test_add_item_negative_price_raises(cart):
with pytest.raises(ValueError, match="Price cannot be negative"):
cart.add_item("Bad", -1.0)
def test_add_item_zero_quantity_raises(cart):
with pytest.raises(ValueError, match="Quantity must be at least 1"):
cart.add_item("Bad", 5.0, 0)
def test_remove_item(cart):
cart.add_item("A", 1.0)
cart.add_item("B", 2.0)
cart.remove_item("A")
assert cart.total() == 2.0
def test_remove_nonexistent_item_does_nothing(cart):
cart.add_item("A", 1.0)
cart.remove_item("Z")
assert cart.total() == 1.0
Run: pytest tests/test_cart.py --cov=src -v
Given this source file src/validator.js:
function isValidEmail(email) {
if (typeof email !== "string") return false;
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(email);
}
function isStrongPassword(password) {
if (typeof password !== "string") return false;
return (
password.length >= 8 &&
/[A-Z]/.test(password) &&
/[a-z]/.test(password) &&
/[0-9]/.test(password)
);
}
module.exports = { isValidEmail, isStrongPassword };
The agent generates src/__tests__/validator.test.js:
const { isValidEmail, isStrongPassword } = require("../validator");
describe("isValidEmail", () => {
test.each([
["[email protected]", true],
["[email protected]", true],
["missing-at-sign.com", false],
["@no-local.com", false],
["spaces [email protected]", false],
["", false],
])("isValidEmail(%s) => %s", (input, expected) => {
expect(isValidEmail(input)).toBe(expected);
});
test("returns false for non-string input", () => {
expect(isValidEmail(null)).toBe(false);
expect(isValidEmail(42)).toBe(false);
});
});
describe("isStrongPassword", () => {
test("accepts a strong password", () => {
expect(isStrongPassword("Str0ngPwd")).toBe(true);
});
test("rejects short password", () => {
expect(isStrongPassword("Ab1")).toBe(false);
});
test("rejects password without uppercase", () => {
expect(isStrongPassword("alllower1")).toBe(false);
});
test("rejects non-string input", () => {
expect(isStrongPassword(undefined)).toBe(false);
});
});
Run: npx jest --coverage --verbose
test_empty_cart_total_is_zero rather than test_total_method. This makes failures self-documenting.@pytest.mark.parametrize or test.each instead of duplicating test bodies.pytest-asyncio, Jest's async handling). The agent will use the appropriate pattern but may ask for confirmation on timeout thresholds.Take seb1n/testing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.