Alle Skills
Web und Code
Unit-Tests für eine Funktion
Eine Funktion samt Beschreibung wird zu Unit-Tests mit Grenzfällen.
Die Demo nutzt erfundene Daten. Die gezeigte Ausgabe ist das, was der Skill aus dieser Beispieleingabe erzeugt hat.
In 3 Schritten ausprobieren
- 01
Kopiere den Ordner oder nur SKILL.md nach .claude/skills/ in deinem Projekt (oder nach ~/.claude/skills/, um ihn überall zu nutzen).
- 02
Öffne Claude Code und frag ihn mit Namen an, zum Beispiel: Nutze den Skill test-writer für meine Dateien.
- 03
Prüfe das Ergebnis. Skills schreiben eine neue Datei und überschreiben nie deine eigenen.
Beispieldurchlauf ansehen
Beispieleingabe · input.py
"""Function under test (fictional) plus the description the user gave.
Description:
parse_duration turns text like "1h30m", "45s" or "2m 10s" into a whole
number of seconds. Units are h, m and s (any case). Spaces are allowed
between parts and around the text. Each unit may appear at most once and
parts must go from largest to smallest. Empty or invalid text raises
ValueError. Anything that is not a string raises TypeError.
"""
import re
_PART = re.compile(r"(\d+)\s*([hms])", re.IGNORECASE)
_SECONDS = {"h": 3600, "m": 60, "s": 1}
_ORDER = "hms"
def parse_duration(text):
if not isinstance(text, str):
raise TypeError("text must be a string")
cleaned = text.strip().lower()
if not cleaned:
raise ValueError("empty duration")
pos = 0
last_rank = -1
total = 0
for match in _PART.finditer(cleaned):
gap = cleaned[pos:match.start()]
if gap.strip():
raise ValueError("unexpected text: " + gap.strip())
unit = match.group(2)
rank = _ORDER.index(unit)
if rank <= last_rank:
raise ValueError("units must be unique and go from h to s")
last_rank = rank
total += int(match.group(1)) * _SECONDS[unit]
pos = match.end()
if pos == 0 or cleaned[pos:].strip():
raise ValueError("invalid duration: " + text)
return total
Beispielausgabe · output.py
"""Tests for parse_duration (from examples/input.py, saved as durations.py).
Run: python -m pytest test_durations.py -q
"""
import pytest
from durations import parse_duration
# --- normal cases ---------------------------------------------------------
@pytest.mark.parametrize(
"text, expected",
[
("45s", 45),
("2m", 120),
("3h", 10800),
("1h30m", 5400),
("2m 10s", 130),
("1h 30m 15s", 5415),
],
)
def test_valid_durations_return_seconds(text, expected):
assert parse_duration(text) == expected
def test_units_are_case_insensitive():
assert parse_duration("1H30M") == 5400
def test_surrounding_and_inner_spaces_are_allowed():
assert parse_duration(" 1 h 5 m ") == 3900
# --- edge cases -----------------------------------------------------------
def test_zero_is_valid():
assert parse_duration("0s") == 0
def test_more_than_60_in_a_unit_is_not_normalised_but_counted():
assert parse_duration("90s") == 90
assert parse_duration("100m") == 6000
def test_very_large_hours():
assert parse_duration("1000h") == 3_600_000
def test_leading_zeros():
assert parse_duration("007s") == 7
# --- error cases ----------------------------------------------------------
@pytest.mark.parametrize("text", ["", " ", "\t\n"])
def test_empty_or_blank_text_raises_value_error(text):
with pytest.raises(ValueError):
parse_duration(text)
@pytest.mark.parametrize(
"text",
[
"5", # number without a unit
"h", # unit without a number
"abc", # not a duration
"1h30", # trailing number without a unit
"-5s", # negative values are not supported
"1.5h", # decimals are not supported
"5d", # unknown unit
"1h, 30m", # punctuation between parts
],
)
def test_invalid_text_raises_value_error(text):
with pytest.raises(ValueError):
parse_duration(text)
@pytest.mark.parametrize("text", ["30m1h", "1h1h", "1m 1m", "10s5m"])
def test_repeated_or_out_of_order_units_raise_value_error(text):
with pytest.raises(ValueError):
parse_duration(text)
@pytest.mark.parametrize("value", [None, 90, 1.5, ["1h"], b"1h"])
def test_non_string_input_raises_type_error(value):
with pytest.raises(TypeError):
parse_duration(value)
Der Skill · SKILL.md
---
name: test-writer
description: Reads a small function and its description, then writes unit tests for normal, edge and error cases and runs them to confirm they pass. Use when a function has no tests, or when you need quick coverage before refactoring it.
---
# Test Writer
A function plus a plain description becomes a runnable test file that covers the happy path, the edges and the errors.
## When to use
- A small, self-contained function (Python or TypeScript) has no tests.
- You are about to refactor and want a safety net.
- Not for UI tests, tests that need a network or database, or whole-system test plans.
## Inputs
- The function source and a short description of what it should do (inputs, outputs, errors).
- The test framework in use (pytest, unittest, vitest, jest). If not given, look at the project; if there is none, ask.
- If the description and the code disagree, ask which one is right before writing tests.
## Steps
1. Read the function and the description. List each rule as a one-line behavior ("units must go from h to s").
2. Plan three groups: normal cases (typical valid inputs and each documented rule), edge cases (zero, empty, boundaries, very large values, case and whitespace), error cases (each exception or rejected input the description names, plus wrong types).
3. Write the tests with the framework's parametrize or table feature so each case is one readable line. Use clear names that state the behavior. One reason to fail per test.
4. Import the function as the project does; put a comment above groups of cases explaining what they cover.
5. Run the tests. If they all pass, count them. If one fails, decide who is wrong: the test (fix the test) or the function (report it as a bug to the user). Do not hide it.
6. Re-run once after any fix to a test and keep the final result.
## Output
Write the tests to a new file such as `test_<module>.py` or `<module>.test.ts` next to the code. In your reply give: the file name, the exact command you ran, the pass count, and any bug found.
Example command (Python): `python -m pytest test_durations.py -q`. Example (TypeScript): `pnpm exec vitest run durations.test.ts`.
Put the run command in a docstring or comment at the top of the test file.
## Rules
- Never change the function under test to make tests pass. If a test reveals a bug, report it and let the user decide.
- Never invent behavior the description or the code does not show. Mark unclear behavior as a question instead of asserting it.
- Never delete or weaken a failing assertion just to get a green run.
- Write results to a new file, never overwrite existing tests or the code.
- Do not use the network, real files outside a temp folder, or the system clock unless the function needs it; then inject or fake it.
- Keep code and data local.
Skills helfen dir beim Lesen und Ordnen. Sie ersetzen keine Rechts-, Medizin-, Steuer- oder Finanzberatung.
Weitere Skills
Briefing zu LandingpageEin kurzes Briefing wird zu einer einseitigen Mobile-first-HTML-Landingpage.
Barrierefreiheits-Check für eine SeitePrüft eine Seite auf Kontrast, Beschriftungen und Tippflächen und listet Korrekturen auf.
README aus deinen ProjektdateienLiest ein Projekt und schreibt eine korrekte README.