Python 如何将集成测试(而不是单元测试)应用于 Flask RESTful API
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41718376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to apply integration tests (rather than unit tests) to a Flask RESTful API
提问by Kurt Peek
[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'}
). 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
Responseobject.
两个测试都通过了,但是对于第二个测试(在 中定义TestFlaskApi
),我还没有弄清楚如何断言 JSON 响应符合预期(即{'hello': 'world'}
)。这是因为它是flask.wrappers.Response
(可能本质上是一个 Werkzeug Response 对象(参见http://werkzeug.pocoo.org/docs/0.11/wrappers/))的一个实例,我一直无法找到等效的Response对象的json()
方法。requests
How can I make assertions on the JSON content of the second response
?
如何对第二个 JSON 内容进行断言response
?
回答by TheGrimmScientist
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>
回答by Kurt Peek
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]
回答by Luisa Emme
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 testingas 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.
问题的标题或方法都不准确。
回答by pylipp
With Python3, I got the error TypeError: the JSON object must be str, not bytes
. It is required to decode:
使用 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 questiongives an explanation.
这个问题给出了解释。