pytest-httpchain 0.2.1__tar.gz → 0.3.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.
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/PKG-INFO +75 -80
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/README.md +72 -77
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/pyproject.toml +9 -7
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/carrier.py +34 -33
- pytest_httpchain-0.3.0/src/pytest_httpchain/cli.py +59 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/constants.py +5 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/exceptions.py +2 -1
- pytest_httpchain-0.3.0/src/pytest_httpchain/har_writer.py +243 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/plugin.py +55 -10
- pytest_httpchain-0.3.0/src/pytest_httpchain/skill.md +257 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/utils.py +21 -3
- pytest_httpchain-0.3.0/src/pytest_httpchain/validation.py +272 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/LICENSE +0 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/__init__.py +0 -0
- {pytest_httpchain-0.2.1 → pytest_httpchain-0.3.0}/src/pytest_httpchain/report_formatter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-httpchain
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: pytest plugin for HTTP testing using JSON files
|
|
5
5
|
Keywords: testing,pytest,requests
|
|
6
6
|
Author: Alexander Eresov
|
|
@@ -19,10 +19,10 @@ Requires-Dist: pydantic>=2.11.7
|
|
|
19
19
|
Requires-Dist: pyrate-limiter>=3.0.0
|
|
20
20
|
Requires-Dist: pytest-httpchain-jsonref
|
|
21
21
|
Requires-Dist: pytest-httpchain-models
|
|
22
|
+
Requires-Dist: pytest-httpchain-templates
|
|
22
23
|
Requires-Dist: pytest-order>=1.3.0
|
|
23
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: typer>=0.16.0
|
|
24
25
|
Requires-Python: >=3.13, <4.0
|
|
25
|
-
Provides-Extra: mcp
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
27
27
|
|
|
28
28
|
[](https://pypi.python.org/pypi/pytest-httpchain)
|
|
@@ -38,66 +38,44 @@ A pytest plugin for testing HTTP endpoints.
|
|
|
38
38
|
`pytest-httpchain` is an integration testing framework for HTTP APIs based on [httpx](https://www.python-httpx.org) lib.
|
|
39
39
|
It aims at helping with common HTTP API testing scenarios, where user needs to make several calls in specific order using data obtained along the way, like auth tokens or resource ids.
|
|
40
40
|
|
|
41
|
-
##
|
|
42
|
-
|
|
43
|
-
Install normally via package manager of your choice from PyPi:
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
pip install pytest-httpchain
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
or directly from Github, in case you need a particular ref:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pip install 'git+https://github.com/aeresov/pytest-httpchain@main'
|
|
53
|
-
```
|
|
41
|
+
## Why pytest-httpchain?
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
Testing HTTP APIs with plain pytest often leads to these pain points:
|
|
56
44
|
|
|
57
|
-
The
|
|
45
|
+
- **Boilerplate accumulates** — Every test repeats the same setup: create client, set headers, make request, parse response, assert. The actual test intent gets buried.
|
|
46
|
+
- **Data threading is manual** — When one call returns a token or ID needed by the next, you end up with fragile helper functions passing state around.
|
|
47
|
+
- **Common patterns get copy-pasted** — Auth flows, base URLs, shared headers end up duplicated across test files. Fixtures might help, but they are not designed for that.
|
|
48
|
+
- **Code reviews are noisy** — The actual test logic is rarely clear because of all the boilerplate and helpers, following changes gets overwhelming quickly.
|
|
58
49
|
|
|
59
|
-
-
|
|
50
|
+
`pytest-httpchain` offers a more structured approach.
|
|
60
51
|
|
|
61
52
|
## Features
|
|
62
53
|
|
|
63
|
-
###
|
|
54
|
+
### Declarative JSON format
|
|
64
55
|
|
|
65
|
-
|
|
56
|
+
Test scenarios are JSON documents that describe _what_ to test, not _how_. No setup code to scroll through — the request and assertions are right there.
|
|
66
57
|
|
|
67
|
-
###
|
|
58
|
+
### `$ref` with deep merging
|
|
68
59
|
|
|
69
|
-
|
|
70
|
-
`pytest-httpchain` supports JSONRef, so use can reuse arbitrary parts of your scenarios with `$ref` directive.
|
|
71
|
-
Properties are merged in a greedy way with type checking.
|
|
60
|
+
Reuse arbitrary parts of your scenarios with JSONRef. Properties merge with type checking, so you can compose scenarios from shared fragments (auth flows, common headers, base URLs).
|
|
72
61
|
|
|
73
|
-
### Multi-stage
|
|
62
|
+
### Multi-stage execution
|
|
74
63
|
|
|
75
|
-
Each
|
|
76
|
-
`pytest-httpchain` executes stages in the order they are listed in scenario file; one stage failure stops the execution chain.
|
|
64
|
+
Each scenario contains 1+ stages executed in order. One stage failure stops the chain. Use `always_run` for cleanup stages that should execute regardless.
|
|
77
65
|
|
|
78
|
-
### Common data context
|
|
66
|
+
### Common data context
|
|
79
67
|
|
|
80
|
-
|
|
81
|
-
This storage ("common data context") is populated with declared variables, fixtures and data saved by stages. The data remains there throughout the scenario execution.
|
|
82
|
-
Writing scenarios, you can use Jinja-style expressions like `"{{ var }}"` for JSON values. `pytest-httpchain` does variable substitution dynamically right before executing a stage, and uses common data context keys as variables in these expressions.
|
|
83
|
-
Values from common data context also might be verified during verified/asserted.
|
|
68
|
+
A key-value store persists throughout scenario execution. Variables, fixtures, and saved response data all live here. Use template expressions (`{{ var }}`) anywhere in your requests — substitution happens dynamically before each stage.
|
|
84
69
|
|
|
85
|
-
###
|
|
70
|
+
### Response processing
|
|
86
71
|
|
|
87
|
-
|
|
72
|
+
- **JMESPath** — Extract values from JSON responses directly
|
|
73
|
+
- **JSON Schema** — Validate response structure against a schema
|
|
74
|
+
- **User functions** — Call Python functions for custom extraction, verification, or [authentication](https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication)
|
|
88
75
|
|
|
89
|
-
|
|
90
|
-
- to verify HTTP response and values in common data context
|
|
91
|
-
- to provide [custom authentication for requests](https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication)
|
|
92
|
-
- to call in substitution expressions
|
|
76
|
+
### Full pytest integration
|
|
93
77
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
`pytest-httpchain` can extract values from JSON responses using JMESPath expressions directly.
|
|
97
|
-
|
|
98
|
-
### JSON schema support
|
|
99
|
-
|
|
100
|
-
`pytest-httpchain` can verify JSON reponses against user-defined JSON schema.
|
|
78
|
+
Markers, fixtures, parametrization, and other plugins work as expected. You're not locked into a separate ecosystem.
|
|
101
79
|
|
|
102
80
|
## Quick Start
|
|
103
81
|
|
|
@@ -122,9 +100,8 @@ def now_utc():
|
|
|
122
100
|
}
|
|
123
101
|
}
|
|
124
102
|
],
|
|
125
|
-
"stages":
|
|
126
|
-
{
|
|
127
|
-
"name": "get_user",
|
|
103
|
+
"stages": {
|
|
104
|
+
"get_user": {
|
|
128
105
|
"request": {
|
|
129
106
|
"url": "https://api.example.com/users/{{ user_id }}"
|
|
130
107
|
},
|
|
@@ -143,8 +120,7 @@ def now_utc():
|
|
|
143
120
|
}
|
|
144
121
|
]
|
|
145
122
|
},
|
|
146
|
-
{
|
|
147
|
-
"name": "update_user",
|
|
123
|
+
"update_user": {
|
|
148
124
|
"fixtures": ["now_utc"],
|
|
149
125
|
"request": {
|
|
150
126
|
"url": "https://api.example.com/users/{{ user_id }}",
|
|
@@ -166,15 +142,14 @@ def now_utc():
|
|
|
166
142
|
}
|
|
167
143
|
]
|
|
168
144
|
},
|
|
169
|
-
{
|
|
170
|
-
"name": "cleanup",
|
|
145
|
+
"cleanup": {
|
|
171
146
|
"always_run": true,
|
|
172
147
|
"request": {
|
|
173
148
|
"url": "https://api.example.com/cleanup",
|
|
174
149
|
"method": "POST"
|
|
175
150
|
}
|
|
176
151
|
}
|
|
177
|
-
|
|
152
|
+
}
|
|
178
153
|
}
|
|
179
154
|
```
|
|
180
155
|
|
|
@@ -196,54 +171,74 @@ Scenario we created:
|
|
|
196
171
|
finalizing call meant for graceful exit
|
|
197
172
|
`always_run` parameter means this stage will be executed regardless of errors in previous stages
|
|
198
173
|
|
|
199
|
-
For detailed
|
|
174
|
+
For detailed usage guide see the [full documentation](https://aeresov.github.io/pytest-httpchain).
|
|
175
|
+
|
|
176
|
+
## Installation
|
|
177
|
+
|
|
178
|
+
Install normally via package manager of your choice from PyPi:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
pip install pytest-httpchain
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
or directly from Github, in case you need a particular ref:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
pip install 'git+https://github.com/aeresov/pytest-httpchain@main'
|
|
188
|
+
```
|
|
200
189
|
|
|
201
190
|
## Configuration
|
|
202
191
|
|
|
203
|
-
- Test file discovery is based on this name pattern: `test_<name>.<suffix>.json`.
|
|
192
|
+
- Test file discovery is based on this name pattern: `test_<name>.<suffix>.json`.
|
|
204
193
|
The `suffix` is configurable as pytest ini option, default value is **http**.
|
|
205
|
-
- `$ref` instructions can point to other files; absolute and relative paths are supported.
|
|
194
|
+
- `$ref` instructions can point to other files; absolute and relative paths are supported.
|
|
206
195
|
You can limit the depth of relative path traversal using `ref_parent_traversal_depth` ini option, default value is **3**.
|
|
196
|
+
- Template expressions support list/dict comprehensions. You can limit the maximum comprehension length using `max_comprehension_length` ini option, default value is **50000**.
|
|
197
|
+
- Parallel stage iterations (repeat/foreach) have a safety limit configurable via `max_parallel_iterations` ini option, default value is **10000**.
|
|
207
198
|
|
|
208
|
-
##
|
|
199
|
+
## AI agent support
|
|
209
200
|
|
|
210
|
-
`pytest-httpchain`
|
|
201
|
+
`pytest-httpchain` ships tooling to help AI coding agents (and humans) author and check test scenarios.
|
|
211
202
|
|
|
212
|
-
###
|
|
203
|
+
### Claude Code skill
|
|
213
204
|
|
|
214
|
-
|
|
215
|
-
Use this script as call target for your MCP configuration.
|
|
205
|
+
Install the authoring skill into your project (or `--global` for personal scope):
|
|
216
206
|
|
|
217
|
-
|
|
207
|
+
```bash
|
|
208
|
+
uvx pytest-httpchain install
|
|
209
|
+
```
|
|
218
210
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
211
|
+
This writes `.claude/skills/pytest-httpchain/SKILL.md` with guidance for writing scenarios.
|
|
212
|
+
|
|
213
|
+
### Scenario validation
|
|
214
|
+
|
|
215
|
+
Validate scenario files for structure and common problems — undefined variables, duplicate stage names, fixture/variable conflicts, stages with no assertions:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
uvx pytest-httpchain validate tests/test_login.http.json
|
|
230
219
|
```
|
|
231
220
|
|
|
232
|
-
|
|
221
|
+
It exits non-zero when any file is invalid, so it doubles as a CI gate. The same checks also run automatically at **pytest collection time** — semantic errors fail collection and warnings are reported — so `pytest --collect-only` validates every scenario in your suite.
|
|
233
222
|
|
|
234
|
-
|
|
223
|
+
### Editor schema
|
|
235
224
|
|
|
236
|
-
-
|
|
225
|
+
A JSON Schema is published for as-you-type validation and autocomplete. Reference it from your test files:
|
|
226
|
+
|
|
227
|
+
```json
|
|
228
|
+
{
|
|
229
|
+
"$schema": "https://aeresov.github.io/pytest-httpchain/schema/scenario.schema.json"
|
|
230
|
+
}
|
|
231
|
+
```
|
|
237
232
|
|
|
238
233
|
## Documentation
|
|
239
234
|
|
|
240
|
-
- [
|
|
241
|
-
- [Full Documentation](https://aeresov.github.io/pytest-httpchain) - Complete guide
|
|
235
|
+
- [Full Documentation](https://aeresov.github.io/pytest-httpchain) - Complete usage guide
|
|
242
236
|
- [Changelog](CHANGELOG.md) - Release notes
|
|
243
237
|
|
|
244
238
|
## Thanks
|
|
245
239
|
|
|
246
|
-
|
|
240
|
+
This project was inspired by [Tavern](https://github.com/taverntesting/tavern) and [pytest-play](https://github.com/davidemoro/pytest-play).
|
|
241
|
+
|
|
247
242
|
[httpx](https://www.python-httpx.org) does comms.
|
|
248
243
|
[Pydantic](https://docs.pydantic.dev) keeps structure.
|
|
249
244
|
[simpleeval](https://github.com/danthedeckie/simpleeval) powers templates.
|
|
@@ -11,66 +11,44 @@ A pytest plugin for testing HTTP endpoints.
|
|
|
11
11
|
`pytest-httpchain` is an integration testing framework for HTTP APIs based on [httpx](https://www.python-httpx.org) lib.
|
|
12
12
|
It aims at helping with common HTTP API testing scenarios, where user needs to make several calls in specific order using data obtained along the way, like auth tokens or resource ids.
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
Install normally via package manager of your choice from PyPi:
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
pip install pytest-httpchain
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
or directly from Github, in case you need a particular ref:
|
|
23
|
-
|
|
24
|
-
```bash
|
|
25
|
-
pip install 'git+https://github.com/aeresov/pytest-httpchain@main'
|
|
26
|
-
```
|
|
14
|
+
## Why pytest-httpchain?
|
|
27
15
|
|
|
28
|
-
|
|
16
|
+
Testing HTTP APIs with plain pytest often leads to these pain points:
|
|
29
17
|
|
|
30
|
-
The
|
|
18
|
+
- **Boilerplate accumulates** — Every test repeats the same setup: create client, set headers, make request, parse response, assert. The actual test intent gets buried.
|
|
19
|
+
- **Data threading is manual** — When one call returns a token or ID needed by the next, you end up with fragile helper functions passing state around.
|
|
20
|
+
- **Common patterns get copy-pasted** — Auth flows, base URLs, shared headers end up duplicated across test files. Fixtures might help, but they are not designed for that.
|
|
21
|
+
- **Code reviews are noisy** — The actual test logic is rarely clear because of all the boilerplate and helpers, following changes gets overwhelming quickly.
|
|
31
22
|
|
|
32
|
-
-
|
|
23
|
+
`pytest-httpchain` offers a more structured approach.
|
|
33
24
|
|
|
34
25
|
## Features
|
|
35
26
|
|
|
36
|
-
###
|
|
27
|
+
### Declarative JSON format
|
|
37
28
|
|
|
38
|
-
|
|
29
|
+
Test scenarios are JSON documents that describe _what_ to test, not _how_. No setup code to scroll through — the request and assertions are right there.
|
|
39
30
|
|
|
40
|
-
###
|
|
31
|
+
### `$ref` with deep merging
|
|
41
32
|
|
|
42
|
-
|
|
43
|
-
`pytest-httpchain` supports JSONRef, so use can reuse arbitrary parts of your scenarios with `$ref` directive.
|
|
44
|
-
Properties are merged in a greedy way with type checking.
|
|
33
|
+
Reuse arbitrary parts of your scenarios with JSONRef. Properties merge with type checking, so you can compose scenarios from shared fragments (auth flows, common headers, base URLs).
|
|
45
34
|
|
|
46
|
-
### Multi-stage
|
|
35
|
+
### Multi-stage execution
|
|
47
36
|
|
|
48
|
-
Each
|
|
49
|
-
`pytest-httpchain` executes stages in the order they are listed in scenario file; one stage failure stops the execution chain.
|
|
37
|
+
Each scenario contains 1+ stages executed in order. One stage failure stops the chain. Use `always_run` for cleanup stages that should execute regardless.
|
|
50
38
|
|
|
51
|
-
### Common data context
|
|
39
|
+
### Common data context
|
|
52
40
|
|
|
53
|
-
|
|
54
|
-
This storage ("common data context") is populated with declared variables, fixtures and data saved by stages. The data remains there throughout the scenario execution.
|
|
55
|
-
Writing scenarios, you can use Jinja-style expressions like `"{{ var }}"` for JSON values. `pytest-httpchain` does variable substitution dynamically right before executing a stage, and uses common data context keys as variables in these expressions.
|
|
56
|
-
Values from common data context also might be verified during verified/asserted.
|
|
41
|
+
A key-value store persists throughout scenario execution. Variables, fixtures, and saved response data all live here. Use template expressions (`{{ var }}`) anywhere in your requests — substitution happens dynamically before each stage.
|
|
57
42
|
|
|
58
|
-
###
|
|
43
|
+
### Response processing
|
|
59
44
|
|
|
60
|
-
|
|
45
|
+
- **JMESPath** — Extract values from JSON responses directly
|
|
46
|
+
- **JSON Schema** — Validate response structure against a schema
|
|
47
|
+
- **User functions** — Call Python functions for custom extraction, verification, or [authentication](https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication)
|
|
61
48
|
|
|
62
|
-
|
|
63
|
-
- to verify HTTP response and values in common data context
|
|
64
|
-
- to provide [custom authentication for requests](https://requests.readthedocs.io/en/latest/user/advanced/#custom-authentication)
|
|
65
|
-
- to call in substitution expressions
|
|
49
|
+
### Full pytest integration
|
|
66
50
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
`pytest-httpchain` can extract values from JSON responses using JMESPath expressions directly.
|
|
70
|
-
|
|
71
|
-
### JSON schema support
|
|
72
|
-
|
|
73
|
-
`pytest-httpchain` can verify JSON reponses against user-defined JSON schema.
|
|
51
|
+
Markers, fixtures, parametrization, and other plugins work as expected. You're not locked into a separate ecosystem.
|
|
74
52
|
|
|
75
53
|
## Quick Start
|
|
76
54
|
|
|
@@ -95,9 +73,8 @@ def now_utc():
|
|
|
95
73
|
}
|
|
96
74
|
}
|
|
97
75
|
],
|
|
98
|
-
"stages":
|
|
99
|
-
{
|
|
100
|
-
"name": "get_user",
|
|
76
|
+
"stages": {
|
|
77
|
+
"get_user": {
|
|
101
78
|
"request": {
|
|
102
79
|
"url": "https://api.example.com/users/{{ user_id }}"
|
|
103
80
|
},
|
|
@@ -116,8 +93,7 @@ def now_utc():
|
|
|
116
93
|
}
|
|
117
94
|
]
|
|
118
95
|
},
|
|
119
|
-
{
|
|
120
|
-
"name": "update_user",
|
|
96
|
+
"update_user": {
|
|
121
97
|
"fixtures": ["now_utc"],
|
|
122
98
|
"request": {
|
|
123
99
|
"url": "https://api.example.com/users/{{ user_id }}",
|
|
@@ -139,15 +115,14 @@ def now_utc():
|
|
|
139
115
|
}
|
|
140
116
|
]
|
|
141
117
|
},
|
|
142
|
-
{
|
|
143
|
-
"name": "cleanup",
|
|
118
|
+
"cleanup": {
|
|
144
119
|
"always_run": true,
|
|
145
120
|
"request": {
|
|
146
121
|
"url": "https://api.example.com/cleanup",
|
|
147
122
|
"method": "POST"
|
|
148
123
|
}
|
|
149
124
|
}
|
|
150
|
-
|
|
125
|
+
}
|
|
151
126
|
}
|
|
152
127
|
```
|
|
153
128
|
|
|
@@ -169,54 +144,74 @@ Scenario we created:
|
|
|
169
144
|
finalizing call meant for graceful exit
|
|
170
145
|
`always_run` parameter means this stage will be executed regardless of errors in previous stages
|
|
171
146
|
|
|
172
|
-
For detailed
|
|
147
|
+
For detailed usage guide see the [full documentation](https://aeresov.github.io/pytest-httpchain).
|
|
148
|
+
|
|
149
|
+
## Installation
|
|
150
|
+
|
|
151
|
+
Install normally via package manager of your choice from PyPi:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pip install pytest-httpchain
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
or directly from Github, in case you need a particular ref:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
pip install 'git+https://github.com/aeresov/pytest-httpchain@main'
|
|
161
|
+
```
|
|
173
162
|
|
|
174
163
|
## Configuration
|
|
175
164
|
|
|
176
|
-
- Test file discovery is based on this name pattern: `test_<name>.<suffix>.json`.
|
|
165
|
+
- Test file discovery is based on this name pattern: `test_<name>.<suffix>.json`.
|
|
177
166
|
The `suffix` is configurable as pytest ini option, default value is **http**.
|
|
178
|
-
- `$ref` instructions can point to other files; absolute and relative paths are supported.
|
|
167
|
+
- `$ref` instructions can point to other files; absolute and relative paths are supported.
|
|
179
168
|
You can limit the depth of relative path traversal using `ref_parent_traversal_depth` ini option, default value is **3**.
|
|
169
|
+
- Template expressions support list/dict comprehensions. You can limit the maximum comprehension length using `max_comprehension_length` ini option, default value is **50000**.
|
|
170
|
+
- Parallel stage iterations (repeat/foreach) have a safety limit configurable via `max_parallel_iterations` ini option, default value is **10000**.
|
|
180
171
|
|
|
181
|
-
##
|
|
172
|
+
## AI agent support
|
|
182
173
|
|
|
183
|
-
`pytest-httpchain`
|
|
174
|
+
`pytest-httpchain` ships tooling to help AI coding agents (and humans) author and check test scenarios.
|
|
184
175
|
|
|
185
|
-
###
|
|
176
|
+
### Claude Code skill
|
|
186
177
|
|
|
187
|
-
|
|
188
|
-
Use this script as call target for your MCP configuration.
|
|
178
|
+
Install the authoring skill into your project (or `--global` for personal scope):
|
|
189
179
|
|
|
190
|
-
|
|
180
|
+
```bash
|
|
181
|
+
uvx pytest-httpchain install
|
|
182
|
+
```
|
|
191
183
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
184
|
+
This writes `.claude/skills/pytest-httpchain/SKILL.md` with guidance for writing scenarios.
|
|
185
|
+
|
|
186
|
+
### Scenario validation
|
|
187
|
+
|
|
188
|
+
Validate scenario files for structure and common problems — undefined variables, duplicate stage names, fixture/variable conflicts, stages with no assertions:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
uvx pytest-httpchain validate tests/test_login.http.json
|
|
203
192
|
```
|
|
204
193
|
|
|
205
|
-
|
|
194
|
+
It exits non-zero when any file is invalid, so it doubles as a CI gate. The same checks also run automatically at **pytest collection time** — semantic errors fail collection and warnings are reported — so `pytest --collect-only` validates every scenario in your suite.
|
|
206
195
|
|
|
207
|
-
|
|
196
|
+
### Editor schema
|
|
208
197
|
|
|
209
|
-
-
|
|
198
|
+
A JSON Schema is published for as-you-type validation and autocomplete. Reference it from your test files:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"$schema": "https://aeresov.github.io/pytest-httpchain/schema/scenario.schema.json"
|
|
203
|
+
}
|
|
204
|
+
```
|
|
210
205
|
|
|
211
206
|
## Documentation
|
|
212
207
|
|
|
213
|
-
- [
|
|
214
|
-
- [Full Documentation](https://aeresov.github.io/pytest-httpchain) - Complete guide
|
|
208
|
+
- [Full Documentation](https://aeresov.github.io/pytest-httpchain) - Complete usage guide
|
|
215
209
|
- [Changelog](CHANGELOG.md) - Release notes
|
|
216
210
|
|
|
217
211
|
## Thanks
|
|
218
212
|
|
|
219
|
-
|
|
213
|
+
This project was inspired by [Tavern](https://github.com/taverntesting/tavern) and [pytest-play](https://github.com/davidemoro/pytest-play).
|
|
214
|
+
|
|
220
215
|
[httpx](https://www.python-httpx.org) does comms.
|
|
221
216
|
[Pydantic](https://docs.pydantic.dev) keeps structure.
|
|
222
217
|
[simpleeval](https://github.com/danthedeckie/simpleeval) powers templates.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "pytest-httpchain"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
description = "pytest plugin for HTTP testing using JSON files"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13,<4.0"
|
|
@@ -11,7 +11,9 @@ dependencies = [
|
|
|
11
11
|
"pyrate-limiter>=3.0.0",
|
|
12
12
|
"pytest-httpchain-jsonref",
|
|
13
13
|
"pytest-httpchain-models",
|
|
14
|
+
"pytest-httpchain-templates",
|
|
14
15
|
"pytest-order>=1.3.0",
|
|
16
|
+
"typer>=0.16.0",
|
|
15
17
|
]
|
|
16
18
|
keywords = ["testing", "pytest", "requests"]
|
|
17
19
|
license = "MIT"
|
|
@@ -26,9 +28,6 @@ classifiers = [
|
|
|
26
28
|
"Topic :: Software Development :: Testing",
|
|
27
29
|
]
|
|
28
30
|
|
|
29
|
-
[project.optional-dependencies]
|
|
30
|
-
mcp = ["pytest-httpchain-mcp"]
|
|
31
|
-
|
|
32
31
|
[dependency-groups]
|
|
33
32
|
dev = [
|
|
34
33
|
"flask-httpauth>=4.8.0",
|
|
@@ -52,9 +51,9 @@ default-groups = ["dev", "docs"]
|
|
|
52
51
|
members = ["packages/*"]
|
|
53
52
|
|
|
54
53
|
[tool.uv.sources]
|
|
54
|
+
pytest-httpchain-core = { workspace = true }
|
|
55
55
|
pytest-httpchain-jsonref = { workspace = true }
|
|
56
56
|
pytest-httpchain-templates = { workspace = true }
|
|
57
|
-
pytest-httpchain-mcp = { workspace = true }
|
|
58
57
|
pytest-httpchain-models = { workspace = true }
|
|
59
58
|
pytest-httpchain-userfunc = { workspace = true }
|
|
60
59
|
|
|
@@ -62,6 +61,9 @@ pytest-httpchain-userfunc = { workspace = true }
|
|
|
62
61
|
requires = ["uv_build>=0.7.21,<0.8.0"]
|
|
63
62
|
build-backend = "uv_build"
|
|
64
63
|
|
|
64
|
+
[project.scripts]
|
|
65
|
+
pytest-httpchain = "pytest_httpchain.cli:app"
|
|
66
|
+
|
|
65
67
|
[project.entry-points.pytest11]
|
|
66
68
|
pytest_httpchain = "pytest_httpchain.plugin"
|
|
67
69
|
|
|
@@ -97,9 +99,9 @@ pytester_example_dir = "tests/integration/examples"
|
|
|
97
99
|
addopts = ["--log-disable=werkzeug", "--import-mode=importlib"]
|
|
98
100
|
pythonpath = [
|
|
99
101
|
".",
|
|
102
|
+
"packages/pytest-httpchain-core/src",
|
|
100
103
|
"packages/pytest-httpchain-jsonref/src",
|
|
101
104
|
"packages/pytest-httpchain-templates/src",
|
|
102
|
-
"packages/pytest-httpchain-mcp/src",
|
|
103
105
|
"packages/pytest-httpchain-models/src",
|
|
104
106
|
"packages/pytest-httpchain-userfunc/src",
|
|
105
107
|
]
|
|
@@ -117,9 +119,9 @@ pythonPlatform = "Linux"
|
|
|
117
119
|
[tool.coverage.run]
|
|
118
120
|
source = [
|
|
119
121
|
"src",
|
|
122
|
+
"packages/pytest-httpchain-core/src",
|
|
120
123
|
"packages/pytest-httpchain-jsonref/src",
|
|
121
124
|
"packages/pytest-httpchain-templates/src",
|
|
122
|
-
"packages/pytest-httpchain-mcp/src",
|
|
123
125
|
"packages/pytest-httpchain-models/src",
|
|
124
126
|
"packages/pytest-httpchain-userfunc/src",
|
|
125
127
|
]
|