我正在使用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'
当某些断言失败时,我会得到类似的东西:
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 ===================
我做了很多TDD,所以我希望我的测试在开发过程中经常失败。我的问题是断言错误消息没有其他响应数据(正文,标题等)是没用的。
我只在输出中得到response.status_code为400但我没有得到响应正文中的错误描述:{"errors": ["username is already taken", "email is required"]}
。理想情况下,当断言失败时,我希望完整转储请求和响应(标题+正文)。
如何在每个失败的断言上打印响应摘要?
答案 0 :(得分:0)
assert response.status_code == 201, "Anything you want"
你可以像你想要的那样冗长。你也可以使用UnitTest的helper methods套件 - 没有测试用例类通过这一点滥用 - https://github.com/nose-devs/nose2/blob/master/nose2/tools/such.py#L34
答案 1 :(得分:0)
我想出了两种不同的解决方案。
解决方案#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,)
解决方案#2:不需要尝试/捕获(如果repr太长,有时会被切断......)
扩展并覆盖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)
和
@pytest.fixture(scope='session')
def test_client(flask_app):
flask_app.response_class = JSONResponse
return flask_app.test_client()
答案 2 :(得分:0)
我知道这是一个较旧的问题,但是Pytest有一个选项--pdb
,如果测试失败,该选项将使您跳入PDB Shell。一种非常方便的“四处浏览”的方法,而不必将大量的内容传递给异常消息。