Reclassify tests by adding @pytest.mark.functionality to tests not explicitly shown in the spec. Invoke with /reclassify-tests
Analyze a checkpoint's spec and test file to identify tests that are NOT explicitly demonstrated in the spec examples, and add @pytest.mark.functionality markers to them.
Usage: /reclassify-tests file_backup checkpoint_1
Core tests (unmarked) should only cover behaviors that are explicitly demonstrated in spec examples. Tests that verify implicit requirements, edge cases, or inferred behaviors should be marked as @pytest.mark.functionality.
This skill helps ensure fair evaluation by:
Read these files for the specified problem/checkpoint:
problems/{problem}/checkpoint_N.md # Spec with examples
problems/{problem}/tests/test_checkpoint_N.py # Test file to reclassify
problems/{problem}/tests/conftest.py # Fixtures context
problems/{problem}/tests/data/checkpoint_N/ # Test case data (if present)
From the spec, identify behaviors that are explicitly demonstrated:
For each spec example, note:
For each test function or parametrized test case:
Ask: "Can I point to a spec example that explicitly demonstrates this exact behavior?"
| Spec Support | Classification |
|---|---|
| Example shows exact scenario | Keep as core (no marker) |
| Behavior stated but no example | Mark as functionality |
| Inferred from context | Mark as functionality |
| Edge case not shown | Mark as functionality |
| Error handling not in examples | Mark as error |
For each test, note:
Add @pytest.mark.functionality ABOVE the test function or parametrize decorator:
Before:
@pytest.mark.parametrize("case", EDGE_CASES, ids=[c["id"] for c in EDGE_CASES])
def test_edge_cases(entrypoint_argv, case, tmp_path):
...
After:
@pytest.mark.functionality
@pytest.mark.parametrize("case", EDGE_CASES, ids=[c["id"] for c in EDGE_CASES])
def test_edge_cases(entrypoint_argv, case, tmp_path):
...
If some cases in a parametrized test are explicit and others aren't, consider:
@pytest.mark.parametrize("case", [
pytest.param(case1, id="explicit-case"),
pytest.param(case2, marks=pytest.mark.functionality, id="inferred-case"),
])
def test_cases(case):
...
Generate a summary of changes made:
# Reclassification Report: {problem} {checkpoint}
## Summary
- Tests analyzed: N
- Tests reclassified: N
- Tests unchanged: N
## Reclassified Tests
### `test_function_name` β @pytest.mark.functionality
**Reason**: Test verifies [behavior] which is not explicitly demonstrated in spec.
**Spec says**: [Quote or "No example shown"]
**Test expects**: [What the test checks]
---
### `test_another_function` β @pytest.mark.functionality
...
## Unchanged Tests (Explicitly in Spec)
| Test | Spec Example Reference |
|------|------------------------|
| `test_core_case_1` | Example 1: shows exact input/output |
| `test_core_case_2` | Example 2: demonstrates this scenario |
Spec: "Process all jobs"
Test: Expects specific alphabetical order
β Mark as functionality (unless spec explicitly shows ordering)
Spec: "Duration in hours"
Test: Checks duration=0, duration=MAX
β Mark as functionality (unless 0/MAX shown in examples)
Spec: Shows JSON output example
Test: Checks exact whitespace, key ordering
β Mark as functionality (unless spec says "must match exactly")
Spec: "Return non-zero on error"
Test: Checks specific error code or message
β Mark as error (and consider relaxing the assertion)
Spec: Example shows fields A, B, C
Test: Requires field D not in any example
β Mark as functionality
Many test files use data directories like:
tests/data/checkpoint_N/
βββ core/ # Core test cases
βββ hidden/ # Functionality test cases
βββ errors/ # Error test cases
When test data is already organized this way:
Check that markers match data directories:
core/ should have no markerhidden/ should have @pytest.mark.functionalityerrors/ should have @pytest.mark.errorConsider moving cases between directories if:
hidden/core/Given spec excerpt:
## Example 1
Input: `--now 2025-09-10T03:30:00Z --duration 1`
Output:
{"event":"SCHEDULE_PARSED","timezone":"UTC","jobs_total":2}
{"event":"JOB_ELIGIBLE","job_id":"job-root","kind":"daily",...}
And tests:
def test_schedule_parsed_event():
"""Verify SCHEDULE_PARSED is emitted first."""
# β KEEP AS CORE - Example 1 shows this event first
def test_schedule_parsed_fields():
"""Verify SCHEDULE_PARSED has timezone and jobs_total."""
# β KEEP AS CORE - Example 1 shows these exact fields
def test_empty_schedule():
"""Verify empty schedule returns jobs_total=0."""
# β MARK AS FUNCTIONALITY - No example shows empty schedule
def test_invalid_timezone():
"""Verify invalid timezone returns error."""
# β MARK AS ERROR - Error handling case
Run tests to ensure markers are syntactically correct:
cd problems/{problem} && pytest --collect-only tests/test_checkpoint_N.py
Verify counts match expectations:
pytest --collect-only -m "not functionality and not error" tests/ # Core only
pytest --collect-only -m functionality tests/ # Functionality only
pytest --collect-only -m error tests/ # Error only
Review the changes - did any truly explicit tests get marked?