Loading...
Automatically run relevant tests when code changes are detected, with intelligent test selection and parallel execution
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/code-test-runner-hook.sh",
"matchers": [
"write",
"edit",
"multiedit"
]
}
}
},
"scriptContent": "#!/usr/bin/env bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\necho \"🧪 Running tests for $FILE_PATH...\"\n\n# Get file extension and directory\nEXT=\"${FILE_PATH##*.}\"\nDIR=$(dirname \"$FILE_PATH\")\n\n# Find and run relevant tests based on file type\ncase \"$EXT\" in\n js|jsx|ts|tsx)\n # JavaScript/TypeScript files\n if [ -f \"package.json\" ]; then\n if command -v npm &> /dev/null && npm list jest &> /dev/null; then\n echo \"Running Jest tests...\"\n npm test -- --testPathPattern=\"$FILE_PATH\" --passWithNoTests 2>/dev/null\n elif command -v npm &> /dev/null && npm list vitest &> /dev/null; then\n echo \"Running Vitest tests...\"\n npx vitest run \"$FILE_PATH\" 2>/dev/null\n fi\n fi\n ;;\n py)\n # Python files\n if command -v pytest &> /dev/null; then\n echo \"Running pytest...\"\n pytest \"${FILE_PATH%.*}_test.py\" \"${DIR}/test_*.py\" 2>/dev/null || echo \"No Python tests found\"\n elif command -v python &> /dev/null; then\n echo \"Running Python unittest...\"\n python -m unittest discover -s \"$DIR\" -p \"*test*.py\" 2>/dev/null || echo \"No Python tests found\"\n fi\n ;;\n go)\n # Go files\n if command -v go &> /dev/null; then\n echo \"Running Go tests...\"\n go test \"${DIR}/...\" 2>/dev/null || echo \"No Go tests found\"\n fi\n ;;\n java)\n # Java files\n if command -v mvn &> /dev/null && [ -f \"pom.xml\" ]; then\n echo \"Running Maven tests...\"\n mvn test 2>/dev/null\n elif command -v gradle &> /dev/null && [ -f \"build.gradle\" ]; then\n echo \"Running Gradle tests...\"\n gradle test 2>/dev/null\n fi\n ;;\nesac\n\necho \"✅ Test execution completed for $FILE_PATH\" >&2\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/code-test-runner-hook.sh",
"matchers": [
"write",
"edit",
"multiedit"
]
}
}
}#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
echo "🧪 Running tests for $FILE_PATH..."
# Get file extension and directory
EXT="${FILE_PATH##*.}"
DIR=$(dirname "$FILE_PATH")
# Find and run relevant tests based on file type
case "$EXT" in
js|jsx|ts|tsx)
# JavaScript/TypeScript files
if [ -f "package.json" ]; then
if command -v npm &> /dev/null && npm list jest &> /dev/null; then
echo "Running Jest tests..."
npm test -- --testPathPattern="$FILE_PATH" --passWithNoTests 2>/dev/null
elif command -v npm &> /dev/null && npm list vitest &> /dev/null; then
echo "Running Vitest tests..."
npx vitest run "$FILE_PATH" 2>/dev/null
fi
fi
;;
py)
# Python files
if command -v pytest &> /dev/null; then
echo "Running pytest..."
pytest "${FILE_PATH%.*}_test.py" "${DIR}/test_*.py" 2>/dev/null || echo "No Python tests found"
elif command -v python &> /dev/null; then
echo "Running Python unittest..."
python -m unittest discover -s "$DIR" -p "*test*.py" 2>/dev/null || echo "No Python tests found"
fi
;;
go)
# Go files
if command -v go &> /dev/null; then
echo "Running Go tests..."
go test "${DIR}/..." 2>/dev/null || echo "No Go tests found"
fi
;;
java)
# Java files
if command -v mvn &> /dev/null && [ -f "pom.xml" ]; then
echo "Running Maven tests..."
mvn test 2>/dev/null
elif command -v gradle &> /dev/null && [ -f "build.gradle" ]; then
echo "Running Gradle tests..."
gradle test 2>/dev/null
fi
;;
esac
echo "✅ Test execution completed for $FILE_PATH" >&2
exit 0Tests run on every file save slowing down
Add file extension filter or test file detection: `if [[ "$FILE_PATH" == *test* ]] || [[ "$FILE_PATH" == *spec* ]]; then exit 0; fi` to skip running tests when editing test files themselves.
Jest testPathPattern not finding related tests
Pattern matches test file paths not source. Use `--findRelatedTests` instead: `npm test -- --findRelatedTests="$FILE_PATH"` which finds tests importing the changed file through dependency graph.
Hook runs tests twice with both Jest and Vitest
Detection uses `npm list jest` which may find both. Add explicit priority: `if npm list jest &> /dev/null; then run_jest; exit 0; elif npm list vitest ...` to prevent fallthrough.
Python tests fail to locate test directory
Hook looks for `${FILE_PATH%.*}_test.py` and `test_*.py`. For pytest, use explicit discovery: `pytest --collect-only "$DIR" 2>/dev/null | grep "test session starts"` to verify test detection.
Go tests timeout on large module changes
Add timeout flag and scope: `go test -timeout 30s "${DIR}" 2>/dev/null` instead of `${DIR}/...` which tests all subpackages. Or use `go test -short` for quick tests only during development.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters