ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Sanic Testing 快速上手:使用官方测试客户端编写 API 测试

Sanic Testing 快速上手:使用官方测试客户端编写 API 测试 Sanic Testing 快速上手使用官方测试客户端编写 API 测试【免费下载链接】sanicAccelerate your web app development | Build fast. Run fast.项目地址: https://gitcode.com/gh_mirrors/sa/sanic本篇技术指南围绕 Sanic 官方测试客户端sanic-testing展开介绍其安装方式、环境要求以及如何通过app.test_client与app.asgi_client编写同步与异步测试。读完本文后你将掌握 Sanic 应用测试的基础流程、三大测试客户端的差异与适用场景并能直接参考 Sanic 项目自身 tests 目录中的真实用法落地实践。什么是 Sanic Testingsanic-testing是 Sanic 的官方测试客户端official testing client。它的首要用途是驱动 Sanic 项目自身的测试——在本仓库的 tests 目录中几乎所有功能测试都通过app.test_client发起请求例如 tests/test_app.py 中就用一个最小应用验证路由处理器内的app.loop可用性def test_app_loop_running(app: Sanic): app.get(/test) async def handler(request): assert isinstance(app.loop, asyncio.AbstractEventLoop) return text(pass) request, response app.test_client.get(/test) assert response.text pass同时它也定位为让 API 测试快速跑起来的易用客户端只要把包装进环境即可直接通过应用实例上的test_client属性发起 HTTP 调用无需额外配置。最低环境要求依赖版本要求说明Python3.7运行时环境Sanic21.3使用独立的sanic-testing包需要特别说明的是Sanic 21.3 之前的版本该测试模块直接内置在 Sanic 中即sanic.testing21.3 起才拆分为独立的sanic-testing分发包。因此如果仍在使用旧版 Sanic无需单独安装本包。安装从 PyPI 直接安装即可pip install sanic-testing安装完成后不需要任何初始化动作——只要sanic-testing在当前 Python 环境中Sanic 应用实例就会自动暴露测试客户端。这一点可以从源码得到印证在 sanic/app.py 中test_client是一个惰性求值的属性首次访问时才导入并实例化客户端property def test_client(self) - SanicTestClient: if self._test_client: return self._test_client elif self._test_manager: return self._test_manager.test_client from sanic_testing.testing import SanicTestClient # type: ignore self._test_client SanicTestClient(self) return self._test_client同理asgi_client属性sanic/app.py在首次访问时惰性创建SanicASGITestClient。这意味着不装包也能正常使用 Sanic只有访问测试客户端属性时才需要sanic-testing。编写同步测试同步测试是 Sanic 应用最常见的测试方式。使用测试客户端只需两步在 fixture 中构造Sanic应用然后在测试中访问app.test_client属性并发起请求。import pytest from sanic import Sanic, response pytest.fixture def app(): sanic_app Sanic(TestSanic) sanic_app.get(/) def basic(request): return response.text(foo) return sanic_app def test_basic_test_client(app): request, response app.test_client.get(/) assert request.method.lower() get assert response.body bfoo assert response.status 200几点值得注意调用返回的是(request, response)二元组其中request是测试客户端收到的请求对象response是应用返回的响应对象对响应可同时使用response.body字节与response.text字符串两种访问方式仓库测试中两种写法都在使用Sanic(TestSanic)的第一个参数是应用名称仓库测试夹具 tests/conftest.py 中会用测试名生成唯一应用名避免应用注册表冲突。仓库自身的测试代码还展示了更丰富的断言模式例如在 tests/test_app.py 中直接断言response.text pass、在 tests/test_blueprint_group.py 中按不同 HTTP 方法逐个调用test_client.put/post/delete/patch并传入自定义headers。编写异步测试ASGI 客户端如果你希望测试以async函数编写可以使用 ASGI 客户端app.asgi_client。由于测试函数本身是协程需要在pytest中启用异步支持pip install pytest-asyncio安装后创建异步测试即可import pytest from sanic import Sanic, response pytest.fixture def app(): sanic_app Sanic(__name__) sanic_app.get(/) def basic(request): return response.text(foo) return sanic_app pytest.mark.asyncio async def test_basic_asgi_client(app): request, response await app.asgi_client.get(/) assert request.method.lower() get assert response.body bfoo assert response.status 200与同步版本相比唯一的区别是测试函数使用pytest.mark.asyncio装饰或按pytest-asyncio的全局配置方式标记每次调用前需要await即await app.asgi_client.get(/)。注意pytest-asyncio是本仓库测试栈之外的第三方插件不属于sanic-testing的依赖需要按需自行安装。三大测试客户端及其原理结合同一目录下的进阶文档 测试客户端详解sanic-testing共提供三种客户端能力各不相同按需选用1. 同步客户端SanicTestClient真实服务器SanicTestClient会在本机网络端口上真实启动一个 Sanic Server来运行测试每次调用端点时它都会拉起一次应用实例并绑定到宿主机操作系统的某个 socket 上然后使用httpx直接对该应用发起调用。这是 Sanic 应用测试的典型方式。安装sanic-testing后即可直接使用无需额外设置也可以通过 sanic/app.py 中test_client属性的惰性导入自动获得。当然你也可以自行实例化from sanic_testing.testing import SanicTestClient test_client SanicTestClient(app) test_client.get(/path/to/endpoint)第三种方式是通过TestManager统一管理两个客户端from sanic_testing import TestManager mgr TestManager(app) app.test_client.get(/path/to/endpoint) # or mgr.test_client.get(/path/to/endpoint)2. ASGI 异步客户端SanicASGITestClient进程内执行与每次请求都拉起服务器的SanicTestClient不同SanicASGITestClient不启动真实服务器而是借助httpx将 Sanic 作为 ASGI 应用执行直接钻进应用内部运行路由处理器因此调用必须awaitawait app.test_client.get(/path/to/endpoint)它提供与SanicTestClient完全相同的方法集合与使用方式。需要澄清一个常见误解ASGI 客户端并不要求被测应用必须按 ASGI 方式运行它和同步客户端一样都能测试任意 Sanic 应用。3. 常驻服务客户端ReusableClient手动控制生命周期ReusableClient与SanicTestClient思路相近真实启动应用实例并发出真实 HTTP 请求但应用的生命周期由你控制并非每个请求都重启一个 Web Server而是启动一次、按需停止并可在同一个运行实例上连续发起多次请求。与前两个客户端不同ReusableClient必须手动实例化from sanic_testing.reusable import ReusableClient client ReusableClient(app)并且要配合上下文管理器使用——一旦离开with作用域服务器即关闭from sanic_testing.reusable import ReusableClient def test_multiple_endpoints_on_same_server(app): client ReusableClient(app) with client: _, response client.get(/path/to/1) assert response.status 200 _, response client.get(/path/to/2) assert response.status 200这一模式特别适合同一服务实例上串行验证多个端点的场景避免了SanicTestClient每个请求重启服务的开销。支持的请求方法客户端提供以下请求方法与httpx的调用习惯几乎一致SanicTestClient.getSanicTestClient.postSanicTestClient.putSanicTestClient.patchSanicTestClient.deleteSanicTestClient.optionsSanicTestClient.headSanicTestClient.websocketSanicTestClient.request使用要点一个关键提醒这些方法可以接受任何你平时传给httpx的参数。唯一的例外是——当你使用test_client.request并希望手动指定 HTTP 方法时参数名是http_method而非methodtest_client.request(/path/to/endpoint, http_methodget)与 Sanic 项目自身的测试体系sanic-testing是 Sanic 自测的基石。从本仓库 tests/conftest.py 可以看到测试基座直接从sanic_testing.testing导入PORT常量并开启Sanic.test_mode Truefrom sanic_testing.testing import PORT ... Sanic.test_mode True此外conftest.py中的portfixturetests/conftest.py通过绑定 0 端口让操作系统自动分配可用端口再配合run_startupfixturetests/conftest.py以app.create_server(portPORT)的方式做启动类测试——这些模式都可以直接迁移到你自己的测试工程中。整个 tests 目录如test_app.py、test_blueprints.py、test_middleware.py、test_request.py等几乎都通过app.test_client发起请求是学习 Sanic Testing 各种用法的最佳活教材。官方测试实战指南还可参考 测试最佳实践。小结环境就绪后Python 3.7、Sanic 21.3pip install sanic-testing即可开箱即用同步测试走app.test_client异步测试走await app.asgi_client需pytest-asyncio三种客户端各有所长SanicTestClient每次请求拉起真实服务器、SanicASGITestClient在进程内按 ASGI 执行、ReusableClient常驻服务手动控制生命周期请求方法兼容httpx参数仅在request方法中用手动指定方法时需使用http_method参数想深入了解三种客户端的更多细节可继续阅读 测试客户端详解。【免费下载链接】sanicAccelerate your web app development | Build fast. Run fast.项目地址: https://gitcode.com/gh_mirrors/sa/sanic创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表