Flask单元测试:获取响应的重定向位置

Mic*_*ler 14 python werkzeug flask python-unittest

我有一个基于Flask的webapp,当以某种方式发布到他们的父文档时偶尔会创建带有新随机密钥的新文档.新密钥进入父级的数据结构,更新的父级临时存储在会话中,并且在成功保存子文档后,存储的父级被拉出会话并存储在一起,以便将两者链接在一起.这是针对某些类型的关系完成的,其中一个人希望在键之间具有固有顺序,因此键被存储为父项上的列表.

现在,当我想使用Werkzeug提供的单元测试客户端进行单元测试时,问题出现了.做一个

 ret = self.test_client.post(
    request_path,
    data=data,
    follow_redirects=True
)
Run Code Online (Sandbox Code Playgroud)

在测试用例对象中将成功使用新密钥重定向到子文档 - 但我不知道在单元测试中检索此新密钥的位置.我无法在返回值的顶部找到一个属性,该属性将指示它被重定向到的位置.dir(ret)给我

 ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_ensure_sequence', '_get_mimetype_params', '_on_close', '_status', '_status_code', 'accept_ranges', 'add_etag', 'age', 'allow', 'autocorrect_location_header', 'automatically_set_content_length', 'cache_control', 'calculate_content_length', 'call_on_close', 'charset', 'close', 'content_encoding', 'content_language', 'content_length', 'content_location', 'content_md5', 'content_range', 'content_type', 'data', 'date', 'default_mimetype', 'default_status', 'delete_cookie', 'direct_passthrough', 'expires', 'force_type', 'freeze', 'from_app', 'get_app_iter', 'get_data', 'get_etag', 'get_wsgi_headers', 'get_wsgi_response', 'headers', 'implicit_sequence_conversion', 'is_sequence', 'is_streamed', 'iter_encoded', 'last_modified', 'location', 'make_conditional', 'make_sequence', 'mimetype', 'mimetype_params', 'response', 'retry_after', 'set_cookie', 'set_data', 'set_etag', 'status', 'status_code', 'stream', 'vary', 'www_authenticate']
Run Code Online (Sandbox Code Playgroud)

其中,headerslocation看好-但位置没有设置和头不包含它的.

如何从响应中获取重定向的位置?我是否真的必须从响应机构解析孩子的密钥?有没有更好的方法?

Pet*_*tts 16

根据您自己的答案,根据您个人对单元测试风格的偏好,可以随意忽略,您可能更喜欢以下建议,以简化和提高单元测试的清晰度和可读性:

response = self.test_client.post(
    request_path,
    data=data,
    follow_redirects=False
)
expectedPath = '/'
self.assertEqual(response.status_code, 302)
self.assertEqual(urlparse(response.location).path, expectedPath)
Run Code Online (Sandbox Code Playgroud)

  • 注意:`urlparse().path`不仅修剪了模式和主机,还修剪了查询字符串.如果要针对带参数的路径进行测试,请不要使用它. (3认同)

Mic*_*ler 4

follow_redirects=False@bwbrowning 提供了正确的提示 - 使用返回值进行发布具有location属性集 - 这是包括参数的完整请求路径。

编辑:提示 - 执行时有一个轻微的问题test_client.get(..)- 路径参数需要是相对路径,而ret.location返回完整路径。所以,我所做的是

child_path_with_parameters = rv.location.split('http://localhost')[1]
child_path = child_path_with_parameters.split('?')[0]
ret = self.test_client.get(child_path_with_parameters)
Run Code Online (Sandbox Code Playgroud)

(稍后使用 child_path 以便发布到子进程)