clean-tests
Skill193 starsChanged 7 months agoMITView on GitHub
Use when writing, fixing, editing, or refactoring Python tests. Enforces Clean Code principles—fast tests, boundary coverage, one assert per test.
2 other projects use a version of this, 2 of them edited.
Adopted by
Most recently taken up by
- phanijapps/memexedited, first seen Oct 17, 2026
- ramybarsoum/claude-skillsedited, first seen Oct 13, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 2
- phanijapps/memex★ 0100% same
- ramybarsoum/claude-skills★ 0100% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- boy-scoutSkill
- clean-commentsSkill
- clean-functionsSkill
- clean-generalSkill
- clean-namesSkill
- python-clean-codeSkill
- boy-scoutSkill
- clean-commentsSkill
- clean-functionsSkill
- clean-generalSkill
- clean-namesSkill
- clean-testsSkill
- typescript-clean-codeSkill
The file
We split this skill into the rules it gives an agent
5 rules. About 0 are common, 4 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 12
Test everything that could possibly break.
- Very specific: line 55
Don't use @pytest.mark.skip to hide problems.
- Distinctive: line 96
When you find a bug, write tests for all similar cases.
- Distinctive: line 111
When tests fail, look for patterns.
- Distinctive: line 120
Look at which code paths are untested.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Clean Tests
T1: Insufficient Tests
Test everything that could possibly break. Use coverage tools as a guide, not a goal.
# Bad - only tests happy path
def test_divide():
assert divide(10, 2) == 5
# Good - tests edge cases too
def test_divide_normal():
assert divide(10, 2) == 5
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(10, 0)
def test_divide_negative():
assert divide(-10, 2) == -5T2: Use a Coverage Tool
Coverage tools report gaps in your testing strategy. Don't ignore them.
# Run with coverage
pytest --cov=myproject --cov-report=term-missing
# Aim for meaningful coverage, not 100%T3: Don't Skip Trivial Tests
Trivial tests document behavior and catch regressions. They're worth more than their cost.
# Worth having - documents expected behavior
def test_user_default_role():
user = User(name="Alice")
assert user.role == "member"T4: An Ignored Test Is a Question About an Ambiguity
Don't use @pytest.mark.skip to hide problems. Either fix the test or delete it.
# Bad - hiding a problem
@pytest.mark.skip(reason="flaky, fix later")
def test_async_operation():
...
# Good - either fix it or document why it's skipped
@pytest.mark.skip(reason="Requires Redis, see CONTRIBUTING.md for setup")
def test_cache_invalidation():
...T5: Test Boundary Conditions
Bugs congregate at boundaries. Test them explicitly.
def test_pagination_boundaries():
items = list(range(100))
# First page
assert paginate(items, page=1, size=10) == items[0:10]
# Last page
assert paginate(items, page=10, size=10) == items[90:100]
# Beyond last page
assert paginate(items, page=11, size=10) == []
# Page zero (invalid)
with pytest.raises(ValueError):
paginate(items, page=0, size=10)
# Empty list
assert paginate([], page=1, size=10) == []T6: Exhaustively Test Near Bugs
When you find a bug, write tests for all similar cases. Bugs cluster.
# Found bug: off-by-one in date calculation
# Now test ALL date boundaries
def test_month_boundaries():
assert last_day_of_month(2024, 1) == 31 # January
assert last_day_of_month(2024, 2) == 29 # Leap year February
assert last_day_of_month(2023, 2) == 28 # Non-leap February
assert last_day_of_month(2024, 4) == 30 # 30-day month
assert last_day_of_month(2024, 12) == 31 # DecemberT7: Patterns of Failure Are Revealing
When tests fail, look for patterns. They often point to deeper issues.
# If all async tests fail intermittently,
# the problem isn't the tests—it's the async handlingT8: Test Coverage Patterns Can Be Revealing
Look at which code paths are untested. Often they reveal design problems.
# If you can't easily test a function, it probably does too much
# Refactor for testabilityT9: Tests Should Be Fast
Slow tests don't get run. Keep unit tests under 100ms each.
# Bad - hits real database
def test_user_creation():
db = connect_to_database() # Slow!
user = db.create_user("Alice")
assert user.name == "Alice"
# Good - uses mock or in-memory
def test_user_creation():
db = InMemoryDatabase()
user = db.create_user("Alice")
assert user.name == "Alice"Test Organization
F.I.R.S.T. Principles
- Fast: Tests should run quickly
- Independent: Tests shouldn't depend on each other
- Repeatable: Same result every time, any environment
- Self-Validating: Pass or fail, no manual inspection
- Timely: Written before or with the code, not after
One Concept Per Test
# Bad - testing multiple things
def test_user():
user = User("Alice", "alice@example.com")
assert user.name == "Alice"
assert user.email == "alice@example.com"
assert user.is_valid()
user.activate()
assert user.is_active
# Good - one concept each
def test_user_stores_name():
user = User("Alice", "alice@example.com")
assert user.name == "Alice"
def test_user_stores_email():
user = User("Alice", "alice@example.com")
assert user.email == "alice@example.com"
def test_new_user_is_valid():
user = User("Alice", "alice@example.com")
assert user.is_valid()
def test_user_can_be_activated():
user = User("Alice", "alice@example.com")
user.activate()
assert user.is_activeQuick Reference
| Rule | Principle |
| T1 | Test everything that could break |
| T2 | Use coverage tools |
| T3 | Don't skip trivial tests |
| T4 | Ignored test = ambiguity question |
| T5 | Test boundary conditions |
| T6 | Exhaustively test near bugs |
| T7 | Look for patterns in failures |
| T8 | Check coverage when debugging |
| T9 | Tests must be fast (<100ms) |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

