Skip to content

Commit 02bf923

Browse files
authored
perf: speed up make tests with xdist and deterministic waits (#2563)
1 parent 5edf91a commit 02bf923

16 files changed

+670
-620
lines changed

.github/workflows/tests.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,11 @@ jobs:
9292
if: steps.changes.outputs.run == 'true'
9393
run: make sync
9494
- name: Run tests with coverage
95-
if: steps.changes.outputs.run == 'true'
95+
if: steps.changes.outputs.run == 'true' && matrix.python-version == '3.12'
9696
run: make coverage
97+
- name: Run tests
98+
if: steps.changes.outputs.run == 'true' && matrix.python-version != '3.12'
99+
run: make tests
97100
- name: Skip tests
98101
if: steps.changes.outputs.run != 'true'
99102
run: echo "Skipping tests for non-code changes."

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,15 @@ mypy:
2020
uv run mypy . --exclude site
2121

2222
.PHONY: tests
23-
tests:
24-
uv run pytest
23+
tests: tests-parallel tests-serial
24+
25+
.PHONY: tests-parallel
26+
tests-parallel:
27+
uv run pytest -n auto --dist loadfile -m "not serial"
28+
29+
.PHONY: tests-serial
30+
tests-serial:
31+
uv run pytest -m serial
2532

2633
.PHONY: coverage
2734
coverage:

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ dev = [
5050
"pytest",
5151
"pytest-asyncio",
5252
"pytest-mock>=3.14.0",
53+
"pytest-xdist",
5354
"rich>=13.1.0, <14",
5455
"mkdocs>=1.6.0",
5556
"mkdocs-material>=9.6.0",
@@ -145,6 +146,7 @@ filterwarnings = [
145146
]
146147
markers = [
147148
"allow_call_model_methods: mark test as allowing calls to real model implementations",
149+
"serial: mark test as requiring serial execution",
148150
]
149151

150152
[tool.inline-snapshot]

tests/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ Before running any tests, make sure you have `uv` installed (and ideally run `ma
88
make tests
99
```
1010

11+
`make tests` runs the shard-safe suite in parallel and then runs tests marked `serial`
12+
in a separate serial pass.
13+
1114
## Snapshots
1215

1316
We use [inline-snapshots](https://15r10nk.github.io/inline-snapshot/latest/) for some tests. If your code adds new snapshot tests or breaks existing ones, you can fix/create them. After fixing/creating snapshots, run `make tests` again to verify the tests pass.

tests/conftest.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,20 @@
66
from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel
77
from agents.models.openai_responses import OpenAIResponsesModel
88
from agents.run import set_default_agent_runner
9-
from agents.tracing import set_trace_processors
10-
from agents.tracing.setup import get_trace_provider
9+
from agents.tracing.provider import DefaultTraceProvider
10+
from agents.tracing.setup import set_trace_provider
1111

1212
from .testing_processor import SPAN_PROCESSOR_TESTING
1313

1414

1515
# This fixture will run once before any tests are executed
1616
@pytest.fixture(scope="session", autouse=True)
1717
def setup_span_processor():
18-
set_trace_processors([SPAN_PROCESSOR_TESTING])
18+
provider = DefaultTraceProvider()
19+
provider.set_processors([SPAN_PROCESSOR_TESTING])
20+
set_trace_provider(provider)
21+
yield
22+
provider.shutdown()
1923

2024

2125
# Ensure a default OpenAI API key is present for tests that construct clients
@@ -51,13 +55,6 @@ def clear_default_runner():
5155
set_default_agent_runner(None)
5256

5357

54-
# This fixture will run after all tests end
55-
@pytest.fixture(autouse=True, scope="session")
56-
def shutdown_trace_provider():
57-
yield
58-
get_trace_provider().shutdown()
59-
60-
6158
@pytest.fixture(autouse=True)
6259
def disable_real_model_clients(monkeypatch, request):
6360
# If the test is marked to allow the method call, don't override it.

tests/extensions/memory/test_dapr_redis_integration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@
5151
from tests.fake_model import FakeModel
5252
from tests.test_responses import get_text_message
5353

54-
# Mark all tests as async
55-
pytestmark = pytest.mark.asyncio
54+
# Docker-backed integration tests should stay on the serial test path.
55+
pytestmark = [pytest.mark.asyncio, pytest.mark.serial]
5656

5757

5858
def wait_for_dapr_health(host: str, port: int, timeout: int = 60) -> bool:

0 commit comments

Comments
 (0)