Skip to content

Commit deaf361

Browse files
use pytest-httpbin instead of a local service
1 parent 8254da5 commit deaf361

File tree

8 files changed

+65
-71
lines changed

8 files changed

+65
-71
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ jobs:
5757
name: test-${{ matrix.python-version }} ${{ matrix.nox-session }}
5858
continue-on-error: ${{ matrix.experimental }}
5959
services:
60-
httpbin:
61-
image: kennethreitz/httpbin
62-
ports:
63-
- 8080:80
6460
elasticsearch:
6561
image: docker.elastic.co/elasticsearch/elasticsearch:9.0.2
6662
env:

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"pytest-cov",
6161
"pytest-mock",
6262
"pytest-asyncio",
63+
"pytest-httpbin",
6364
"pytest-httpserver",
6465
"trustme",
6566
"requests",

tests/async_/test_async_transport.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,20 @@
4646

4747

4848
@pytest.mark.asyncio
49-
async def test_async_transport_httpbin(httpbin_node_config):
49+
async def test_async_transport_httpbin(httpbin_node_config, httpbin):
5050
t = AsyncTransport([httpbin_node_config], meta_header=False)
5151
resp, data = await t.perform_request("GET", "/anything?key=value")
5252

5353
assert resp.status == 200
5454
assert data["method"] == "GET"
55-
assert data["url"] == "http://localhost:8080/anything?key=value"
55+
assert data["url"] == f"{httpbin.url}/anything?key=value"
5656
assert data["args"] == {"key": "value"}
5757

5858
data["headers"].pop("X-Amzn-Trace-Id", None)
5959
assert data["headers"] == {
6060
"User-Agent": DEFAULT_USER_AGENT,
6161
"Connection": "keep-alive",
62-
"Host": "localhost:8080",
62+
"Host": f"{httpbin.host}:{httpbin.port}",
6363
}
6464

6565

tests/async_/test_httpbin.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828

2929
@pytest.mark.asyncio
30-
async def test_simple_request(httpbin_node_config):
30+
async def test_simple_request(httpbin_node_config, httpbin):
3131
t = AsyncTransport([httpbin_node_config])
3232

3333
resp, data = await t.perform_request(
@@ -38,7 +38,7 @@ async def test_simple_request(httpbin_node_config):
3838
)
3939
assert resp.status == 200
4040
assert data["method"] == "GET"
41-
assert data["url"] == "http://localhost:8080/anything?key[]=1&key[]=2&q1&q2="
41+
assert data["url"] == f"{httpbin.url}/anything?key[]=1&key[]=2&q1&q2="
4242

4343
# httpbin makes no-value query params into ''
4444
assert data["args"] == {
@@ -54,13 +54,13 @@ async def test_simple_request(httpbin_node_config):
5454
"Content-Length": "15",
5555
"Custom": "headeR",
5656
"Connection": "keep-alive",
57-
"Host": "localhost:8080",
57+
"Host": f"{httpbin.host}:{httpbin.port}",
5858
}
5959
assert all(v == data["headers"][k] for k, v in request_headers.items())
6060

6161

6262
@pytest.mark.asyncio
63-
async def test_node(httpbin_node_config):
63+
async def test_node(httpbin_node_config, httpbin):
6464
def new_node(**kwargs):
6565
return AiohttpHttpNode(dataclasses.replace(httpbin_node_config, **kwargs))
6666

@@ -71,11 +71,11 @@ def new_node(**kwargs):
7171
assert parsed == {
7272
"headers": {
7373
"Connection": "keep-alive",
74-
"Host": "localhost:8080",
74+
"Host": f"{httpbin.host}:{httpbin.port}",
7575
"User-Agent": DEFAULT_USER_AGENT,
7676
},
7777
"method": "GET",
78-
"url": "http://localhost:8080/anything",
78+
"url": f"{httpbin.url}/anything",
7979
}
8080

8181
node = new_node(http_compress=True)
@@ -86,11 +86,11 @@ def new_node(**kwargs):
8686
"headers": {
8787
"Accept-Encoding": "gzip",
8888
"Connection": "keep-alive",
89-
"Host": "localhost:8080",
89+
"Host": f"{httpbin.host}:{httpbin.port}",
9090
"User-Agent": DEFAULT_USER_AGENT,
9191
},
9292
"method": "GET",
93-
"url": "http://localhost:8080/anything",
93+
"url": f"{httpbin.url}/anything",
9494
}
9595

9696
resp, data = await node.perform_request("GET", "/anything", body=b"hello, world!")
@@ -103,11 +103,11 @@ def new_node(**kwargs):
103103
"Content-Type": "application/octet-stream",
104104
"Content-Length": "33",
105105
"Connection": "keep-alive",
106-
"Host": "localhost:8080",
106+
"Host": f"{httpbin.host}:{httpbin.port}",
107107
"User-Agent": DEFAULT_USER_AGENT,
108108
},
109109
"method": "GET",
110-
"url": "http://localhost:8080/anything",
110+
"url": f"{httpbin.url}/anything",
111111
}
112112

113113
resp, data = await node.perform_request(
@@ -125,9 +125,9 @@ def new_node(**kwargs):
125125
"Content-Length": "36",
126126
"Content-Type": "application/json",
127127
"Connection": "keep-alive",
128-
"Host": "localhost:8080",
128+
"Host": f"{httpbin.host}:{httpbin.port}",
129129
"User-Agent": DEFAULT_USER_AGENT,
130130
},
131131
"method": "POST",
132-
"url": "http://localhost:8080/anything",
132+
"url": f"{httpbin.url}/anything",
133133
}

tests/conftest.py

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,9 @@ def cert_fingerprint(request) -> str:
8484

8585

8686
@pytest.fixture(scope="session")
87-
def httpbin_node_config() -> NodeConfig:
88-
try:
89-
sock = socket.create_connection(("localhost", 8080))
90-
except Exception as e:
91-
pytest.skip(
92-
f"Couldn't connect to localhost:8080, not running httpbin image? {e}"
93-
)
94-
sock.close()
87+
def httpbin_node_config(httpbin) -> NodeConfig:
9588
return NodeConfig(
96-
"http", "localhost", 8080, verify_certs=False, ssl_show_warn=False
89+
"http", httpbin.host, httpbin.port, verify_certs=False, ssl_show_warn=False
9790
)
9891

9992

tests/node/test_http_aiohttp.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -307,27 +307,29 @@ async def test_ssl_assert_fingerprint(cert_fingerprint):
307307

308308

309309
@pytest.mark.asyncio
310-
async def test_default_headers():
311-
node = AiohttpHttpNode(NodeConfig(scheme="http", host="localhost", port=8080))
310+
async def test_default_headers(httpbin):
311+
node = AiohttpHttpNode(
312+
NodeConfig(scheme="http", host=httpbin.host, port=httpbin.port)
313+
)
312314
resp, data = await node.perform_request("GET", "/anything")
313315

314316
assert resp.status == 200
315317
headers = json.loads(data)["headers"]
316318
headers.pop("X-Amzn-Trace-Id", None)
317319
assert headers == {
318320
"Connection": "keep-alive",
319-
"Host": "localhost:8080",
321+
"Host": f"{httpbin.host}:{httpbin.port}",
320322
"User-Agent": DEFAULT_USER_AGENT,
321323
}
322324

323325

324326
@pytest.mark.asyncio
325-
async def test_custom_headers():
327+
async def test_custom_headers(httpbin):
326328
node = AiohttpHttpNode(
327329
NodeConfig(
328330
scheme="http",
329-
host="localhost",
330-
port=8080,
331+
host=httpbin.host,
332+
port=httpbin.port,
331333
headers={"accept-encoding": "gzip", "Content-Type": "application/json"},
332334
)
333335
)
@@ -347,18 +349,18 @@ async def test_custom_headers():
347349
"Accept-Encoding": "gzip",
348350
"Connection": "keep-alive",
349351
"Content-Type": "application/x-ndjson",
350-
"Host": "localhost:8080",
352+
"Host": f"{httpbin.host}:{httpbin.port}",
351353
"User-Agent": "custom-agent/1.2.3",
352354
}
353355

354356

355357
@pytest.mark.asyncio
356-
async def test_custom_user_agent():
358+
async def test_custom_user_agent(httpbin):
357359
node = AiohttpHttpNode(
358360
NodeConfig(
359361
scheme="http",
360-
host="localhost",
361-
port=8080,
362+
host=httpbin.host,
363+
port=httpbin.port,
362364
headers={
363365
"accept-encoding": "gzip",
364366
"Content-Type": "application/json",
@@ -378,7 +380,7 @@ async def test_custom_user_agent():
378380
"Accept-Encoding": "gzip",
379381
"Connection": "keep-alive",
380382
"Content-Type": "application/json",
381-
"Host": "localhost:8080",
383+
"Host": f"{httpbin.host}:{httpbin.port}",
382384
"User-Agent": "custom-agent/1.2.3",
383385
}
384386

@@ -389,9 +391,11 @@ def test_repr():
389391

390392

391393
@pytest.mark.asyncio
392-
async def test_head():
394+
async def test_head(httpbin):
393395
node = AiohttpHttpNode(
394-
NodeConfig(scheme="http", host="localhost", port=8080, http_compress=True)
396+
NodeConfig(
397+
scheme="http", host=httpbin.host, port=httpbin.port, http_compress=True
398+
)
395399
)
396400
resp, data = await node.perform_request("HEAD", "/anything")
397401

tests/test_httpbin.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727

2828
@pytest.mark.parametrize("node_class", ["urllib3", "requests"])
29-
def test_simple_request(node_class, httpbin_node_config):
29+
def test_simple_request(node_class, httpbin_node_config, httpbin):
3030
t = Transport([httpbin_node_config], node_class=node_class)
3131

3232
resp, data = t.perform_request(
@@ -37,7 +37,7 @@ def test_simple_request(node_class, httpbin_node_config):
3737
)
3838
assert resp.status == 200
3939
assert data["method"] == "GET"
40-
assert data["url"] == "http://localhost:8080/anything?key[]=1&key[]=2&q1&q2="
40+
assert data["url"] == f"{httpbin.url}/anything?key[]=1&key[]=2&q1&q2="
4141

4242
# httpbin makes no-value query params into ''
4343
assert data["args"] == {
@@ -53,13 +53,13 @@ def test_simple_request(node_class, httpbin_node_config):
5353
"Content-Length": "15",
5454
"Custom": "headeR",
5555
"Connection": "keep-alive",
56-
"Host": "localhost:8080",
56+
"Host": f"{httpbin.host}:{httpbin.port}",
5757
}
5858
assert all(v == data["headers"][k] for k, v in request_headers.items())
5959

6060

6161
@pytest.mark.parametrize("node_class", ["urllib3", "requests"])
62-
def test_node(node_class, httpbin_node_config):
62+
def test_node(node_class, httpbin_node_config, httpbin):
6363
def new_node(**kwargs):
6464
return NODE_CLASS_NAMES[node_class](
6565
dataclasses.replace(httpbin_node_config, **kwargs)
@@ -73,11 +73,11 @@ def new_node(**kwargs):
7373
"headers": {
7474
"Accept-Encoding": "identity",
7575
"Connection": "keep-alive",
76-
"Host": "localhost:8080",
76+
"Host": f"{httpbin.host}:{httpbin.port}",
7777
"User-Agent": DEFAULT_USER_AGENT,
7878
},
7979
"method": "GET",
80-
"url": "http://localhost:8080/anything",
80+
"url": f"{httpbin.url}/anything",
8181
}
8282

8383
node = new_node(http_compress=True)
@@ -88,11 +88,11 @@ def new_node(**kwargs):
8888
"headers": {
8989
"Accept-Encoding": "gzip",
9090
"Connection": "keep-alive",
91-
"Host": "localhost:8080",
91+
"Host": f"{httpbin.host}:{httpbin.port}",
9292
"User-Agent": DEFAULT_USER_AGENT,
9393
},
9494
"method": "GET",
95-
"url": "http://localhost:8080/anything",
95+
"url": f"{httpbin.url}/anything",
9696
}
9797

9898
resp, data = node.perform_request("GET", "/anything", body=b"hello, world!")
@@ -104,11 +104,11 @@ def new_node(**kwargs):
104104
"Content-Encoding": "gzip",
105105
"Content-Length": "33",
106106
"Connection": "keep-alive",
107-
"Host": "localhost:8080",
107+
"Host": f"{httpbin.host}:{httpbin.port}",
108108
"User-Agent": DEFAULT_USER_AGENT,
109109
},
110110
"method": "GET",
111-
"url": "http://localhost:8080/anything",
111+
"url": f"{httpbin.url}/anything",
112112
}
113113

114114
resp, data = node.perform_request(
@@ -126,11 +126,11 @@ def new_node(**kwargs):
126126
"Content-Length": "36",
127127
"Content-Type": "application/json",
128128
"Connection": "keep-alive",
129-
"Host": "localhost:8080",
129+
"Host": f"{httpbin.host}:{httpbin.port}",
130130
"User-Agent": DEFAULT_USER_AGENT,
131131
},
132132
"method": "POST",
133-
"url": "http://localhost:8080/anything",
133+
"url": f"{httpbin.url}/anything",
134134
}
135135

136136

tests/test_logging.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
@node_class
4040
@pytest.mark.asyncio
41-
async def test_debug_logging(node_class, httpbin_node_config):
41+
async def test_debug_logging(node_class, httpbin_node_config, httpbin):
4242
debug_logging()
4343

4444
stream = io.StringIO()
@@ -59,8 +59,8 @@ async def test_debug_logging(node_class, httpbin_node_config):
5959
print(node_class)
6060
print(stream.getvalue())
6161

62-
lines = stream.getvalue().split("\n")
63-
print(lines)
62+
response = stream.getvalue()
63+
print(response)
6464
for line in [
6565
"> GET /anything HTTP/1.1",
6666
"> Connection: keep-alive",
@@ -72,23 +72,23 @@ async def test_debug_logging(node_class, httpbin_node_config):
7272
"< Access-Control-Allow-Origin: *",
7373
"< Content-Type: application/json",
7474
"< {",
75-
' "args": {}, ',
76-
' "data": "{\\"key\\":\\"value\\"}", ',
77-
' "files": {}, ',
78-
' "form": {}, ',
79-
' "headers": {',
80-
' "Content-Type": "application/json", ',
81-
' "Host": "localhost:8080", ',
82-
f' "User-Agent": "{DEFAULT_USER_AGENT}"',
83-
" }, ",
84-
' "json": {',
85-
' "key": "value"',
86-
" }, ",
87-
' "method": "GET", ',
88-
' "url": "http://localhost:8080/anything"',
75+
'"args":{},',
76+
'"data":"{\\"key\\":\\"value\\"}",',
77+
'"files":{},',
78+
'"form":{},',
79+
'"headers":{',
80+
'"Content-Type":"application/json",',
81+
f'"Host":"{httpbin.host}:{httpbin.port}",',
82+
f'"User-Agent":"{DEFAULT_USER_AGENT}"',
83+
"},",
84+
'"json":{',
85+
'"key":"value"',
86+
"},",
87+
'"method":"GET",',
88+
f'"url":"{httpbin.url}/anything"',
8989
"}",
9090
]:
91-
assert line in lines
91+
assert line in response
9292

9393

9494
@node_class

0 commit comments

Comments
 (0)