You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -5,9 +5,9 @@ A **pytest plugin** that measures **API endpoint coverage** for FastAPI and Flas
5
5
## Features
6
6
7
7
-**Zero Configuration**: Plug-and-play with Flask/FastAPI apps - just install and run
8
+
-**Client-Based Discovery**: Automatically extracts app from your existing test client fixtures
8
9
-**Terminal Reports**: Rich terminal output with detailed coverage information
9
10
-**JSON Reports**: Export coverage data for CI/CD integration
10
-
-**Setup Wizard**: Interactive setup wizard for complex projects
11
11
12
12
## Quick Start
13
13
@@ -28,25 +28,13 @@ pytest --api-cov-report
28
28
29
29
### App Location Flexibility
30
30
31
-
**Zero Config**: Works automatically if your app is in `app.py`, `main.py`, or `server.py`
31
+
Discovery in this plugin is client-based: the plugin extracts the application instance from your test client fixtures, or from an `app` fixture when present. This means the plugin integrates with the test clients or fixtures you already use in your tests rather than relying on background file scanning.
32
32
33
-
**Any Location**: Place your app anywhere in your project - just create a `conftest.py`:
33
+
How discovery works (in order):
34
34
35
-
```python
36
-
import pytest
37
-
from my_project.backend.api import my_app # Any import path!
38
-
39
-
@pytest.fixture
40
-
defapp():
41
-
return my_app
42
-
```
43
-
44
-
The plugin will automatically discover your Flask/FastAPI app if it's in common locations:
45
-
-`app.py` (with variable `app`, `application`, or `main`)
46
-
-`main.py` (with variable `app`, `application`, or `main`)
47
-
-`server.py` (with variable `app`, `application`, or `server`)
48
-
49
-
**Your app can be located anywhere!** If it's not in a standard location, just create a `conftest.py` file to tell the plugin where to find it.
35
+
1. If you configure one or more candidate client fixture names (see configuration below), the plugin will try each in order and wrap the first matching fixture it finds.
36
+
2. If no configured client fixture is found, the plugin will look for a standard `app` fixture and use that to create a tracked client.
37
+
3. If neither a client fixture nor an `app` fixture is available (or the plugin cannot extract an app from the client), coverage tracking will be skipped and a helpful message is shown.
50
38
51
39
### Example
52
40
@@ -97,7 +85,7 @@ API Coverage Report
97
85
Uncovered Endpoints:
98
86
❌ GET /health
99
87
100
-
Total API Coverage: 66.67%
88
+
Total API Coverage: 75.0%
101
89
```
102
90
103
91
Or running with advanced options:
@@ -120,6 +108,16 @@ Total API Coverage: 50.0%
120
108
JSON report saved to api_coverage.json
121
109
```
122
110
111
+
### See examples
112
+
113
+
```bash
114
+
# Print an example pyproject.toml configuration snippet
115
+
pytest-api-cov show-pyproject
116
+
117
+
# Print an example conftest.py for a known app module
118
+
pytest-api-cov show-conftest FastAPI src.main app
119
+
```
120
+
123
121
## HTTP Method-Aware Coverage
124
122
125
123
By default, pytest-api-cov tracks coverage for **each HTTP method separately**. This means `GET /users` and `POST /users` are treated as different endpoints for coverage purposes.
@@ -160,19 +158,6 @@ Total API Coverage: 100.0% # All endpoints have at least one method tested
160
158
161
159
## Advanced Configuration
162
160
163
-
### Setup Wizard
164
-
165
-
If auto-discovery doesn't work for your project, use the interactive setup wizard:
Create a `conftest.py` file to specify your app location (works with **any** file path or structure):
@@ -194,7 +179,15 @@ This approach works with any project structure - the plugin doesn't care where y
194
179
195
180
### Custom Test Client Fixtures
196
181
197
-
You have several options for using custom client fixtures:
182
+
The plugin can wrap existing test client fixtures automatically. Recent changes allow you to specify one or more candidate fixture names (the plugin will try them in order) instead of a single configured name.
183
+
184
+
Default client fixture names the plugin will look for (in order):
185
+
-`client`
186
+
-`test_client`
187
+
-`api_client`
188
+
-`app_client`
189
+
190
+
If you use a different fixture name, you can provide one or more names via the CLI flag `--api-cov-client-fixture-names` (repeatable) or in `pyproject.toml` under `[tool.pytest_api_cov]` as `client_fixture_names` (a list).
If the configured fixture(s) are not found, the plugin will try to use an `app` fixture (if present) to create a tracked client. If neither is available or the plugin cannot extract the app from a discovered client fixture, the tests will still run — coverage will simply be unavailable and a warning will be logged.
Create a `conftest.py` file to specify your app location:
462
-
463
-
```python
464
-
import pytest
465
-
from my_project.api.server import my_flask_app # Any import path
466
-
# or from src.backend.main import fastapi_instance
467
-
# or from anywhere import your_app
468
-
469
-
@pytest.fixture
470
-
def app():
471
-
return my_flask_app # Return your app instance
472
-
```
473
-
474
-
**Option 3 - Override Auto-discovery**
475
-
If you have multiple auto-discoverable files or want to use a different app:
476
-
477
-
```python
478
-
# Even if you have app.py, you can override it
479
-
import pytest
480
-
from main import my_real_app # Use this instead of app.py
481
-
482
-
@pytest.fixture
483
-
def app():
484
-
return my_real_app
485
-
```
486
-
487
-
**Option 4 - Setup Wizard**
488
-
Run the interactive setup: `pytest-api-cov init`
489
-
490
-
The plugin will automatically find your app using the `app` fixture first, then fall back to auto-discovery in common locations. This means you can place your app **anywhere** as long as you create the fixture.
491
-
492
-
### Multiple App Files
493
-
494
-
If you have multiple files that could be auto-discovered (e.g., both `app.py` and `main.py`), the plugin will use the **first valid app it finds** in this priority order:
495
-
496
-
1. `app.py`
497
-
2. `main.py`
498
-
3. `server.py`
499
-
4. `wsgi.py`
500
-
5. `asgi.py`
437
+
If coverage is not running because the plugin could not locate an app, check the following:
501
438
502
-
To use a specific app when multiple exist, create a `conftest.py` with an `app` fixture pointing to your preferred app.
439
+
- Ensure you are running pytest with `--api-cov-report` enabled.
440
+
- Confirm you have a test client fixture (e.g. `client`, `test_client`, `api_client`) or an `app` fixture in your test suite.
441
+
- If you use a custom client fixture, add its name to `client_fixture_names` in `pyproject.toml` or pass it via the CLI using `--api-cov-client-fixture-names` (repeatable) so the plugin can find and wrap it.
442
+
- If the plugin finds the client fixture but cannot extract the underlying app (for example the client type is not supported or wrapped in an unexpected way), you will see a message like "Could not extract app from client" — in that case either provide an `app` fixture directly or wrap your existing client using `create_coverage_fixture`.
503
443
504
-
### No Endpoints Discovered
444
+
### No endpoints Discovered
505
445
506
-
If you see "No endpoints discovered":
446
+
If you still see no endpoints discovered:
507
447
508
-
1. Check that your app is properly instantiated
509
-
2. Verify your routes/endpoints are defined
510
-
3. Ensure the `coverage_client` fixture is working in your tests
511
-
4. Use `-v` or `-vv` for debug information
448
+
1. Check that your app is properly instantiated inside the fixture or client.
449
+
2. Verify your routes/endpoints are defined and reachable by the test client.
450
+
3. Ensure the `coverage_client` fixture is being used in your tests (or that your configured client fixture is listed and discovered).
451
+
4. Use `-v` or `-vv` for debug logging to see why the plugin skipped discovery or wrapping.
512
452
513
453
### Framework Not Detected
514
454
515
455
The plugin supports:
516
-
- **FastAPI**: Detected by `from fastapi import` or `import fastapi`
517
-
- **Flask**: Detected by `from flask import` or `import flask`
456
+
- **FastAPI**: Detected by `FastAPI` class
457
+
- **Flask**: Detected by `Flask` class
458
+
- **FlaskOpenAPI3**: Detected by `FlaskOpenAPI3` class
518
459
519
460
Other frameworks are not currently supported.
520
461
521
462
## License
522
463
523
-
This project is licensed under the Apache License 2.0.
464
+
This project is licensed under the Apache License 2.0.
0 commit comments