![](/img/trans.png)
[英]Testing a Flask app with pytest-flask + pytest-selenium (docker)
[英]Preserve response context testing flask app with pytest
我正在使用 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"]}
。 理想情況下,我希望在斷言失敗時完整轉儲請求和響應(標頭 + 正文)。
如何打印每個失敗斷言的響應摘要?
assert response.status_code == 201, "Anything you want"
您可以隨心所欲地詳細說明。 您還可以使用 UnitTest 的輔助方法套件 - 通過這種濫用而無需測試用例類 - https://github.com/nose-devs/nose2/blob/master/nose2/tools/such.py#L34
我想出了兩種不同的解決方案。
解決方案#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:不需要 try/catch(如果 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()
我知道這是一個較舊的問題,但 Pytest 有一個選項--pdb
,如果您的測試失敗,它會將您彈出到 PDB shell。 “環顧四周”的非常方便的方法,而不必將大量內容傳遞給異常消息。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.