Skip to content

Debugging Karma Tests in the Browser

Because Karma runs your tests in a real browser, you have full access to real DevTools — the same breakpoints, console, and DOM inspector you'd use debugging any web application. This lesson covers using them effectively against Karma tests.

Opening DevTools Against a Karma Run

With Karma running in watch mode, open http://localhost:9876/debug.html in a visible browser and open its DevTools normally (F12 or Cmd+Option+I). The Sources panel shows your actual test and application files (assuming source maps are configured correctly), and the Console panel shows any output your code produces directly.

# Terminal 1: keep Karma running in watch mode
karma start

# Then, in any browser:
# open http://localhost:9876/debug.html
# open DevTools (F12) and use Sources / Console as normal

The debug page reruns your suite automatically whenever Karma detects a file change, exactly like a normal watch-mode run.

Setting Breakpoints

// Option 1: a debugger statement directly in source or spec code
function calculateTotal(items) {
  debugger; // execution pauses here when DevTools is open
  return items.reduce((sum, item) => sum + item.price, 0);
}

// Option 2: a breakpoint set directly in the Sources panel,
// on any line of your actual source file
  • debugger; statements only pause execution when DevTools is actually open and attached.
  • Breakpoints set in the Sources panel persist across reruns within the same DevTools session.
  • Conditional breakpoints (right-click a line number in Chrome DevTools) are useful for pausing only on a specific iteration.
  • Remove debugger; statements before committing — they're a debugging aid, not something to ship.

Browser Debugging Cheat Sheet

Common DevTools techniques applied to a Karma test run.

Technique How
Pause execution debugger; statement or a Sources panel breakpoint
Inspect a variable's value Hover over it while paused, or use the Console
See console output Console panel (enable client.captureConsole for terminal too)
Inspect rendered DOM Elements panel, exactly like debugging a real page
Step through code Step over/into/out controls while paused at a breakpoint

Debugging Asynchronous Test Failures

Async failures are often the hardest to debug because the relevant code may execute after the surrounding test function has already 'moved on.' Setting a breakpoint inside a .then() callback or right before an await line, then stepping through carefully, is usually more productive than scattering console.log() calls.

it('resolves with user data', async function() {
  debugger; // pause before the async call
  const user = await fetchUser(1);
  debugger; // pause after it resolves, inspect the actual value
  expect(user.name).toBe('Ada');
});

Debugging a Headless-Only Failure

Sometimes a failure only reproduces in ChromeHeadless, not visible Chrome — timing or rendering differences can occasionally matter. Headless Chrome's remote debugging port (covered in the ChromeHeadless lesson) lets you attach real DevTools even to the headless instance itself.

Common Mistakes

  • Scattering console.log() statements everywhere instead of using a proper breakpoint and stepping through.
  • Forgetting DevTools must actually be open for debugger; statements to pause execution at all.
  • Debugging only in a visible browser when the actual failure is specific to the headless configuration.
  • Leaving debugger; statements committed into the codebase after finishing an investigation.

Key Takeaways

  • Karma's /debug.html page gives full, real DevTools access to your test files in any browser.
  • debugger; statements and Sources panel breakpoints work exactly as they would on any web page.
  • Async failures are often best debugged by pausing before and after the awaited call, not just with logging.
  • Headless-specific failures can be debugged via headless Chrome's remote debugging port.

Pro Tip

For a genuinely confusing async test failure, set two breakpoints — one immediately before the asynchronous call and one immediately after — rather than one. Comparing state at both points side by side reveals far more than stepping through line by line from the very top.