
Testing Python
- 139 installs
- 99 repo stars
- Updated August 4, 2026
- thebeardedbearsas/claude-craft
Helps with testing & qa tasks.
About
testing-python is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted coding.
- testing-python
- Testing & QA
- AI-coding skill
Testing Python by the numbers
- 139 all-time installs (skills.sh)
- +3 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #906 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thebeardedbearsas/claude-craft --skill testing-pythonAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 139 |
|---|---|
| repo stars | ★ 99 |
| Last updated | August 4, 2026 |
| Repository | thebeardedbearsas/claude-craft ↗ |
What it does
Helps with testing & qa tasks.
Files
Stratégie de Tests Python 3.14+
Versions : Python 3.14+ | pytest 8.x | Ruff 0.8+ | mypy 1.13+ | Playwright
Ruff remplace Black + isort + Flake8 (10-100x plus rapide). mypy strict élimine les bugs de type à la compilation.
Stack recommandée 2026
| Type | Outil | Usage |
|---|---|---|
| Unit/Integration | pytest 8.x | Tests backend FastAPI/Django |
| Linting + Format | Ruff 0.8+ | 10-100× plus rapide que Black+Flake8 |
| Type checking | mypy 1.13+ strict | Vérification statique |
| E2E/Browser | Playwright | Tests frontend web |
| Mutation | Mutmut | Qualité des tests (score >= 80%) |
| Property-based | Hypothesis | Génération de cas de test automatique |
Sources : pytest, Ruff, Mutmut
Invariants non-négociables
- Couverture >= 80% (
--cov-fail-under=80danspyproject.toml) - mypy strict — zéro
Anynon justifié,disallow_untyped_defs = true - Ruff obligatoire (check + format) dans CI
- Pattern AAA (Arrange-Act-Assert) dans chaque test
- Fixtures pytest pour l'injection de dépendances (pas d'état global)
- Mutation score >= 80% via Mutmut
Checklist par type
| Type | Vérification |
|---|---|
| Unit | Isolation totale, fixtures pytest, mocks unittest.mock |
| Integration | TestClient FastAPI / Client Django, DB de test |
| E2E | Playwright sync_api, expect() assertions |
| Property | Hypothesis @given pour edge cases automatiques |
| Mutation | mutmut run, score >= 80 avant merge |
Détails complets, exemples de code, configs et checklists : voir REFERENCE.md
Stratégie de Tests Python 3.14+ — Référence Complète
Versions : Python 3.14+ | pytest 8.x | Ruff 0.8+ | mypy 1.13+ | Playwright
Configuration pytest + Ruff + mypy
# pyproject.toml
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = "--cov=app --cov-report=term-missing --cov-fail-under=80"
[tool.ruff]
line-length = 88
target-version = "py314"
select = ["E", "F", "I", "N", "W", "UP", "B", "C4", "SIM"]
fix = true
[tool.mypy]
python_version = "3.14"
strict = true
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = trueSource : Ruff Configuration
Tests pytest avec fixtures
# tests/test_user_service.py
import pytest
from app.services.user_service import UserService
from app.models.user import User
@pytest.fixture
def user_service():
"""Fixture pour créer un service utilisateur avec dépendances mockées."""
return UserService(db=MockDatabase())
def test_create_user_returns_user_with_id(user_service):
# Arrange
user_data = {"name": "Alice", "email": "alice@example.com"}
# Act
user = user_service.create_user(user_data)
# Assert
assert user.id is not None
assert user.name == "Alice"
assert user.email == "alice@example.com"Source : pytest fixtures
Mutation Testing avec Mutmut
# Installation
pip install mutmut
# Exécution
mutmut run
# Rapport
mutmut results
mutmut html # Génère rapport HTML
# Seuil minimum mutation score
mutmut run --min-msi=80Philosophie : "Coverage mesure la quantité, mutation score mesure la qualité."
Source : Mutmut
Property-based Testing avec Hypothesis
# tests/test_calculator.py
from hypothesis import given, strategies as st
from app.calculator import calculate_total
@given(st.lists(st.floats(min_value=0, max_value=1000)))
def test_calculate_total_is_never_negative(prices):
"""Le total ne peut jamais être négatif."""
total = calculate_total(prices)
assert total >= 0
@given(st.lists(st.floats(min_value=0, max_value=1000)))
def test_calculate_total_order_independent(prices):
"""L'ordre des prix ne change pas le total."""
total1 = calculate_total(prices)
total2 = calculate_total(prices[::-1])
assert total1 == total2Source : Hypothesis
Tests FastAPI avec pytest
# tests/test_api.py
from fastapi.testclient import TestClient
from app.main import app
client = TestClient(app)
def test_get_user_returns_200():
response = client.get("/users/123")
assert response.status_code == 200
assert response.json()["id"] == "123"
def test_create_user_validates_email():
response = client.post("/users", json={"name": "Bob", "email": "invalid"})
assert response.status_code == 422 # Validation errorSource : FastAPI Testing
Ruff — Linting + Formatting unifié
Remplace Black, isort, Flake8, pyupgrade — 10-100× plus rapide.
# Check
ruff check .
# Format
ruff format .
# Fix automatique
ruff check --fix .Source : Ruff
mypy strict mode
# app/services/user_service.py
from typing import Protocol
class Database(Protocol):
def save(self, user: User) -> None: ...
class UserService:
def __init__(self, db: Database) -> None:
self._db = db
def create_user(self, data: dict[str, str]) -> User:
user = User(**data)
self._db.save(user)
return userSource : mypy strict mode
Tests Playwright pour E2E
# tests/e2e/test_login.py
from playwright.sync_api import Page, expect
def test_user_can_login(page: Page):
page.goto("http://localhost:8000/login")
page.fill('input[name="email"]', "alice@example.com")
page.fill('input[name="password"]', "secret")
page.click('button[type="submit"]')
expect(page).to_have_url("http://localhost:8000/dashboard")Source : Playwright Python
---
Voir @.claude/rules/07-testing.md pour principes transverses.