Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ title = response.get("title")
- [Why Use OpenAPI Validation?](#why-use-openapi-validation)
- [Setup](#setup)
- [Use Cases](#use-cases-1)
- [Request/Response Tracking](#requestresponse-tracking)
- [Why Use Tracking?](#why-use-tracking)
- [Quick Setup](#quick-setup)
- [pytest-html Integration](#pytest-html-integration)
- [Manual Tracking](#manual-tracking)
- [Error Handling](#error-handling)
- [Migration from v1](#migration-from-v1)

Expand Down Expand Up @@ -920,6 +925,165 @@ def test_validation_error_matches_spec(api):
)
```

## Request/Response Tracking

BerAPI includes built-in request/response tracking for debugging and integration with pytest-html reports. When tests fail, you can see exactly what API calls were made and what responses were received.

### Why Use Tracking?

- **Debug Failed Tests** - See exact request/response details when tests fail
- **pytest-html Integration** - Automatic HTML reports with API call details
- **Sensitive Data Masking** - Hide authorization tokens in reports
- **Multiple Requests** - Track all API calls in a single test

### Quick Setup

The easiest way to enable tracking is with the pytest plugin:

```python
# conftest.py
pytest_plugins = ["berapi.contrib.pytest_plugin"]

from berapi.contrib.pytest_plugin import create_tracking_client
import pytest

@pytest.fixture
def api():
return create_tracking_client(
base_url="https://api.example.com",
mask_headers=["Authorization", "X-Api-Key"], # Hide sensitive headers
)
```

```python
# test_api.py
def test_user_api(api):
# All requests are automatically tracked
response = api.get("/users/1").assert_2xx()

# If this fails, the HTML report will show:
# - Request URL, method, headers, body
# - Response status, headers, body
# - Response time
assert response.get("name") == "Expected Name"
```

Run with pytest-html:
```bash
pytest --html=report.html
```

### pytest-html Integration

The tracking plugin automatically adds request/response details to pytest-html reports:

1. **Passed tests** - No extra information shown
2. **Failed tests** - Click to expand and see:
- Full request URL and method
- Request headers (with sensitive values masked)
- Request body (JSON formatted)
- Response status code (color-coded: green/yellow/red)
- Response headers
- Full response body (JSON formatted)
- Response time

#### Configuration Options

```python
from berapi.contrib.pytest_plugin import create_tracking_client, configure_tracking

# Configure global tracking behavior
configure_tracking(
track_only_failures=True, # Only show tracking on failed tests (default)
max_requests=10, # Max requests to track per test
mask_headers=["Authorization", "X-Api-Key"],
)

@pytest.fixture
def api():
return create_tracking_client(
base_url="https://api.example.com",
headers={"Content-Type": "application/json"},
timeout=30.0,
mask_headers=["Authorization"], # Override global setting
max_requests=20, # Override global setting
)
```

#### Track All Tests (Not Just Failures)

```python
# conftest.py
from berapi.contrib.pytest_plugin import configure_tracking

configure_tracking(track_only_failures=False)
```

### Manual Tracking

You can also use tracking middleware manually without the pytest plugin:

```python
from berapi import BerAPI, Settings
from berapi.middleware import TrackingMiddleware, RequestTracker

# Create a tracker
tracker = RequestTracker(
max_requests=10,
mask_headers=["Authorization"],
)

# Create middleware with tracker
middleware = TrackingMiddleware(tracker)

# Create client with tracking
api = BerAPI(
Settings(base_url="https://api.example.com"),
middlewares=[middleware],
)

# Make requests - they're automatically tracked
api.get("/users/1").assert_2xx()
api.post("/users", json={"name": "John"}).assert_2xx()

# Access tracked data
print(f"Tracked {len(tracker)} requests")

# Generate HTML report
html = tracker.to_html()
print(html)

# Clear tracking
tracker.clear()
```

### Combining with Other Middleware

Tracking middleware works alongside other middleware:

```python
from berapi import BerAPI, Settings
from berapi.middleware import (
LoggingMiddleware,
BearerAuthMiddleware,
TrackingMiddleware,
RequestTracker,
)

tracker = RequestTracker()

api = BerAPI(
Settings(base_url="https://api.example.com"),
middlewares=[
LoggingMiddleware(), # Log to console
BearerAuthMiddleware(token="secret"), # Add auth header
TrackingMiddleware(tracker), # Track for reports
],
)
```

---

## Error Handling

```python
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "berapi"
version = "2.0.0"
version = "2.1.0"
description = "A modern, scalable API testing library for Python with middleware support, structured logging, and fluent assertions"
authors = ["fachrulch <fachrul.fch@gmail.com>"]
license = "MIT"
Expand Down
6 changes: 5 additions & 1 deletion src/berapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
LoggingMiddleware,
BearerAuthMiddleware,
ApiKeyMiddleware,
TrackingMiddleware,
RequestTracker,
)

# Re-export exceptions
Expand All @@ -54,7 +56,7 @@
RetryExhaustedError,
)

__version__ = "2.0.0"
__version__ = "2.1.0"

__all__ = [
# Main client
Expand All @@ -73,6 +75,8 @@
"LoggingMiddleware",
"BearerAuthMiddleware",
"ApiKeyMiddleware",
"TrackingMiddleware",
"RequestTracker",
# Exceptions
"BerAPIError",
"HTTPError",
Expand Down
17 changes: 17 additions & 0 deletions src/berapi/contrib/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Contrib modules for berapi integrations.

This package contains optional integrations with external tools:
- pytest_plugin: pytest-html report integration
"""

from berapi.contrib.pytest_plugin import (
create_tracking_client,
get_tracker,
pytest_configure,
)

__all__ = [
"create_tracking_client",
"get_tracker",
"pytest_configure",
]
Loading