如何将集成测试应用于 Flask RESTful API
How to apply integration tests to a Flask RESTful API
[根据 ,标题应指集成测试而不是单元测试]
假设我想测试以下 Flask API(来自 here):
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)
将其保存为 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()
两个测试都通过了,但是对于第二个测试(在TestFlaskApi
中定义)class我还没有想出如何断言JSON响应是预期(即 {'hello': 'world'}
)。这是因为它是 flask.wrappers.Response
的一个实例(这可能本质上是一个 Werkzeug 响应 object (参见 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.
如何对第二个 response
的 JSON 内容进行断言?
我发现我可以通过将 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()
两项测试均按预期通过:
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s
OK
[Finished in 0.3s]
使用 Python3,我得到了错误 TypeError: the JSON object must be str, not bytes
。需要解码:
# in TestFlaskApi.test_hello_world
self.assertEqual(json.loads(response.get_data().decode()), {'hello': 'world'})
This question给出解释
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>
你在那里做的不是单元测试。在每种情况下,当使用请求库或 Flask 客户端时,您都在 integration testing 对端点进行实际的 http 调用并测试交互。
问题的标题或方法不准确。
来自 test_client
的 response
对象有一个 get_json
方法。
无需使用 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"},
)
[根据
假设我想测试以下 Flask API(来自 here):
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)
将其保存为 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()
两个测试都通过了,但是对于第二个测试(在TestFlaskApi
中定义)class我还没有想出如何断言JSON响应是预期(即 {'hello': 'world'}
)。这是因为它是 flask.wrappers.Response
的一个实例(这可能本质上是一个 Werkzeug 响应 object (参见 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.
如何对第二个 response
的 JSON 内容进行断言?
我发现我可以通过将 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()
两项测试均按预期通过:
..
----------------------------------------------------------------------
Ran 2 tests in 0.019s
OK
[Finished in 0.3s]
使用 Python3,我得到了错误 TypeError: the JSON object must be str, not bytes
。需要解码:
# in TestFlaskApi.test_hello_world
self.assertEqual(json.loads(response.get_data().decode()), {'hello': 'world'})
This question给出解释
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>
你在那里做的不是单元测试。在每种情况下,当使用请求库或 Flask 客户端时,您都在 integration testing 对端点进行实际的 http 调用并测试交互。
问题的标题或方法不准确。
来自 test_client
的 response
对象有一个 get_json
方法。
无需使用 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"},
)