Skip to main content
hook

test-runner — Claude Code hook: run tests after every edit

This hook fires a test command right after Claude edits a file. Handy when you keep forgetting to re-run checks by hand.

Install into Claude Code · claude-code-templates All methods and platforms ↓
npx claude-code-templates@latest --hook testing/test-runner
Open on GitHub

What test-runner does

The hook listens on PostToolUse with an Edit matcher. Once the agent saves a change, the command inspects the file extension and what sits next to it in the project.

For .js and .ts it wants a package.json, then runs npm test and falls back to yarn test. Python files go through pytest on that single file, gated on pytest.ini, setup.cfg or pyproject.toml. Ruby needs a Gemfile, after which bundle exec rspec takes over. Errors are suppressed, so a failing suite won't break your session — and you won't see why it failed either.

Dropping it into a repo with no test setup does nothing: without package.json, pytest.ini or Gemfile, no branch of the command runs.

What it helps with

  • run tests right after a file edit
  • catch a regression while the agent still has context
  • skip switching to a terminal for npm test
  • check one changed file instead of the whole suite
  • cover Python and Ruby in the same project

Example prompts for the agent

  • Edit src/api/users.ts and run the tests afterwards
  • Fix app/models/order.py — the hook will run pytest on that file
  • Update lib/parser.rb and confirm rspec passes

How to install test-runner

1claude-code-templates

npx claude-code-templates@latest --hook testing/test-runner

2Manually: put the files in place

.claude/settings.json

The hooks block: event (PreToolUse, PostToolUse, Stop…) → command. Personal ones go to ~/.claude/settings.json

Step by step, with commands for each platform: Claude Code hooks: what they are, where to configure them, how to block a risky command

Questions about test-runner

How do I install test-runner in Claude?

Run npx claude-code-templates@latest --hook testing/test-runner, then check .claude/settings.json — the hook entry should be written there.

What does test-runner do?

After each file edit it runs the matching test command: npm test or yarn test for JS and TS, pytest for Python, bundle exec rspec for Ruby.

Why aren't my tests running?

The hook only fires when project markers exist: package.json for JS and TS, pytest.ini, setup.cfg or pyproject.toml for Python, Gemfile for Ruby. Without them the command exits quietly.

Source text

test-runner.json · MIT
{
  "description": "Automatically run relevant tests after code changes. Detects test files and runs appropriate test commands based on file extensions and project structure.",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "hooks": [
          {
            "type": "command",
            "command": "if [[ \"$CLAUDE_TOOL_FILE_PATH\" == *.js || \"$CLAUDE_TOOL_FILE_PATH\" == *.ts ]] && [[ -f package.json ]]; then npm test 2>/dev/null || yarn test 2>/dev/null || true; elif [[ \"$CLAUDE_TOOL_FILE_PATH\" == *.py ]] && [[ -f pytest.ini || -f setup.cfg || -f pyproject.toml ]]; then pytest \"$CLAUDE_TOOL_FILE_PATH\" 2>/dev/null || python -m pytest \"$CLAUDE_TOOL_FILE_PATH\" 2>/dev/null || true; elif [[ \"$CLAUDE_TOOL_FILE_PATH\" == *.rb ]] && [[ -f Gemfile ]]; then bundle exec rspec \"$CLAUDE_TOOL_FILE_PATH\" 2>/dev/null || true; fi"
          }
        ]
      }
    ]
  }
}

© davila7 · MIT · davila7/claude-code-templates

Similar hooks

Everything for Testing and QA →

From the same set205

The whole set →

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor