How to speed up pytest
Runners
May 20, 2025
How to Run Pytest Faster: A Guide to Turbocharging Your Test Suite
If you’re a Python developer using pytest, you’ve probably stared at your terminal, coffee in hand, willing those tests to finish faster. Slow test suites aren’t just annoying; they can grind your team’s momentum to a halt, delay releases, and make everyone grumpy. Whether you’re a solo coder or part of a sprawling CI/CD pipeline running thousands of tests, this guide will help you speed up pytest, squash flaky tests, and maybe even save some CI budget. Let’s make your tests zoom without sacrificing reliability or coverage.
Why Test Speed Is a Big Deal
Before we jump into the how-to, let’s talk about why pytest speed matters—especially if you’re building developer tools or working in a fast-moving SaaS environment:
Developer sanity: Slow tests kill your flow state. Every second you’re not waiting adds up to more productive coding time.
Faster CI pipelines: Quick tests mean faster feedback, fewer bugs slipping through, and lower cloud compute bills.
Happier teams: Nobody likes twiddling their thumbs while tests chug along. Fast tests keep engineers smiling.
More throughput: Speedy pipelines let you merge more PRs daily, keeping your project moving at lightning speed.
Ready to make your tests fly? Here’s how.
1. Profile Your Tests to Find the Slowpokes
You can’t fix what you don’t measure. Start by figuring out what’s dragging your suite down:
Which tests are the slowest?
Is setup or teardown eating up time?
Are you running tests you don’t need?
Pytest’s --durations flag is your friend:
This spits out the 10 slowest tests, often revealing low-hanging fruit for optimization.
Want to go deeper? Install pytest-profiling for detailed cProfile reports:
If you’re running tests in CI, pipe this data to a test analytics tool to spot trends or regressions over time. Knowledge is power!
2. Parallelize with pytest-xdist for Instant Gains
Want a quick win? Parallelize your tests with pytest-xdist. It’s like giving your test suite a shot of espresso.
Install it:
Then run:
This uses all available CPU cores to run tests concurrently. Want more control? Specify the number of workers:
A few gotchas:
Tests need to be independent. Shared resources (like temp files or databases) can cause flakiness.
You might need to refactor stateful fixtures to avoid conflicts.
3. Save Time on Database Setup (Django Users)
If you’re using Django, your database is probably the biggest bottleneck. Creating a fresh DB for every test run is a time suck.
Use pytest-django’s --reuse-db flag to skip recreating the database:
This can shave minutes off large Django projects. Just make sure your tests don’t depend on a pristine DB unless absolutely necessary.
4. Cut Down on Database Hits
Database calls are sloooow. Every ORM query or TestCase that touches the DB adds up.
Try these:
Use @pytest.mark.django_db only for tests that truly need the database.
For pure logic tests, stick to unittest.TestCase or plain pytest functions.
Mock slow I/O with unittest.mock or pytest-mock.
Shifting even 20% of your tests away from the DB can make a noticeable difference.
5. Break Up Long Tests and Optimize Fixtures
Got a test that feels like it’s running a marathon? Split it into smaller, focused tests. They’re faster and easier to debug.
Also, take a hard look at your fixtures. For expensive setup/teardown, use broader fixture scopes:
But don’t go overboard—too broad a scope can lead to flaky tests or weird side effects.
6. Cache Results to Skip Redundant Work
Pytest’s built-in caching can save you from rerunning tests unnecessarily:
Or:
In CI, cache .pytest_cache between runs, but be careful to avoid stale results.
7. Run Only What You Need
Why run your entire test suite when you’re just tweaking one feature? Scope your tests with --maxfail or -k:
For CI, tools like pytest-testmon (which tracks test dependencies) or tox with matrix builds can run only the relevant subset. You can even build custom test selection based on git diffs.
8. Skip Slow Tests for Quick Feedback
Some tests are just slow by design—think big data imports or complex integrations. Mark them:
Then skip them for daily runs:
Save these for nightly or weekly builds to balance speed and coverage.
9. Slim Down Imports
Heavy imports can quietly slow your tests. That massive pandas or TensorFlow import might be overkill.
Tips:
Move heavy imports inside test functions.
Avoid circular or duplicate imports.
Use tools like import-tracker or pyinstrument to profile import times.
10. Track Performance with Test Analytics
Speed isn’t just about running tests—it’s about keeping them fast over time. Use analytics platforms like BuildPulse, TestRail, Allure, or CircleCI Test Insights to monitor:
Test runtime trends
Flaky tests
Failure patterns
Set alerts for when test durations creep up. It’s like a fitness tracker for your test suite.
11. Optimize CI with Containers
Your local tests might be snappy, but CI can still feel like molasses. Fix it:
Use prebuilt Docker images with Python, dependencies, and DBs ready to go.
Use RAM disks for ephemeral DBs to speed up I/O.
Run CI jobs on beefier machines.
Shard tests with GitHub Actions, CircleCI, or Buildkite matrix builds.
Here’s a sample Docker base:
Combine this with caching for .tox, .venv, or .pytest_cache.
12. Squash Flaky Tests
Flaky tests are the worst—they waste time and make you question your automation. Root them out:
Ditch sleep statements.
Mock network calls and I/O.
Use @pytest.mark.flaky sparingly as a last resort.
Tools like BuildPulse or the flaky pytest plugin can help detect and manage flakiness.
13. Bonus: Combine Assertions with pytest-check
Pytest stops at the first failed assertion, which can mean multiple runs to debug. Use pytest-check to run all assertions and report every failure:
This saves time during debugging and cuts down on reruns.
Wrapping up
Speeding up pytest isn’t just about cutting seconds—it’s about supercharging your entire development cycle. For high-growth SaaS teams or anyone building developer tools, fast tests mean:
More features shipped
Quicker bug fixes
Happier developers
Leaner infrastructure costs
All of these changes can speed up your tests, but at a certain point, your hardware and execution environment play a role as well. BuildPulse Runners can help by running your GitHub Actions jobs 2x faster, at half cost.