繁体   English   中英

如何将集成测试应用于 Flask RESTful API

[英]How to apply integration tests to a Flask RESTful API

[根据https://stackoverflow.com/a/46369945/1021819 ,标题应该指的是集成测试而不是单元测试]

假设我想测试以下 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)

将其保存为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定义)类,我还没有弄清楚如何断言 JSON 响应符合预期(即{'hello': 'world'} )。 这是因为它是flask.wrappers.Response一个实例(它可能本质上是一个 Werkzeug Response 对象(参见http://werkzeug.pocoo.org/docs/0.11/wrappers/ )),我还没有能够为requests Response对象找到等效的json()方法。

如何对第二个response的 JSON 内容进行断言?

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>

烧瓶测试文档

我发现我可以通过将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]

你在那里做的不是单元测试。 在每种情况下,在使用请求库或 Flask 客户端时,您都是在对端点进行实际 http 调用并测试交互时进行集成测试

问题的标题或方法都不准确。

使用 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'})

这个问题给出了解释。

来自test_clientresponse对象有一个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"},
        )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM