Sanic的pytest插件
项目描述
构建 |
|
---|---|
文档 |
|
包 |
一个Sanic的pytest插件。它帮助您异步测试代码。
此插件提供
使用异步协程进行非常简单的测试
常见且有用的固定装置
异步固定装置支持
为Sanic应用程序提供test_client/sanic_client
为Sanic应用程序提供test_server
您可以在这里了解更多信息
http://pytest-sanic.readthedocs.io/en/latest/
发布和变更日志可以在以下位置找到
https://github.com/yunstanford/pytest-sanic/releases
安装
pip install pytest-sanic
快速入门
您不需要显式加载pytest-sanic。pytest会为您完成。
您可以为您的app设置一个固定装置,如下所示
import pytest
from .app import create_app
@pytest.yield_fixture
def app():
app = create_app(test_config, **params)
yield app
然后可以从测试中使用此app固定装置
async def test_sanic_db_find_by_id(app):
"""
Let's assume that, in db we have,
{
"id": "123",
"name": "Kobe Bryant",
"team": "Lakers",
}
"""
doc = await app.db["players"].find_by_id("123")
assert doc.name == "Kobe Bryant"
assert doc.team == "Lakers"
要向您的app发送请求,您可以使用loop和sanic_client固定装置设置一个客户端固定装置
@pytest.fixture
def test_cli(loop, app, sanic_client):
return loop.run_until_complete(sanic_client(app))
然后可以使用此test_cli固定装置向您的app发送请求
async def test_index(test_cli):
resp = await test_cli.get('/')
assert resp.status_code == 200
async def test_player(test_cli):
resp = await test_cli.get('/player')
assert resp.status_code == 200
异步固定装置
pytest-sanic还支持异步固定装置,只需像常见的pytest固定装置一样编写它们。
@pytest.fixture
async def async_fixture_sleep():
await asyncio.sleep(0.1)
return "sleep..."
固定装置
一些用于轻松测试的固定装置。
loop
pytest-sanic 创建一个事件循环并将其注入为固定值。 pytest 将使用此事件循环来运行您的 async tests。 默认情况下,固定值 loop 是 asyncio.new_event_loop 的实例。但是,您也可以通过简单地传递 --loop uvloop 来选择 uvloop。 请记住只使用一个事件循环。
unused_port
本地的未使用 TCP 端口。
test_server
通过提供一个 Sanic 应用程序来创建一个 TestServer 实例。利用 test_server 创建您的 Sanic 应用程序服务器进行测试非常简单。
@pytest.yield_fixture
def app():
app = Sanic("test_sanic_app")
@app.route("/test_get", methods=['GET'])
async def test_get(request):
return response.json({"GET": True})
yield app
@pytest.fixture
def sanic_server(loop, app, test_server):
return loop.run_until_complete(test_server(app))
您也可以非常容易地通过创建自己的来覆盖此 loop 固定值,如下所示,
@pytest.yield_fixture
def loop():
loop = MyEventLoop()
yield loop
loop.close()
test_client
test_client 已弃用,请使用 sanic_client 代替,更多上下文请查看 问题。
sanic_client
通过提供一个 Sanic 应用程序来创建一个 TestClient 实例。您可以使用 sanic_client 简单地拥有一个客户端,如下所示
@pytest.yield_fixture
def app():
app = Sanic("test_sanic_app")
@app.route("/test_get", methods=['GET'])
async def test_get(request):
return response.json({"GET": True})
@app.route("/test_post", methods=['POST'])
async def test_post(request):
return response.json({"POST": True})
@app.route("/test_put", methods=['PUT'])
async def test_put(request):
return response.json({"PUT": True})
@app.route("/test_delete", methods=['DELETE'])
async def test_delete(request):
return response.json({"DELETE": True})
@app.route("/test_patch", methods=['PATCH'])
async def test_patch(request):
return response.json({"PATCH": True})
@app.route("/test_options", methods=['OPTIONS'])
async def test_options(request):
return response.json({"OPTIONS": True})
@app.route("/test_head", methods=['HEAD'])
async def test_head(request):
return response.json({"HEAD": True})
@app.websocket("/test_ws")
async def test_ws(request, ws):
data = await ws.recv()
await ws.send(data)
yield app
@pytest.fixture
def test_cli(loop, app, sanic_client):
return loop.run_until_complete(sanic_client(app, protocol=WebSocketProtocol))
#########
# Tests #
#########
async def test_fixture_test_client_get(test_cli):
"""
GET request
"""
resp = await test_cli.get('/test_get')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"GET": True}
async def test_fixture_test_client_post(test_cli):
"""
POST request
"""
resp = await test_cli.post('/test_post')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"POST": True}
async def test_fixture_test_client_put(test_cli):
"""
PUT request
"""
resp = await test_cli.put('/test_put')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"PUT": True}
async def test_fixture_test_client_delete(test_cli):
"""
DELETE request
"""
resp = await test_cli.delete('/test_delete')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"DELETE": True}
async def test_fixture_test_client_patch(test_cli):
"""
PATCH request
"""
resp = await test_cli.patch('/test_patch')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"PATCH": True}
async def test_fixture_test_client_options(test_cli):
"""
OPTIONS request
"""
resp = await test_cli.options('/test_options')
assert resp.status_code == 200
resp_json = resp.json()
assert resp_json == {"OPTIONS": True}
async def test_fixture_test_client_head(test_cli):
"""
HEAD request
"""
resp = await test_cli.head('/test_head')
assert resp.status_code == 200
resp_json = resp.json()
# HEAD should not have body
assert resp_json is None
async def test_fixture_test_client_ws(test_cli):
"""
Websockets
"""
ws_conn = await test_cli.ws_connect('/test_ws')
data = 'hello world!'
await ws_conn.send(data)
msg = await ws_conn.recv()
assert msg == data
await ws_conn.close()
小贴士
test_cli.ws_connect 在 sanic.__version__ <= '0.5.4' 中不起作用,因为存在一个 Sanic 错误,但在 master 分支中已修复。另外,由于 websockets.__version__ >= '4.0' 在 sanic.__version__ <= '0.6.0' 中破坏了 websockets,但在 此提交 中已修复。
提示
test_cli.ws_connect 在 sanic.__version__ <= '0.5.4' 中不起作用,因为存在一个 Sanic 错误,但在 master 分支中已修复。
当您有 db_init 监听器时,您会遇到 导入应用程序已存在正在运行的循环。
与 pytest-cov 一起,您将获得 错误的覆盖率报告,但我们可以为此问题提供解决方案,这基本上是一个 pytest 加载插件问题。
Websockets > 4.0 在 sanic.__version__ <= '0.6.0' 中破坏了 websockets,但在 此提交 中已修复。
如果您有任何问题,请随时创建问题。您也可以查看 已关闭的问题
开发
pytest-sanic 接受 GitHub 上的贡献,形式为问题或拉取请求。
构建。
poetry install
运行单元测试。
poetry run pytest ./tests --cov pytest_sanic
参考
一些有用的 pytest 插件
项目详情
下载文件
下载您平台所需的文件。如果您不确定该选择哪个,请了解有关安装包的更多信息。