python - Flask 测试 - 从蓝图动态测试所有受保护的路由
问题描述
我想测试来自蓝图的所有路由都受登录所需装饰器的保护。
重点是:如果开发人员添加了一条新路由并忘记添加此装饰器,我希望我的测试能够自动发现该缺陷。
为了做到这一点,我想循环遍历所有路线和方法
for rule in app.url_map.iter_rules():
if rule.endpoint.startswith("my_blueprint"):
response = app.test_client().get(rule)
assert response.status_code == 401
如您所见,我必须像这样指定方法(get、post..)app.test_client().get(rule)
。
有没有更动态的方式来调用这些方法?
解决方案
发现功能
def blueprint_site_map(app, blueprint, all_methods=False):
'''
utilizes Flask's built-in rule mapper to generate a
site-map of the application, returning a list of dicts, ex.
{
'endpoint' : repr(Blueprint)
'methods' : list
'rule' : /route
{
'''
reply = []
rules = list(app.url_map.iter_rules())
ignored_methods = set(() if all_methods else ('HEAD', 'OPTIONS'))
rule_methods = [','.join(sorted(rule.methods - ignored_methods)) for rule in rules]
for rule, methods in zip(rules, rule_methods):
if (rule.endpoint != 'static') and (rule.endpoint.startswith(blueprint)):
reply.append(dict(endpoint=rule.endpoint, methods=methods.split(','), rule=rule.rule))
return reply
样本输出
>>> blueprint_site_map(app, 'my_blueprint')
[
{
'endpoint': 'my_blueprint.foo',
'methods': ['GET', 'POST'],
'rule': '/auth/foo'
},
{
'endpoint': 'my_blueprint.bar',
'methods': ['DELETE', 'GET', 'POST'],
'rule': '/auth/bar'
}
]
用法
def test_my_blueprint_is_protected(client):
from flask import current_app as app
obj = blueprint_site_map(app, 'my_blueprint')
for each in obj:
for method in each['methods']:
func = getattr(client, method)
url = each['rule'] # *see note
kwargs = {} # inject headers, etc if needed
response = func(url, **kwargs)
assert response.status_code == 401
应该注意的是,如果您使用任何参数化的 URL 规则,例如允许两者/foo
,/foo/<string:s>
那么您将需要手动模板化或过滤掉这些规则。该blueprint_site_map
函数将包含单独的列表元素/foo
和/foo/<string:s>
,从字面上看会导致测试客户端本身或您的路由逻辑出现问题。
发现功能的设计方式是,您可以根据需要将此约定用于尽可能多的不同蓝图,就您使用蓝图约定的本质而言,这意味着您可以保持单元测试与应用程序一样模块化。
干杯!
推荐阅读
- python - Azure DevOps 管道不理解 flake8 忽略列表
- php - 根据条件更改颜色的列内容
- c# - 当前日期的 DateTimeOffSet 用法
- rust - 错误[E0433]:无法解决:使用未声明的板条箱或模块
- java - 使用 Spring KafkaStreams 组合来自两个主题的数据
- c# - 在 Swagger .NET Framework 4.7(非核心)中包含 System.Web.Mvc.Controller
- c++ - 更改 CDockablePane 上的标题按钮大小
- c# - 在 C# 中更改 DataGridView 中的日期格式
- java - 使用 prometheus jmx 导出器缺少 JVM 指标
- tensorflow.js - TensorFlow.js 模型转换器冻结模型无法识别的参数