The Failed Test: Debugging Automation Like a Senior · Lesson 5 of 6 · Bonus module

It Only Fails in CI

The worst failures happen on a machine you can't watch. Shrink the difference between your laptop and the runner — and make the pipeline hand you evidence, not theories.

By Shahriyar · Updated

The usual suspects

Reproduce the delta, not the mystery

▸ Make local look like the runner
# same headless mode, same viewport as CI — suddenly it fails here too
pytest --headed=false \
  --browser chromium tests/ \
  -o addopts="" --tb=short

# better still: run the CI image itself
docker run --rm -it -v $PWD:/work -w /work \
  mcr.microsoft.com/playwright/python:v1.44.0 pytest tests/

Make the pipeline hand you evidence

A trace is a time machine — DOM, network, console and screenshots at every step, recorded on the runner, replayed on your laptop:

▸ pytest-playwright: keep traces for failures
pytest --tracing retain-on-failure --video retain-on-failure tests/
# CI: upload test-results/ as a build artifact.
# Open a trace locally with: playwright show-trace trace.zip

Grounded in the pytest-playwright tracing options and common CI runner behaviour

All lessons in The Failed Test: Debugging Automation Like a Senior

  1. The Four Questions That Sort Any Failure
  2. Reading the Traceback Like a Senior
  3. Shrinking the Search Space
  4. Flaky or Broken: Prove It With a Number
  5. It Only Fails in CI
  6. The Write-Up: Product Bug or Test Bug