pytest-httpserver 是一个 pytest 插件,用于在测试期间启动一个简单的 HTTP 服务器。它非常适用于编写测试用例,特别是那些需要模拟 HTTP 请求和响应的场景。下面我会详细介绍如何使用 pytest-httpserver 并给出十个具体的例子及其应用场景和输出结果。
首先,你需要安装 pytest-httpserver。可以通过 pip 安装:
pip install pytest-httpserver
- 基本 GET 请求
场景描述:
启动一个 HTTP 服务器,监听一个端点 /test,返回固定的内容。
使用 requests 库发送 GET 请求并验证返回内容。
from httpserver import HTTPServer
import requests
import pytest
@pytest.fixture
def httpserver_listen_port():
return 8000
def test_httpserver(httpserver):
# 设置 HTTP 服务器的路由
httpserver.expect_request("/test").respond_with_data("Hello, World!")
# 发送 GET 请求
response = requests.get(f"http://localhost:{httpserver.port}/test")
assert response.text == "Hello, World!"
输出结果:
PASSED
- POST 请求并返回 JSON
场景描述:
设置一个 POST 路由,接收 JSON 数据并返回 JSON 响应。
使用 requests 发送 POST 请求。
def test_httpserver(httpserver):
httpserver.expect_request("/post", method="POST").respond_with_json({"message": "Received"})
response = requests.post(f"http://localhost:{httpserver.port}/post", json={"data": "Hello"})
assert response.json() == {"message": "Received"}
输出结果:
PASSED
- 验证请求头
场景描述:
设置一个路由,检查请求头是否包含特定值。
发送带有指定请求头的 GET 请求。
def test_httpserver(httpserver):
httpserver.expect_request("/header", headers={"X-Custom-Header": "My-Value"}).respond_with_data("Custom header received")
response = requests.get(f"http://localhost:{httpserver.port}/header", headers={"X-Custom-Header": "My-Value"})
assert response.text == "Custom header received"
输出结果:
PASSED
- 检查查询参数
场景描述:
设置一个路由,检查 URL 中的查询参数。
发送带有查询参数的 GET 请求。
def test_httpserver(httpserver):
httpserver.expect_request("/query", query_string="param=value").respond_with_data("Query param received")
response = requests.get(f"http://localhost:{httpserver.port}/query?param=value")
assert response.text == "Query param received"
输出结果:
PASSED
- 多次请求
场景描述:
设置一个路由,只允许特定次数的请求。
发送多次 GET 请求并验证结果。
def test_httpserver(httpserver):
httpserver.expect_request("/count").respond_with_data("Counting", times=2)
response1 = requests.get(f"http://localhost:{httpserver.port}/count")
response2 = requests.get(f"http://localhost:{httpserver.port}/count")
response3 = requests.get(f"http://localhost:{httpserver.port}/count")
assert response1.text == "Counting"
assert response2.text == "Counting"
assert response3.status_code == 404
输出结果:
PASSED
- 返回错误状态码
场景描述:
设置一个路由,返回特定的错误状态码。
发送 GET 请求并验证返回的状态码。
def test_httpserver(httpserver):
httpserver.expect_request("/error").respond_with_status(404)
response = requests.get(f"http://localhost:{httpserver.port}/error")
assert response.status_code == 404
输出结果:
PASSED
INSPIRATION
- 测试重定向
场景描述:
设置一个路由,将请求重定向到另一个 URL。
发送 GET 请求并验证重定向行为。
def test_httpserver(httpserver):
httpserver.expect_request("/redirect").respond_with_redirect("/target")
response = requests.get(f"http://localhost:{httpserver.port}/redirect", allow_redirects=False)
assert response.status_code == 302
assert response.headers["Location"] == "/target"
输出结果:
PASSED
- 上传文件
场景描述:
设置一个路由,接收文件上传请求。
使用 requests 发送文件上传请求。
def test_httpserver(httpserver):
httpserver.expect_request("/upload", method="POST").respond_with_data("File uploaded")
files = {'file': ('example.txt', 'Some file content'.encode('utf-8'))}
response = requests.post(f"http://localhost:{httpserver.port}/upload", files=files)
assert response.text == "File uploaded"
输出结果:
PASSED
- 设置超时
场景描述:
设置一个路由,等待一段时间后才响应。
使用 requests 发送请求,并设置超时。
def test_httpserver(httpserver):
httpserver.expect_request("/timeout", delay=2).respond_with_data("Delayed response")
response = requests.get(f"http://localhost:{httpserver.port}/timeout", timeout=3)
assert response.text == "Delayed response"
输出结果:
PASSED
- 验证客户端证书
场景描述:
设置一个路由,要求客户端发送证书。
使用 requests 发送带证书的请求。
import ssl
def test_httpserver(httpserver):
httpserver.expect_request("/cert", method="GET").respond_with_data("Certificate received")
cert_file = "path/to/cert.pem"
key_file = "path/to/key.pem"
response = requests.get(f"https://localhost:{httpserver.port}/cert", verify=False, cert=(cert_file, key_file))
assert response.text == "Certificate received"
注意事项:
为了使此示例工作,你需要生成一个 SSL 证书和密钥,并将路径替换为实际的文件路径。
这里使用了 verify=False 来跳过 SSL 证书验证,仅用于测试目的。