arabelatso/test-case-reducer
Automatically reduces bug-triggering test cases to minimal form while preserving the failure. Use when debugging with large, complex test cases that need simplification, reproducing bugs with minimal examples, or creating regression tests from verbose failure scenarios. Takes a failing test and systematically removes unnecessary inputs, steps, assertions, and code using delta debugging and other reduction algorithms. Supports unit tests, integration tests, input files, and multiple programming languages (Python, JavaScript, Java, C/C++).
npx skills add https://github.com/ArabelaTso/Skills-4-SE --skill test-case-reducer
Automatically reduce bug-triggering test cases to minimal form while guaranteeing the reduced test still reproduces the same failure.
Test case reduction works by:
Ensure you have:
The oracle determines if the test still exhibits the expected failure:
Exit code:
--oracle exit_code --expected 1Exception type:
--oracle exception --expected ValueErrorOutput pattern:
--oracle output_pattern --expected "division by zero"Assertion:
--oracle assertion --expected AssertionErrorAggressive (fastest, smallest result):
Balanced (recommended):
Conservative (safest, most readable):
Using the provided script:
python scripts/reduce_test.py test_file.py \
--command "python test_file.py" \
--oracle exit_code \
--expected 1 \
--strategy balanced
Or manually apply reduction algorithms (see references/algorithms.md).
Examine the reduced test case:
Original test (15 lines):
import unittest
from mymodule import Calculator
class TestCalculator(unittest.TestCase):
def setUp(self):
self.calc = Calculator()
self.test_data = [1, 2, 3, 4, 5]
def test_divide(self):
result = self.calc.divide(10, 2)
self.assertEqual(result, 5)
result = self.calc.divide(10, 0) # This fails
self.assertEqual(result, 0)
if __name__ == '__main__':
unittest.main()
Reduction command:
python scripts/reduce_test.py test_calc.py \
--command "python test_calc.py" \
--oracle exception \
--expected "ZeroDivisionError"
Reduced test (3 lines):
from mymodule import Calculator
Calculator().divide(10, 0)
Original test (20 lines):
const request = require('supertest');
const app = require('../app');
describe('API Tests', () => {
beforeEach(() => {
// Setup database
db.reset();
db.seed();
});
it('should handle invalid user ID', async () => {
const response = await request(app)
.get('/api/users/invalid')
.set('Authorization', 'Bearer token')
.expect(400);
expect(response.body.error).toBe('Invalid user ID');
});
});
Reduced test (4 lines):
const request = require('supertest');
const app = require('../app');
request(app).get('/api/users/invalid').expect(400);
Original input (100 lines of JSON):
{
"users": [...100 user objects...],
"settings": {...many settings...},
"data": [...large data array...]
}
Reduced input (5 lines):
{
"users": [{"id": 42, "name": "Bob"}]
}
python scripts/reduce_test.py <test_file> \
--command "<command to run test>" \
--oracle <oracle_type> \
--expected <expected_value>
Required:
test_file: Path to the test file to reduce--command: Command to execute the test (e.g., python test.py, npm test)--oracle: Type of failure oracle (exit_code, exception, output_pattern, assertion)--expected: Expected value for the oracleOptional:
--strategy: Reduction strategy (aggressive, balanced, conservative)--timeout: Timeout in seconds for test executionPython test with exception:
python scripts/reduce_test.py test.py \
--command "python test.py" \
--oracle exception \
--expected "ValueError"
JavaScript test with exit code:
python scripts/reduce_test.py test.js \
--command "node test.js" \
--oracle exit_code \
--expected 1 \
--strategy aggressive
Java test with timeout:
python scripts/reduce_test.py Test.java \
--command "javac Test.java && java Test" \
--oracle output_pattern \
--expected "NullPointerException" \
--timeout 10
When not using the script, follow this process:
# Run original test
python test.py
# Verify it fails as expected
Remove half the test:
# Original
line1
line2
line3
line4
# Try first half
line1
line2
# Or second half
line3
line4
See references/algorithms.md for detailed algorithm.
Remove one line at a time, testing after each removal.
Ensure reduced test still fails with same error.
For detailed language-specific reduction techniques, see references/language-specific.md.
Python:
JavaScript:
Java:
C/C++:
Problem: Integration test with 200 lines fails intermittently
Solution:
Problem: 10MB JSON file causes parser to crash
Solution:
Problem: Unit test with extensive setup fails on one assertion
Solution:
Reduction removes too much:
Test becomes non-deterministic:
Reduction is too slow:
Syntax errors after reduction:
Take arabelatso/test-case-reducer 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.