pytest-api-cov 1.0.2__py3-none-any.whl → 1.1.0__py3-none-any.whl
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.
- pytest_api_cov/cli.py +3 -0
- pytest_api_cov/config.py +2 -0
- pytest_api_cov/frameworks.py +26 -5
- pytest_api_cov/models.py +42 -23
- pytest_api_cov/plugin.py +11 -6
- pytest_api_cov/pytest_flags.py +6 -0
- pytest_api_cov/report.py +22 -2
- {pytest_api_cov-1.0.2.dist-info → pytest_api_cov-1.1.0.dist-info}/METADATA +65 -7
- pytest_api_cov-1.1.0.dist-info/RECORD +13 -0
- pytest_api_cov-1.0.2.dist-info/RECORD +0 -13
- {pytest_api_cov-1.0.2.dist-info → pytest_api_cov-1.1.0.dist-info}/WHEEL +0 -0
- {pytest_api_cov-1.0.2.dist-info → pytest_api_cov-1.1.0.dist-info}/entry_points.txt +0 -0
- {pytest_api_cov-1.0.2.dist-info → pytest_api_cov-1.1.0.dist-info}/licenses/LICENSE +0 -0
pytest_api_cov/cli.py
CHANGED
@@ -117,6 +117,9 @@ show_excluded_endpoints = false
|
|
117
117
|
|
118
118
|
# Wrap an existing custom test client fixture with coverage tracking (optional)
|
119
119
|
# client_fixture_name = "my_custom_client"
|
120
|
+
|
121
|
+
# Group HTTP methods by endpoint for legacy behavior (optional)
|
122
|
+
# group_methods_by_endpoint = false
|
120
123
|
"""
|
121
124
|
|
122
125
|
|
pytest_api_cov/config.py
CHANGED
@@ -21,6 +21,7 @@ class ApiCoverageReportConfig(BaseModel):
|
|
21
21
|
force_sugar: bool = Field(False, alias="api-cov-force-sugar")
|
22
22
|
force_sugar_disabled: bool = Field(False, alias="api-cov-force-sugar-disabled")
|
23
23
|
client_fixture_name: str = Field("coverage_client", alias="api-cov-client-fixture-name")
|
24
|
+
group_methods_by_endpoint: bool = Field(False, alias="api-cov-group-methods-by-endpoint")
|
24
25
|
|
25
26
|
|
26
27
|
def read_toml_config() -> Dict[str, Any]:
|
@@ -45,6 +46,7 @@ def read_session_config(session_config: Any) -> Dict[str, Any]:
|
|
45
46
|
"api-cov-force-sugar": "force_sugar",
|
46
47
|
"api-cov-force-sugar-disabled": "force_sugar_disabled",
|
47
48
|
"api-cov-client-fixture-name": "client_fixture_name",
|
49
|
+
"api-cov-group-methods-by-endpoint": "group_methods_by_endpoint",
|
48
50
|
}
|
49
51
|
config = {}
|
50
52
|
for opt, key in cli_options.items():
|
pytest_api_cov/frameworks.py
CHANGED
@@ -21,8 +21,17 @@ class BaseAdapter:
|
|
21
21
|
|
22
22
|
class FlaskAdapter(BaseAdapter):
|
23
23
|
def get_endpoints(self) -> List[str]:
|
24
|
+
"""Return list of 'METHOD /path' strings."""
|
24
25
|
excluded_rules = ("/static/<path:filename>",)
|
25
|
-
|
26
|
+
endpoints = []
|
27
|
+
|
28
|
+
for rule in self.app.url_map.iter_rules():
|
29
|
+
if rule.rule not in excluded_rules:
|
30
|
+
for method in rule.methods:
|
31
|
+
if method not in ("HEAD", "OPTIONS"): # Skip automatic methods
|
32
|
+
endpoints.append(f"{method} {rule.rule}")
|
33
|
+
|
34
|
+
return sorted(endpoints)
|
26
35
|
|
27
36
|
def get_tracked_client(self, recorder: Optional["ApiCallRecorder"], test_name: str) -> Any:
|
28
37
|
from flask.testing import FlaskClient
|
@@ -33,11 +42,13 @@ class FlaskAdapter(BaseAdapter):
|
|
33
42
|
class TrackingFlaskClient(FlaskClient):
|
34
43
|
def open(self, *args: Any, **kwargs: Any) -> Any:
|
35
44
|
path = kwargs.get("path") or (args[0] if args else None)
|
45
|
+
method = kwargs.get("method", "GET").upper()
|
46
|
+
|
36
47
|
if path and hasattr(self.application.url_map, "bind"):
|
37
48
|
try:
|
38
|
-
endpoint_name, _ = self.application.url_map.bind("").match(path, method=
|
49
|
+
endpoint_name, _ = self.application.url_map.bind("").match(path, method=method)
|
39
50
|
endpoint_rule_string = next(self.application.url_map.iter_rules(endpoint_name)).rule
|
40
|
-
recorder.record_call(endpoint_rule_string, test_name) # type: ignore[union-attr]
|
51
|
+
recorder.record_call(endpoint_rule_string, test_name, method) # type: ignore[union-attr]
|
41
52
|
except Exception:
|
42
53
|
pass
|
43
54
|
return super().open(*args, **kwargs)
|
@@ -47,9 +58,17 @@ class FlaskAdapter(BaseAdapter):
|
|
47
58
|
|
48
59
|
class FastAPIAdapter(BaseAdapter):
|
49
60
|
def get_endpoints(self) -> List[str]:
|
61
|
+
"""Return list of 'METHOD /path' strings."""
|
50
62
|
from fastapi.routing import APIRoute
|
51
63
|
|
52
|
-
|
64
|
+
endpoints = []
|
65
|
+
for route in self.app.routes:
|
66
|
+
if isinstance(route, APIRoute):
|
67
|
+
for method in route.methods:
|
68
|
+
if method not in ("HEAD", "OPTIONS"):
|
69
|
+
endpoints.append(f"{method} {route.path}")
|
70
|
+
|
71
|
+
return sorted(endpoints)
|
53
72
|
|
54
73
|
def get_tracked_client(self, recorder: Optional["ApiCallRecorder"], test_name: str) -> Any:
|
55
74
|
from starlette.testclient import TestClient
|
@@ -61,7 +80,9 @@ class FastAPIAdapter(BaseAdapter):
|
|
61
80
|
def send(self, *args: Any, **kwargs: Any) -> Any:
|
62
81
|
request = args[0]
|
63
82
|
if recorder is not None:
|
64
|
-
|
83
|
+
method = request.method.upper()
|
84
|
+
path = request.url.path
|
85
|
+
recorder.record_call(path, test_name, method)
|
65
86
|
return super().send(*args, **kwargs)
|
66
87
|
|
67
88
|
return TrackingFastAPIClient(self.app)
|
pytest_api_cov/models.py
CHANGED
@@ -12,19 +12,27 @@ class ApiCallRecorder(BaseModel):
|
|
12
12
|
|
13
13
|
calls: Dict[str, Set[str]] = Field(default_factory=dict)
|
14
14
|
|
15
|
-
def record_call(self, endpoint: str, test_name: str) -> None:
|
16
|
-
"""Record that a test called an endpoint."""
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
15
|
+
def record_call(self, endpoint: str, test_name: str, method: str = "GET") -> None:
|
16
|
+
"""Record that a test called a specific method on an endpoint."""
|
17
|
+
endpoint_method = self._format_endpoint_key(method, endpoint)
|
18
|
+
if endpoint_method not in self.calls:
|
19
|
+
self.calls[endpoint_method] = set()
|
20
|
+
self.calls[endpoint_method].add(test_name)
|
21
|
+
|
22
|
+
@staticmethod
|
23
|
+
def _format_endpoint_key(method: str, endpoint: str) -> str:
|
24
|
+
"""Format method and endpoint into a consistent key format."""
|
25
|
+
return f"{method.upper()} {endpoint}"
|
26
|
+
|
27
|
+
@staticmethod
|
28
|
+
def _parse_endpoint_key(endpoint_key: str) -> tuple[str, str]:
|
29
|
+
"""Parse an endpoint key back into method and endpoint parts."""
|
30
|
+
if " " in endpoint_key:
|
31
|
+
method, endpoint = endpoint_key.split(" ", 1)
|
32
|
+
return method, endpoint
|
33
|
+
else:
|
34
|
+
# Handle legacy format without method
|
35
|
+
return "GET", endpoint_key
|
28
36
|
|
29
37
|
def merge(self, other: "ApiCallRecorder") -> None:
|
30
38
|
"""Merge another recorder's data into this one."""
|
@@ -70,15 +78,17 @@ class EndpointDiscovery(BaseModel):
|
|
70
78
|
endpoints: List[str] = Field(default_factory=list)
|
71
79
|
discovery_source: str = Field(default="unknown")
|
72
80
|
|
73
|
-
def add_endpoint(self, endpoint: str) -> None:
|
74
|
-
"""Add a discovered endpoint."""
|
75
|
-
|
76
|
-
|
81
|
+
def add_endpoint(self, endpoint: str, method: str = "GET") -> None:
|
82
|
+
"""Add a discovered endpoint method."""
|
83
|
+
endpoint_method = ApiCallRecorder._format_endpoint_key(method, endpoint)
|
84
|
+
if endpoint_method not in self.endpoints:
|
85
|
+
self.endpoints.append(endpoint_method)
|
77
86
|
|
78
87
|
def merge(self, other: "EndpointDiscovery") -> None:
|
79
88
|
"""Merge another discovery's endpoints into this one."""
|
80
89
|
for endpoint in other.endpoints:
|
81
|
-
self.
|
90
|
+
if endpoint not in self.endpoints:
|
91
|
+
self.endpoints.append(endpoint)
|
82
92
|
|
83
93
|
def __len__(self) -> int:
|
84
94
|
"""Return number of discovered endpoints."""
|
@@ -95,15 +105,24 @@ class SessionData(BaseModel):
|
|
95
105
|
recorder: ApiCallRecorder = Field(default_factory=ApiCallRecorder)
|
96
106
|
discovered_endpoints: EndpointDiscovery = Field(default_factory=EndpointDiscovery)
|
97
107
|
|
98
|
-
def record_call(self, endpoint: str, test_name: str) -> None:
|
108
|
+
def record_call(self, endpoint: str, test_name: str, method: str = "GET") -> None:
|
99
109
|
"""Record an API call."""
|
100
|
-
self.recorder.record_call(endpoint, test_name)
|
110
|
+
self.recorder.record_call(endpoint, test_name, method)
|
111
|
+
|
112
|
+
def add_discovered_endpoint(self, endpoint: str, method_or_source: str = "GET", source: str = "unknown") -> None:
|
113
|
+
"""Add a discovered endpoint method."""
|
114
|
+
# Handle both old and new method signatures for backward compatibility
|
115
|
+
if method_or_source in ["flask_adapter", "fastapi_adapter", "worker", "unknown"]:
|
116
|
+
# Old signature: add_discovered_endpoint(endpoint, source)
|
117
|
+
method = "GET"
|
118
|
+
source = method_or_source
|
119
|
+
else:
|
120
|
+
# New signature: add_discovered_endpoint(endpoint, method, source)
|
121
|
+
method = method_or_source
|
101
122
|
|
102
|
-
def add_discovered_endpoint(self, endpoint: str, source: str = "unknown") -> None:
|
103
|
-
"""Add a discovered endpoint."""
|
104
123
|
if not self.discovered_endpoints.endpoints:
|
105
124
|
self.discovered_endpoints.discovery_source = source
|
106
|
-
self.discovered_endpoints.add_endpoint(endpoint)
|
125
|
+
self.discovered_endpoints.add_endpoint(endpoint, method)
|
107
126
|
|
108
127
|
def merge_worker_data(self, worker_recorder: Dict[str, Any], worker_endpoints: List[str]) -> None:
|
109
128
|
"""Merge data from a worker process."""
|
pytest_api_cov/plugin.py
CHANGED
@@ -189,14 +189,15 @@ def wrap_client_with_coverage(client: Any, recorder: Any, test_name: str) -> Any
|
|
189
189
|
|
190
190
|
def tracked_method(*args: Any, **kwargs: Any) -> Any:
|
191
191
|
response = attr(*args, **kwargs)
|
192
|
-
# Extract path from args[0]
|
192
|
+
# Extract path from args[0] and method from function name
|
193
193
|
if args and recorder is not None:
|
194
194
|
path = args[0]
|
195
195
|
# Clean up the path to match endpoint format
|
196
196
|
if isinstance(path, str):
|
197
197
|
# Remove query parameters
|
198
198
|
path = path.partition("?")[0]
|
199
|
-
|
199
|
+
method = name.upper() # get -> GET, post -> POST, etc.
|
200
|
+
recorder.record_call(path, test_name, method)
|
200
201
|
return response
|
201
202
|
|
202
203
|
return tracked_method
|
@@ -250,8 +251,10 @@ def coverage_client(request: pytest.FixtureRequest) -> Any:
|
|
250
251
|
if not coverage_data.discovered_endpoints.endpoints:
|
251
252
|
endpoints = adapter.get_endpoints()
|
252
253
|
framework_name = type(app).__name__
|
253
|
-
for
|
254
|
-
|
254
|
+
for endpoint_method in endpoints:
|
255
|
+
# endpoint_method is now in "METHOD /path" format
|
256
|
+
method, path = endpoint_method.split(" ", 1)
|
257
|
+
coverage_data.add_discovered_endpoint(path, method, f"{framework_name.lower()}_adapter")
|
255
258
|
logger.info(f"> pytest-api-coverage: Discovered {len(endpoints)} endpoints.")
|
256
259
|
logger.debug(f"> Discovered endpoints: {endpoints}")
|
257
260
|
except Exception as e:
|
@@ -285,8 +288,10 @@ def coverage_client(request: pytest.FixtureRequest) -> Any:
|
|
285
288
|
try:
|
286
289
|
endpoints = adapter.get_endpoints()
|
287
290
|
framework_name = type(app).__name__
|
288
|
-
for
|
289
|
-
|
291
|
+
for endpoint_method in endpoints:
|
292
|
+
# endpoint_method is now in "METHOD /path" format
|
293
|
+
method, path = endpoint_method.split(" ", 1)
|
294
|
+
coverage_data.add_discovered_endpoint(path, method, f"{framework_name.lower()}_adapter")
|
290
295
|
logger.info(f"> pytest-api-coverage: Discovered {len(endpoints)} endpoints.")
|
291
296
|
logger.debug(f"> Discovered endpoints: {endpoints}")
|
292
297
|
except Exception as e:
|
pytest_api_cov/pytest_flags.py
CHANGED
@@ -74,3 +74,9 @@ def add_pytest_api_cov_flags(parser: pytest.Parser) -> None:
|
|
74
74
|
default=None,
|
75
75
|
help="Name of existing test client fixture to wrap with coverage tracking",
|
76
76
|
)
|
77
|
+
parser.addoption(
|
78
|
+
"--api-cov-group-methods-by-endpoint",
|
79
|
+
action="store_true",
|
80
|
+
default=False,
|
81
|
+
help="Group HTTP methods by endpoint for legacy behavior (default: method-aware coverage)",
|
82
|
+
)
|
pytest_api_cov/report.py
CHANGED
@@ -44,7 +44,19 @@ def categorise_endpoints(
|
|
44
44
|
)
|
45
45
|
|
46
46
|
for endpoint in endpoints:
|
47
|
-
|
47
|
+
# Check exclusion patterns against both full "METHOD /path" and just "/path"
|
48
|
+
is_excluded = False
|
49
|
+
if compiled_patterns:
|
50
|
+
# Extract path from "METHOD /path" format for pattern matching
|
51
|
+
if " " in endpoint:
|
52
|
+
_, path_only = endpoint.split(" ", 1)
|
53
|
+
is_excluded = any(p.match(endpoint) for p in compiled_patterns) or any(
|
54
|
+
p.match(path_only) for p in compiled_patterns
|
55
|
+
)
|
56
|
+
else:
|
57
|
+
is_excluded = any(p.match(endpoint) for p in compiled_patterns)
|
58
|
+
|
59
|
+
if is_excluded:
|
48
60
|
excluded.append(endpoint)
|
49
61
|
continue
|
50
62
|
elif contains_escape_characters(endpoint):
|
@@ -67,7 +79,15 @@ def print_endpoints(
|
|
67
79
|
if endpoints:
|
68
80
|
console.print(f"[{style}]{label}[/]:")
|
69
81
|
for endpoint in endpoints:
|
70
|
-
|
82
|
+
# Format endpoint with consistent spacing for HTTP methods
|
83
|
+
if " " in endpoint:
|
84
|
+
method, path = endpoint.split(" ", 1)
|
85
|
+
# Pad method to 6 characters (longest common method is DELETE)
|
86
|
+
formatted_endpoint = f"{method:<6} {path}"
|
87
|
+
else:
|
88
|
+
# Handle legacy format without method
|
89
|
+
formatted_endpoint = endpoint
|
90
|
+
console.print(f" {symbol} [{style}]{formatted_endpoint}[/]")
|
71
91
|
|
72
92
|
|
73
93
|
def compute_coverage(covered_count: int, uncovered_count: int) -> float:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pytest-api-cov
|
3
|
-
Version: 1.0
|
3
|
+
Version: 1.1.0
|
4
4
|
Summary: Pytest Plugin to provide API Coverage statistics for Python Web Frameworks
|
5
5
|
Author-email: Barnaby Gill <barnabasgill@gmail.com>
|
6
6
|
License: Apache-2.0
|
@@ -83,6 +83,10 @@ def read_root():
|
|
83
83
|
def get_user(user_id: int):
|
84
84
|
return {"user_id": user_id}
|
85
85
|
|
86
|
+
@app.post("/users")
|
87
|
+
def create_user(user: dict):
|
88
|
+
return {"message": "User created", "user": user}
|
89
|
+
|
86
90
|
@app.get("/health")
|
87
91
|
def health_check():
|
88
92
|
return {"status": "ok"}
|
@@ -98,6 +102,10 @@ def test_root_endpoint(coverage_client):
|
|
98
102
|
def test_get_user(coverage_client):
|
99
103
|
response = coverage_client.get("/users/123")
|
100
104
|
assert response.status_code == 200
|
105
|
+
|
106
|
+
def test_create_user(coverage_client):
|
107
|
+
response = coverage_client.post("/users", json={"name": "John"})
|
108
|
+
assert response.status_code == 200
|
101
109
|
```
|
102
110
|
|
103
111
|
Running `pytest --api-cov-report` produces:
|
@@ -105,27 +113,69 @@ Running `pytest --api-cov-report` produces:
|
|
105
113
|
```
|
106
114
|
API Coverage Report
|
107
115
|
Uncovered Endpoints:
|
108
|
-
|
116
|
+
❌ GET /health
|
109
117
|
|
110
118
|
Total API Coverage: 66.67%
|
111
119
|
```
|
112
120
|
|
113
|
-
Or running with advanced options
|
121
|
+
Or running with advanced options:
|
122
|
+
```bash
|
123
|
+
pytest --api-cov-report --api-cov-show-covered-endpoints --api-cov-exclusion-patterns="/users*" --api-cov-show-excluded-endpoints --api-cov-report-path=api_coverage.json
|
124
|
+
```
|
114
125
|
|
115
126
|
```
|
116
127
|
API Coverage Report
|
117
128
|
Uncovered Endpoints:
|
118
|
-
|
129
|
+
❌ GET /health
|
119
130
|
Covered Endpoints:
|
120
|
-
|
131
|
+
✅ GET /
|
121
132
|
Excluded Endpoints:
|
122
|
-
|
133
|
+
🚫 GET /users/{user_id}
|
134
|
+
🚫 POST /users
|
123
135
|
|
124
|
-
|
136
|
+
Total API Coverage: 50.0%
|
125
137
|
|
126
138
|
JSON report saved to api_coverage.json
|
127
139
|
```
|
128
140
|
|
141
|
+
## HTTP Method-Aware Coverage
|
142
|
+
|
143
|
+
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.
|
144
|
+
|
145
|
+
### Method-Aware (Default Behavior)
|
146
|
+
```
|
147
|
+
Covered Endpoints:
|
148
|
+
✅ GET /users/{id}
|
149
|
+
✅ POST /users
|
150
|
+
Uncovered Endpoints:
|
151
|
+
❌ PUT /users/{id}
|
152
|
+
❌ DELETE /users/{id}
|
153
|
+
|
154
|
+
Total API Coverage: 50.0% # 2 out of 4 method-endpoint combinations
|
155
|
+
```
|
156
|
+
|
157
|
+
### Endpoint Grouping
|
158
|
+
To group all methods on an endpoint are together, use:
|
159
|
+
|
160
|
+
```bash
|
161
|
+
pytest --api-cov-report --api-cov-group-methods-by-endpoint
|
162
|
+
```
|
163
|
+
|
164
|
+
Or in `pyproject.toml`:
|
165
|
+
```toml
|
166
|
+
[tool.pytest_api_cov]
|
167
|
+
group_methods_by_endpoint = true
|
168
|
+
```
|
169
|
+
|
170
|
+
This would show:
|
171
|
+
```
|
172
|
+
Covered Endpoints:
|
173
|
+
✅ /users/{id} # Any method tested
|
174
|
+
✅ /users # Any method tested
|
175
|
+
|
176
|
+
Total API Coverage: 100.0% # All endpoints have at least one method tested
|
177
|
+
```
|
178
|
+
|
129
179
|
## Advanced Configuration
|
130
180
|
|
131
181
|
### Setup Wizard
|
@@ -230,6 +280,11 @@ force_sugar_disabled = true
|
|
230
280
|
|
231
281
|
# Wrap an existing custom test client fixture with coverage tracking
|
232
282
|
client_fixture_name = "my_custom_client"
|
283
|
+
|
284
|
+
# Group HTTP methods by endpoint for legacy behavior (default: false)
|
285
|
+
# When true: treats GET /users and POST /users as one "/users" endpoint
|
286
|
+
# When false: treats them as separate "GET /users" and "POST /users" endpoints (recommended)
|
287
|
+
group_methods_by_endpoint = false
|
233
288
|
```
|
234
289
|
|
235
290
|
### Command Line Options
|
@@ -261,6 +316,9 @@ pytest --api-cov-report -v
|
|
261
316
|
|
262
317
|
# Debug logging (very detailed)
|
263
318
|
pytest --api-cov-report -vv
|
319
|
+
|
320
|
+
# Group HTTP methods by endpoint (legacy behavior)
|
321
|
+
pytest --api-cov-report --api-cov-group-methods-by-endpoint
|
264
322
|
```
|
265
323
|
|
266
324
|
## Framework Support
|
@@ -0,0 +1,13 @@
|
|
1
|
+
pytest_api_cov/__init__.py,sha256=7ZX-XIlYwdB0AkSSaXG2O6mah3CBCjZGTiBSEf5dTqk,177
|
2
|
+
pytest_api_cov/cli.py,sha256=1iDYhWZJ_wDU9nPov7FfNrpT5sIU7PmAGiuVqy4zFM4,7290
|
3
|
+
pytest_api_cov/config.py,sha256=m9UsbKKcL5_Wb-lRMCpV-_mMpdYFDo0oV6vxxHKAB7k,3493
|
4
|
+
pytest_api_cov/frameworks.py,sha256=0_8ZzVbeZ6U1ZZwuzCn82m-q5NcRlIOTtocV5zeIGd0,3955
|
5
|
+
pytest_api_cov/models.py,sha256=AW7X4DzzsY-HtNsQMm5x55x95Q-10B2xhD9_XaXFDBw,5997
|
6
|
+
pytest_api_cov/plugin.py,sha256=o2fqQv3M5HzlPYGXm-rDBxbPRHbiMEPpImJ4a5tum0s,16540
|
7
|
+
pytest_api_cov/pytest_flags.py,sha256=oGTCv7T_Mj439PFrvB3LawmLFQYppZOOS1f_HOK1cJE,2408
|
8
|
+
pytest_api_cov/report.py,sha256=hUBEIjK0TXEnamWV61_w6AZKHLh5mD0eXcrmTs61baQ,7600
|
9
|
+
pytest_api_cov-1.1.0.dist-info/METADATA,sha256=uznGlaFxXlXM2FnGtRTtyDqM_nPerAaTMt8ubTQQvxY,12841
|
10
|
+
pytest_api_cov-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
11
|
+
pytest_api_cov-1.1.0.dist-info/entry_points.txt,sha256=hWqEhsBKzbwSwcxCzKgSA8NElQxk0K4PKERrYsi3csk,110
|
12
|
+
pytest_api_cov-1.1.0.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
13
|
+
pytest_api_cov-1.1.0.dist-info/RECORD,,
|
@@ -1,13 +0,0 @@
|
|
1
|
-
pytest_api_cov/__init__.py,sha256=7ZX-XIlYwdB0AkSSaXG2O6mah3CBCjZGTiBSEf5dTqk,177
|
2
|
-
pytest_api_cov/cli.py,sha256=TCnldhRBi9BMLaPrnp7sfoWNc0Ktu8XnoRQKUuXFGWo,7186
|
3
|
-
pytest_api_cov/config.py,sha256=51GaJgAtctAcNb2F-7Q65qZuNusf3_s1-4bE-AWv5QE,3323
|
4
|
-
pytest_api_cov/frameworks.py,sha256=5d6wnEsb2BykPtpnpkv98GMPuyoG4elXRJ7vtGHF06A,3228
|
5
|
-
pytest_api_cov/models.py,sha256=YiXLiEEyNREiodzn1pGqSNIHrm3zV6kFn0XgyN8_8Rs,4893
|
6
|
-
pytest_api_cov/plugin.py,sha256=rZVTvhqKv5GCIbwgFRH3KcrwNXdecFDRrtbMepZfjs8,16118
|
7
|
-
pytest_api_cov/pytest_flags.py,sha256=OX1NMcQHfI9uyPrZXj0Q_VG1daU8uKKB4sY-4JLm220,2175
|
8
|
-
pytest_api_cov/report.py,sha256=VxfWag20V8o9ArbxOkR_gWQ2TE-sthrS0PCJvn4YCSU,6642
|
9
|
-
pytest_api_cov-1.0.2.dist-info/METADATA,sha256=jR8gMyw5frvKQzWeyPrjHmACqa1S6xPZuYXgoshK9Vc,11303
|
10
|
-
pytest_api_cov-1.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
11
|
-
pytest_api_cov-1.0.2.dist-info/entry_points.txt,sha256=hWqEhsBKzbwSwcxCzKgSA8NElQxk0K4PKERrYsi3csk,110
|
12
|
-
pytest_api_cov-1.0.2.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
13
|
-
pytest_api_cov-1.0.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|