[英]Preserve response context testing flask app with pytest
I'm testing a flask application with py.test with the following code:我正在使用 py.test 使用以下代码测试烧瓶应用程序:
response = flask_app_test_client.post('/users', data=json.dumps(user))
assert response.status_code == 201
assert response.content_type == 'application/json'
assert isinstance(response.json, dict)
assert set(response.json.keys()) >= {'id', 'status', 'created_at', 'updated_at'}
assert response.json['name'] == user['name']
assert response.json['status'] == 'pending'
When some assertion fails I'm getting something like this:当某些断言失败时,我会得到这样的信息:
response = test_client.post('/users', data=json.dumps(user))
> assert response.status_code == 201
E assert 400 == 201
E + where 400 = <JSONResponse streamed [400 BAD REQUEST]>.status_code
============== 1 failed, 3 passed in 0.10 seconds ===================
I do a lot of TDD so I expect my test fails frequently while developing.我做了很多 TDD,所以我希望我的测试在开发过程中经常失败。 My problem is the assertion error message is kind of useless without the rest of the response data (body, headers, etc).
我的问题是断言错误消息在没有其余响应数据(正文、标题等)的情况下毫无用处。
I only get in the output that the response.status_code is 400 but I don't get the error description that is in the response body: {"errors": ["username is already taken", "email is required"]}
.我只得到 response.status_code 为 400 的输出,但我没有得到响应正文中的错误描述:
{"errors": ["username is already taken", "email is required"]}
。 Ideally I would like a full dump of the request and response (headers + body) when an assertion fails.理想情况下,我希望在断言失败时完整转储请求和响应(标头 + 正文)。
How I can print a summary of the response on each failed assertion?如何打印每个失败断言的响应摘要?
Assert statement graamar 断言语句语法
assert response.status_code == 201, "Anything you want"
You can be as verbose as you want.您可以随心所欲地详细说明。 You can also use UnitTest's suite of helper methods - without test case classes through this bit of abuse - https://github.com/nose-devs/nose2/blob/master/nose2/tools/such.py#L34
您还可以使用 UnitTest 的辅助方法套件 - 通过这种滥用而无需测试用例类 - https://github.com/nose-devs/nose2/blob/master/nose2/tools/such.py#L34
I'm came up with two different solutions.我想出了两种不同的解决方案。
Solution #1: try/catch解决方案#1:尝试/捕获
try:
assert response.status_code == 201
assert response.content_type == 'application/json'
assert isinstance(response.json, dict)
assert set(response.json.keys()) >= {'id', 'status', 'created_at', 'updated_at'}
assert response.json['name'] == user['name']
assert response.json['status'] == 'pending'
except AssertionError as e:
except AssertionError as e:
raise ResponseAssertionError(e, response)
class ResponseAssertionError(AssertionError):
def __init__(self, e, response):
response_dump = "\n + where full response was:\n" \
"HTTP/1.1 {}\n" \
"{}{}\n".format(response.status, response.headers, response.json)
self.args = (e.args[0] + response_dump,)
Solution #2: no try/catch needed (if repr is too long sometimes is cut off...)解决方案#2:不需要 try/catch(如果 repr 太长有时会被切断......)
Extend and override Flask response object扩展和覆盖 Flask 响应对象
import json
class JSONResponse(Response):
def __repr__(self):
headers = {}
while len(self.headers) > 0:
tuple_ = self.headers.popitem()
headers[tuple_[0]] = tuple_[1]
data = {
'status': self.status,
'headers': headers,
'body': self.json
}
return json.dumps(data)
and和
@pytest.fixture(scope='session')
def test_client(flask_app):
flask_app.response_class = JSONResponse
return flask_app.test_client()
I know this is an older question, but Pytest has an option --pdb
that will pop you into a PDB shell should your test fail.我知道这是一个较旧的问题,但 Pytest 有一个选项
--pdb
,如果您的测试失败,它会将您弹出到 PDB shell。 Very handy way to "just look around" rather than having to pass tons of stuff to an exception message. “环顾四周”的非常方便的方法,而不必将大量内容传递给异常消息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.