pytest-async-benchmark 0.1.1__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/.gitignore +1 -0
  2. pytest_async_benchmark-0.2.0/CHANGELOG.md +67 -0
  3. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/PKG-INFO +307 -18
  4. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/README.md +304 -17
  5. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/RELEASE_GUIDE.md +1 -1
  6. pytest_async_benchmark-0.2.0/examples/backwards_compatibility_examples.py +174 -0
  7. pytest_async_benchmark-0.2.0/examples/marker_syntax_examples.py +124 -0
  8. pytest_async_benchmark-0.2.0/examples/pytest_asyncio_showcase.py +163 -0
  9. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/examples/pytest_examples.py +33 -20
  10. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/examples/quart_api_comparison.py +1 -1
  11. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/pyproject.toml +6 -6
  12. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/scripts/release-check.py +12 -0
  13. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/__init__.py +1 -1
  14. pytest_async_benchmark-0.2.0/src/pytest_async_benchmark/plugin.py +185 -0
  15. pytest_async_benchmark-0.2.0/test_marker_functionality.py +53 -0
  16. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/tests/test_async_bench.py +12 -8
  17. pytest_async_benchmark-0.2.0/tests/test_async_compatibility.py +80 -0
  18. pytest_async_benchmark-0.2.0/tests/test_backwards_compatibility.py +84 -0
  19. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/tests/test_demo.py +12 -8
  20. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/uv.lock +8 -3
  21. pytest_async_benchmark-0.1.1/src/pytest_async_benchmark/plugin.py +0 -91
  22. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/.github/workflows/ci.yml +0 -0
  23. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/.github/workflows/release.yml +0 -0
  24. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/.github/workflows/test-publish.yml +0 -0
  25. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/.pre-commit-config.yaml +0 -0
  26. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/LICENSE +0 -0
  27. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/PYPI_SETUP.md +0 -0
  28. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/examples/comparison_examples.py +0 -0
  29. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/screenshot.png +0 -0
  30. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/scripts/quality-check.py +0 -0
  31. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/analytics.py +0 -0
  32. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/comparison.py +0 -0
  33. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/display.py +0 -0
  34. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/runner.py +0 -0
  35. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/stats.py +0 -0
  36. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/src/pytest_async_benchmark/utils.py +0 -0
  37. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/tests/conftest.py +0 -0
  38. {pytest_async_benchmark-0.1.1 → pytest_async_benchmark-0.2.0}/tests/test_comparison.py +0 -0
@@ -172,3 +172,4 @@ cython_debug/
172
172
 
173
173
  # PyPI configuration file
174
174
  .pypirc
175
+ .github/instructions/copilot_instructions.instructions.md
@@ -0,0 +1,67 @@
1
+ # Changelog
2
+
3
+ All notable changes to pytest-async-benchmark will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.0] - 2025-05-28
9
+
10
+ ### 🚀 Major Features
11
+ - **Backwards Compatibility**: Automatic interface detection supporting both sync and async usage patterns
12
+ - **pytest-asyncio Integration**: Full compatibility with pytest-asyncio plugin when available
13
+ - **Dual Interface Support**: Works with `await async_benchmark(...)` (with pytest-asyncio) or `result = async_benchmark(...)` (without)
14
+ - **Smart Detection**: Automatically detects pytest-asyncio availability and provides appropriate interface
15
+
16
+ ### ✨ Added
17
+ - Automatic pytest-asyncio detection and interface switching
18
+ - Legacy sync interface support for backwards compatibility with v0.1.x
19
+ - Optional dependency configuration for pytest-asyncio
20
+ - Comprehensive backwards compatibility test suite
21
+ - `_SyncResultWrapper` class for seamless sync interface
22
+ - Enhanced documentation covering both usage patterns
23
+
24
+ ### 🔧 Changed
25
+ - **NON-BREAKING**: pytest-asyncio moved from required to optional dependency
26
+ - `AsyncBenchmarkFixture.__call__` now returns different types based on environment
27
+ - Enhanced fixture to support both sync and async interfaces automatically
28
+ - Updated examples to show both usage patterns
29
+ - README updated with backwards compatibility documentation
30
+
31
+ ### 🛠️ Fixed
32
+ - RuntimeError issues when pytest-asyncio not available
33
+ - Event loop management conflicts in different environments
34
+ - Compatibility issues with projects not using pytest-asyncio
35
+
36
+ ### 📚 Documentation
37
+ - Added pytest-asyncio compatibility section to README
38
+ - Updated all code examples to demonstrate async/await usage
39
+ - Created dedicated pytest-asyncio showcase example
40
+ - Enhanced Quick Start guide with modern async patterns
41
+
42
+ ### 🧪 Testing
43
+ - All 40 tests passing with pytest-asyncio integration
44
+ - Examples thoroughly tested and validated
45
+ - Comprehensive test coverage maintained
46
+
47
+ ---
48
+
49
+ ## [0.1.1] - 2025-05-27
50
+
51
+ ### Initial Features
52
+ - Core async benchmarking functionality
53
+ - Rich console output with beautiful formatting
54
+ - Statistical analysis and comparison tools
55
+ - Multiple examples and comprehensive testing
56
+
57
+ ### Core Components
58
+ - `AsyncBenchmarkFixture` for pytest integration
59
+ - `AsyncBenchmarkRunner` for timing execution
60
+ - `BenchmarkComparator` for performance analysis
61
+ - Rich-based display formatting
62
+
63
+ ### Examples
64
+ - Basic pytest examples
65
+ - Quart API comparison
66
+ - Comparison analysis tools
67
+ - Statistical benchmarking patterns
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-async-benchmark
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: pytest-async-benchmark: Modern pytest benchmarking for async code. 🚀
5
5
  Author-email: Mihai Farcas <contact@mihai.ltd>
6
6
  License: MIT License
@@ -28,6 +28,8 @@ License-File: LICENSE
28
28
  Requires-Python: >=3.9
29
29
  Requires-Dist: pytest>=8.3.5
30
30
  Requires-Dist: rich>=14.0.0
31
+ Provides-Extra: asyncio
32
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'asyncio'
31
33
  Description-Content-Type: text/markdown
32
34
 
33
35
  # pytest-async-benchmark 🚀
@@ -37,8 +39,8 @@ Modern pytest benchmarking for async code with beautiful terminal output and adv
37
39
  ## ✨ Features
38
40
 
39
41
  - 🎯 **Async-First**: Designed specifically for benchmarking `async def` functions
40
- - 🔌 **Pytest Integration**: Seamless integration as a pytest plugin
41
- - 🎨 **Rich Output**: Beautiful terminal reporting!
42
+ - 🔌 **Pytest Integration**: Seamless integration as a pytest plugin with full **pytest-asyncio** support
43
+ - 🎨 **Rich Output**: Beautiful terminal reporting powered by Rich!
42
44
  - 📊 **Comprehensive Stats**: Min, max, mean, median, std dev, percentiles, and more
43
45
  - ⚖️ **A vs B Comparisons**: Compare different implementations side-by-side
44
46
  - 📈 **Multi-Scenario Analysis**: Benchmark multiple scenarios with detailed comparison tables
@@ -46,18 +48,59 @@ Modern pytest benchmarking for async code with beautiful terminal output and adv
46
48
  - ⚡ **Auto Calibration**: Intelligent round and iteration detection
47
49
  - 🔄 **Quick Compare**: One-line comparison utilities
48
50
  - 🏆 **Winner Detection**: Automatic identification of best-performing implementation
49
- - 🚀 **Easy to Use**: Simple fixture-based API
51
+ - 🚀 **Easy to Use**: Simple fixture-based API with native `async`/`await` support
52
+ - 🔧 **pytest-asyncio Compatible**: Works perfectly with pytest-asyncio's event loop management
50
53
 
51
54
  ## 📦 Installation
52
55
 
56
+ ### For Existing pytest-asyncio Users 🚀
57
+ **Already testing async APIs (FastAPI, Quart, aiohttp)?** You're all set with the basic installation:
58
+
53
59
  ```bash
54
- uv add pytest-async-benchmark
60
+ pip install pytest-async-benchmark
55
61
  # or
62
+ uv add pytest-async-benchmark
63
+ ```
64
+
65
+ You'll get the full async/await experience immediately since you already have pytest-asyncio!
66
+
67
+ ### For New Users
68
+ Choose your installation based on your needs:
69
+
70
+ ```bash
71
+ # Full installation with async/await support (recommended)
72
+ pip install pytest-async-benchmark[asyncio]
73
+ uv add pytest-async-benchmark --optional asyncio
74
+
75
+ # Basic installation (simple interface)
56
76
  pip install pytest-async-benchmark
77
+ uv add pytest-async-benchmark
78
+ ```
79
+
80
+ ### Quick Check ✅
81
+ Already using `@pytest.mark.asyncio` in your tests? Then the basic installation is all you need:
82
+
83
+ ```python
84
+ # If you already have tests like this:
85
+ @pytest.mark.asyncio
86
+ async def test_my_api():
87
+ # Your existing async test code
88
+ pass
89
+
90
+ # Then just add pytest-async-benchmark and use:
91
+ @pytest.mark.asyncio
92
+ async def test_my_api_performance(async_benchmark):
93
+ result = await async_benchmark(my_async_function)
94
+ assert result['mean'] < 0.01
57
95
  ```
58
96
 
59
97
  ## 🚀 Quick Start
60
98
 
99
+ pytest-async-benchmark automatically adapts to your environment, providing **two convenient interfaces**:
100
+
101
+ ### Async Interface (with pytest-asyncio)
102
+ When pytest-asyncio is installed, use the natural async/await syntax:
103
+
61
104
  ```python
62
105
  import asyncio
63
106
  import pytest
@@ -66,26 +109,190 @@ async def slow_async_operation():
66
109
  await asyncio.sleep(0.01) # 10ms
67
110
  return "result"
68
111
 
69
- def test_async_performance(async_benchmark):
70
- result = async_benchmark(slow_async_operation, rounds=5)
112
+ @pytest.mark.asyncio
113
+ @pytest.mark.async_benchmark(rounds=5, iterations=10)
114
+ async def test_async_performance(async_benchmark):
115
+ # Use await with pytest-asyncio for best experience
116
+ result = await async_benchmark(slow_async_operation)
117
+
118
+ # Your assertions here
119
+ assert result['mean'] < 0.02
120
+ ```
121
+
122
+ ### Simple Interface (without pytest-asyncio)
123
+ For simpler setups, the sync interface works automatically:
124
+
125
+ ```python
126
+ import asyncio
127
+ import pytest
128
+
129
+ async def slow_async_operation():
130
+ await asyncio.sleep(0.01)
131
+ return "result"
132
+
133
+ @pytest.mark.async_benchmark(rounds=5, iterations=10)
134
+ def test_sync_performance(async_benchmark):
135
+ # No await needed - sync interface
136
+ result = async_benchmark(slow_async_operation)
71
137
 
72
138
  # Your assertions here
73
139
  assert result['mean'] < 0.02 # Should complete in under 20ms
74
140
  ```
75
141
 
142
+ ### Flexible Configuration Syntax
143
+
144
+ pytest-async-benchmark supports **two syntax options** for configuring benchmarks:
145
+
146
+ #### Option 1: Marker Syntax (Recommended)
147
+ ```python
148
+ @pytest.mark.async_benchmark(rounds=5, iterations=10)
149
+ async def test_with_marker(async_benchmark):
150
+ result = await async_benchmark(slow_async_operation)
151
+ assert result['rounds'] == 5 # From marker
152
+ ```
153
+
154
+ #### Option 2: Function Parameter Syntax
155
+ ```python
156
+ async def test_with_parameters(async_benchmark):
157
+ result = await async_benchmark(slow_async_operation, rounds=5, iterations=10)
158
+ assert result['rounds'] == 5 # From function parameters
159
+ ```
160
+
161
+ ## 🔧 Interface Detection & Flexibility
162
+
163
+ pytest-async-benchmark **automatically detects** your environment and provides the best interface:
164
+
165
+ ### With pytest-asyncio (Recommended)
166
+ When pytest-asyncio is installed, use natural async/await syntax:
167
+
168
+ ```python
169
+ # Set in your pyproject.toml for automatic async test detection
170
+ [tool.pytest.ini_options]
171
+ asyncio_mode = "auto"
172
+
173
+ # Then use await syntax
174
+ @pytest.mark.asyncio
175
+ async def test_my_benchmark(async_benchmark):
176
+ result = await async_benchmark(my_async_function)
177
+ # Your assertions here
178
+ ```
179
+
180
+ **Benefits of pytest-asyncio integration:**
181
+ - ✅ Native `async`/`await` syntax support
182
+ - ✅ Automatic event loop management
183
+ - ✅ No `RuntimeError: cannot be called from a running event loop`
184
+ - ✅ Better compatibility with async frameworks like FastAPI, Quart, aiohttp
185
+ - ✅ Cleaner test code with standard async patterns
186
+
187
+ ### Without pytest-asyncio (Simple Setup)
188
+ When pytest-asyncio is not available, the simple interface works automatically:
189
+
190
+ ```python
191
+ # No pytest-asyncio required
192
+ def test_my_benchmark(async_benchmark):
193
+ result = async_benchmark(my_async_function) # No await needed
194
+ # Your assertions here
195
+ ```
196
+
197
+ **Benefits of simple interface:**
198
+ - ✅ No additional dependencies required
199
+ - ✅ Simpler setup for basic use cases
200
+ - ✅ Perfect for getting started quickly
201
+ - ✅ Automatic event loop management internally
202
+
76
203
  ## 🎯 Core Usage Examples
77
204
 
205
+ ### Interface Flexibility
206
+
207
+ #### Async Interface (with pytest-asyncio)
208
+ ```python
209
+ @pytest.mark.asyncio
210
+ @pytest.mark.async_benchmark(rounds=10, iterations=100, warmup_rounds=2)
211
+ async def test_with_marker(async_benchmark):
212
+ """Use marker for consistent, visible configuration."""
213
+ result = await async_benchmark(my_async_function)
214
+ assert result['rounds'] == 10 # Configuration is explicit and visible
215
+ ```
216
+
217
+ #### Simple Interface (without pytest-asyncio)
218
+ ```python
219
+ @pytest.mark.async_benchmark(rounds=10, iterations=100, warmup_rounds=2)
220
+ def test_with_marker_sync(async_benchmark):
221
+ """Use marker for consistent, visible configuration - simple style."""
222
+ result = async_benchmark(my_async_function) # No await needed
223
+ assert result['rounds'] == 10 # Configuration is explicit and visible
224
+ ```
225
+
226
+ ### Two Configuration Syntaxes
227
+
228
+ #### Marker Syntax (Declarative)
229
+ ```python
230
+ # With pytest-asyncio
231
+ @pytest.mark.asyncio
232
+ @pytest.mark.async_benchmark(rounds=10, iterations=100, warmup_rounds=2)
233
+ async def test_with_marker_async(async_benchmark):
234
+ result = await async_benchmark(my_async_function)
235
+ assert result['rounds'] == 10
236
+
237
+ # Without pytest-asyncio
238
+ @pytest.mark.async_benchmark(rounds=10, iterations=100, warmup_rounds=2)
239
+ def test_with_marker_sync(async_benchmark):
240
+ result = async_benchmark(my_async_function)
241
+ assert result['rounds'] == 10
242
+ ```
243
+
244
+ #### Function Parameter Syntax (Dynamic)
245
+ ```python
246
+ # With pytest-asyncio
247
+ @pytest.mark.asyncio
248
+ async def test_with_parameters_async(async_benchmark):
249
+ result = await async_benchmark(
250
+ my_async_function,
251
+ rounds=10,
252
+ iterations=100,
253
+ warmup_rounds=2
254
+ )
255
+ assert result['rounds'] == 10
256
+
257
+ # Without pytest-asyncio
258
+ def test_with_parameters_simple(async_benchmark):
259
+ result = async_benchmark(
260
+ my_async_function,
261
+ rounds=10,
262
+ iterations=100,
263
+ warmup_rounds=2
264
+ )
265
+ assert result['rounds'] == 10
266
+ ```
267
+
268
+ #### Combined Syntax (Override)
269
+ Both interfaces support parameter precedence where function parameters override marker settings:
270
+
271
+ ```python
272
+ @pytest.mark.async_benchmark(rounds=5, iterations=50) # Default config
273
+ async def test_with_override(async_benchmark): # Works with or without @pytest.mark.asyncio
274
+ """Function parameters override marker settings."""
275
+ result = await async_benchmark( # Use 'await' only with pytest-asyncio
276
+ my_async_function,
277
+ rounds=20 # This overrides marker's rounds=5
278
+ # iterations=50 comes from marker
279
+ )
280
+ assert result['rounds'] == 20 # Function parameter wins
281
+ assert result['iterations'] == 50 # From marker
282
+ ```
283
+
78
284
  ### Basic Benchmarking
79
285
 
80
286
  ```python
81
- def test_my_async_function(async_benchmark):
287
+ @pytest.mark.asyncio
288
+ async def test_my_async_function(async_benchmark):
82
289
  async def my_function():
83
290
  # Your async code here
84
291
  await some_async_operation()
85
292
  return result
86
293
 
87
294
  # Benchmark with default settings (5 rounds, 1 iteration each)
88
- stats = async_benchmark(my_function)
295
+ stats = await async_benchmark(my_function)
89
296
 
90
297
  # Access comprehensive timing statistics
91
298
  print(f"Mean execution time: {stats['mean']:.3f}s")
@@ -95,9 +302,86 @@ def test_my_async_function(async_benchmark):
95
302
 
96
303
  ### Advanced Configuration
97
304
 
305
+ ## 🎯 Two Configuration Syntaxes
306
+
307
+ pytest-async-benchmark offers **two flexible ways** to configure your benchmarks:
308
+
309
+ ### 🏷️ Marker Syntax (Recommended)
310
+
311
+ Use pytest markers for **declarative, visible configuration**:
312
+
98
313
  ```python
99
- def test_with_custom_settings(async_benchmark):
100
- result = async_benchmark(
314
+ @pytest.mark.asyncio
315
+ @pytest.mark.async_benchmark(rounds=10, iterations=100, warmup_rounds=2)
316
+ async def test_high_precision_benchmark(async_benchmark):
317
+ """High precision benchmark with marker configuration."""
318
+ result = await async_benchmark(my_async_function)
319
+
320
+ # Configuration is visible and consistent
321
+ assert result['rounds'] == 10
322
+ assert result['iterations'] == 100
323
+ ```
324
+
325
+ **Benefits:**
326
+ - ✅ **Visible configuration** - Parameters are clear at test level
327
+ - ✅ **IDE support** - Better tooling and autocomplete
328
+ - ✅ **Test discovery** - Easy to find all benchmark tests
329
+ - ✅ **Consistent configs** - Same settings across related tests
330
+
331
+ ### ⚙️ Function Parameter Syntax
332
+
333
+ Use function parameters for **dynamic, flexible configuration**:
334
+
335
+ ```python
336
+ @pytest.mark.asyncio
337
+ async def test_dynamic_benchmark(async_benchmark):
338
+ """Dynamic benchmark with runtime configuration."""
339
+ # Configuration can be computed or conditional
340
+ rounds = 20 if is_production else 5
341
+
342
+ result = await async_benchmark(
343
+ my_async_function,
344
+ rounds=rounds,
345
+ iterations=50,
346
+ warmup_rounds=1
347
+ )
348
+ ```
349
+
350
+ **Benefits:**
351
+ - ✅ **Dynamic configuration** - Runtime parameter calculation
352
+ - ✅ **Conditional logic** - Different configs based on environment
353
+ - ✅ **Per-call customization** - Each benchmark call can differ
354
+
355
+ ### 🔄 Combined Syntax (Best of Both)
356
+
357
+ **Function parameters override marker parameters**:
358
+
359
+ ```python
360
+ @pytest.mark.asyncio
361
+ @pytest.mark.async_benchmark(rounds=5, iterations=50, warmup_rounds=1)
362
+ async def test_with_overrides(async_benchmark):
363
+ """Use marker defaults with selective overrides."""
364
+
365
+ # Quick test with marker defaults
366
+ quick_result = await async_benchmark(fast_function)
367
+
368
+ # Precision test with overridden rounds
369
+ precise_result = await async_benchmark(
370
+ slow_function,
371
+ rounds=20 # Overrides marker's rounds=5
372
+ # iterations=50 and warmup_rounds=1 come from marker
373
+ )
374
+
375
+ assert quick_result['rounds'] == 5 # From marker
376
+ assert precise_result['rounds'] == 20 # From function override
377
+ ```
378
+
379
+ ### Traditional Configuration
380
+
381
+ ```python
382
+ @pytest.mark.asyncio
383
+ async def test_with_custom_settings(async_benchmark):
384
+ result = await async_benchmark(
101
385
  my_async_function,
102
386
  rounds=10, # Number of rounds to run
103
387
  iterations=5, # Iterations per round
@@ -108,13 +392,14 @@ def test_with_custom_settings(async_benchmark):
108
392
  ### With Function Arguments
109
393
 
110
394
  ```python
111
- def test_with_args(async_benchmark):
395
+ @pytest.mark.asyncio
396
+ async def test_with_args(async_benchmark):
112
397
  async def process_data(data, multiplier=1):
113
398
  # Process the data
114
399
  await asyncio.sleep(0.01)
115
400
  return len(data) * multiplier
116
401
 
117
- result = async_benchmark(
402
+ result = await async_benchmark(
118
403
  process_data,
119
404
  "test_data", # positional arg
120
405
  multiplier=2, # keyword arg
@@ -317,13 +602,14 @@ async def get_data():
317
602
  await asyncio.sleep(0.005)
318
603
  return {"data": "example"}
319
604
 
320
- def test_fastapi_endpoint_performance(async_benchmark):
605
+ @pytest.mark.asyncio
606
+ async def test_fastapi_endpoint_performance(async_benchmark):
321
607
  async def make_request():
322
608
  with TestClient(app) as client:
323
609
  response = client.get("/api/data")
324
610
  return response.json()
325
611
 
326
- result = async_benchmark(make_request, rounds=10)
612
+ result = await async_benchmark(make_request, rounds=10)
327
613
  assert result['mean'] < 0.1 # Should respond within 100ms
328
614
  assert result['grade'] in ['A', 'B'] # Should have good performance grade
329
615
  ```
@@ -358,6 +644,7 @@ a_vs_b_comparison(
358
644
  ### Database Query Benchmarking
359
645
 
360
646
  ```python
647
+ @pytest.mark.asyncio
361
648
  async def test_database_query_performance(async_benchmark):
362
649
  async def fetch_user_data(user_id):
363
650
  async with database.connection() as conn:
@@ -365,7 +652,7 @@ async def test_database_query_performance(async_benchmark):
365
652
  "SELECT * FROM users WHERE id = ?", user_id
366
653
  )
367
654
 
368
- result = async_benchmark(fetch_user_data, 123, rounds=5)
655
+ result = await async_benchmark(fetch_user_data, 123, rounds=5)
369
656
  assert result['mean'] < 0.05 # Should complete within 50ms
370
657
  assert result['p95'] < 0.1 # 95% of queries under 100ms
371
658
  ```
@@ -374,9 +661,10 @@ async def test_database_query_performance(async_benchmark):
374
661
 
375
662
  ```python
376
663
  @pytest.mark.async_benchmark
377
- def test_performance(async_benchmark):
664
+ @pytest.mark.asyncio
665
+ async def test_performance(async_benchmark):
378
666
  # Your benchmark test
379
- result = async_benchmark(my_async_function)
667
+ result = await async_benchmark(my_async_function)
380
668
  assert result is not None
381
669
  ```
382
670
 
@@ -405,6 +693,7 @@ A dictionary with comprehensive statistics including min, max, mean, median, std
405
693
 
406
694
  - Python ≥ 3.9
407
695
  - pytest ≥ 8.3.5
696
+ - pytest-asyncio ≥ 0.23.0 (automatically installed)
408
697
 
409
698
  Note: Rich (for beautiful terminal output) is automatically installed as a dependency.
410
699