[英]How to apply integration tests to a Flask RESTful API
[As per https://stackoverflow.com/a/46369945/1021819 , the title should refer to integration tests rather than unit tests] [根据https://stackoverflow.com/a/46369945/1021819 ,标题应该指的是集成测试而不是单元测试]
Suppose I'd like to test the following Flask API (from here ):假设我想测试以下 Flask API(来自此处):
import flask
import flask_restful
app = flask.Flask(__name__)
api = flask_restful.Api(app)
class HelloWorld(flask_restful.Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == "__main__":
app.run(debug=True)
Having saved this as flaskapi.py
and run it, in the same directory I run the script test_flaskapi.py
:将其保存为
flaskapi.py
并运行它后,在同一目录中我运行脚本test_flaskapi.py
:
import unittest
import flaskapi
import requests
class TestFlaskApiUsingRequests(unittest.TestCase):
def test_hello_world(self):
response = requests.get('http://localhost:5000')
self.assertEqual(response.json(), {'hello': 'world'})
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get('/')
if __name__ == "__main__":
unittest.main()
Both the tests pass, but for the second test (defined in the TestFlaskApi
) class I haven't yet figured out how to assert that the JSON response is as expected (namely, {'hello': 'world'}
).两个测试都通过了,但是对于第二个测试(在
TestFlaskApi
定义)类,我还没有弄清楚如何断言 JSON 响应符合预期(即{'hello': 'world'}
)。 This is because it is an instance of flask.wrappers.Response
(which is probably essentially a Werkzeug Response object (cf. http://werkzeug.pocoo.org/docs/0.11/wrappers/ )), and I haven't been able to find an equivalent of the json()
method for requests
Response object.这是因为它是
flask.wrappers.Response
一个实例(它可能本质上是一个 Werkzeug Response 对象(参见http://werkzeug.pocoo.org/docs/0.11/wrappers/ )),我还没有能够为requests
Response对象找到等效的json()
方法。
How can I make assertions on the JSON content of the second response
?如何对第二个
response
的 JSON 内容进行断言?
Flask provides a test_client you can use in your tests: Flask 提供了一个 test_client 可以在你的测试中使用:
from source.api import app
from unittest import TestCase
class TestIntegrations(TestCase):
def setUp(self):
self.app = app.test_client()
def test_thing(self):
response = self.app.get('/')
assert <make your assertion here>
I've found that I can get the JSON data by applying json.loads()
to the output of the get_data()
method:我发现我可以通过将
json.loads()
应用于get_data()
方法的输出来获取 JSON 数据:
import unittest
import flaskapi
import requests
import json
import sys
class TestFlaskApiUsingRequests(unittest.TestCase):
def test_hello_world(self):
response = requests.get('http://localhost:5000')
self.assertEqual(response.json(), {'hello': 'world'})
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get('/')
self.assertEqual(
json.loads(response.get_data().decode(sys.getdefaultencoding())),
{'hello': 'world'}
)
if __name__ == "__main__":
unittest.main()
Both tests pass as desired:两项测试均按预期通过:
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s
OK
[Finished in 0.3s]
What you're doing there is not unit testing.你在那里做的不是单元测试。 In every case, when using the requests library or the flask client, you're doing integration testing as you make actual http calls to the endpoints and test the interaction.
在每种情况下,在使用请求库或 Flask 客户端时,您都是在对端点进行实际 http 调用并测试交互时进行集成测试。
Either the title of the question or the approach is not accurate.问题的标题或方法都不准确。
With Python3, I got the error TypeError: the JSON object must be str, not bytes
.使用 Python3,我收到错误
TypeError: the JSON object must be str, not bytes
。 It is required to decode:需要解码:
# in TestFlaskApi.test_hello_world
self.assertEqual(json.loads(response.get_data().decode()), {'hello': 'world'})
This question gives an explanation. 这个问题给出了解释。
The response
object from test_client
has a get_json
method.来自
test_client
的response
对象有一个get_json
方法。
There's no need for converting the response to json with json.loads
.无需使用
json.loads
将响应转换为 json。
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get("/")
self.assertEqual(
response.get_json(),
{"hello": "world"},
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.