@@ -140,95 +140,27 @@ Examples
140140 """ 10% of requests"""
141141 assert api.delete(" /data/old" ).status_code == 204
142142
143- **Conditional stop with shared state across workers : **
143+ **Conditional stop: **
144144
145145.. code-block :: python
146146
147- import pytest
148147 from pytest_load_testing import weight, stop_load_testing
149148
150- @pytest.fixture (scope = " session" )
151- def error_tracker (shared_json_fixture_factory ):
152- """ Track errors across all workers."""
153- return shared_json_fixture_factory(
154- name = " errors" ,
155- on_first_worker = {' count' : 0 }
156- )
157-
158149 @weight (1 )
159- def test_health_check (request , error_tracker ):
150+ def test_health_check (request ):
160151 response = api.get(" /health" )
161152 if response.json()[" status" ] == " critical" :
162153 stop_load_testing(request, " System health critical" )
163154 assert response.status_code == 200
164155
165- @weight (10 )
166- def test_normal_operation (error_tracker ):
167- try :
168- assert api.get(" /api/data" ).status_code == 200
169- except AssertionError :
170- with error_tracker.locked_dict() as data:
171- data[' count' ] += 1
172-
173- See the full documentation for more details on concurrent fixtures and shared state.
174-
175-
176- Rate Limiting
177- ~~~~~~~~~~~~~
178-
179- The plugin provides a ``rate_limiter_fixture_factory `` for enforcing rate limits across workers:
180-
181- .. code-block :: python
182-
183- import pytest
184- from pytest_load_testing import weight, stop_load_testing
185- from pytest_load_testing.token_bucket_rate_limiter import RateLimit
186-
187- @pytest.fixture (scope = " session" )
188- def api_limiter (rate_limiter_fixture_factory , request ):
189- """ Rate limiter that stops tests if rate drift exceeds 20%."""
190-
191- def on_drift (limiter_id , current_rate , target_rate , drift ):
192- message = (
193- f " Rate drift for { limiter_id} : "
194- f " current= { current_rate:.2f } /hr, target= { target_rate} /hr, "
195- f " drift= { drift:.2% } "
196- )
197- stop_load_testing(request, message)
198-
199- return rate_limiter_fixture_factory(
200- name = " api_limiter" ,
201- hourly_rate = RateLimit.per_second(10 ), # 10 calls/second
202- max_drift = 0.2 , # 20% tolerance
203- on_drift_callback = on_drift
204- )
205-
206- @weight (1 )
207- def test_api_call (api_limiter ):
208- with api_limiter.rate_limited_context() as ctx:
209- # Context entry waits if rate limit would be exceeded
210- response = api.get(" /data" )
211- assert response.status_code == 200
212- assert ctx.call_count >= 1
213-
214- **Key Features: **
215-
216- * **Token Bucket Algorithm **: Allows controlled bursts while maintaining average rate
217- * **Shared State **: Rate limiting coordinated across all workers
218- * **Drift Detection **: Monitors actual vs. target rate and triggers callbacks
219- * **Max Calls **: Optional limit on total calls with callback
220- * **Dynamic Rates **: Support for callable rate functions
221156
222- **Rate Limit Helpers: **
223-
224- .. code-block :: python
157+ Rate Limiting and Shared State
158+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
225159
226- RateLimit.per_second(10 ) # 10 calls per second
227- RateLimit.per_minute(600 ) # 600 calls per minute
228- RateLimit.per_hour(3600 ) # 3600 calls per hour
229- RateLimit.per_day(86400 ) # 86400 calls per day
160+ For rate limiting and shared state management across pytest-xdist workers,
161+ see the companion package `pytest-xdist-rate-limit `_.
230162
231- See the full documentation for more examples and advanced usage.
163+ .. _ `pytest-xdist-rate-limit` : https://github.com/xverges/pytest-xdist-rate-limit
232164
233165
234166License
0 commit comments