一尘不染

如何将集成测试(而非单元测试)应用于Flask RESTful API

flask

假设我想测试以下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响应对象(请参阅http://werkzeug.pocoo.org/docs/0.11/wrappers/)),但是我找不到等效的对象响应对象的json()方法。requests

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


阅读 484

收藏
2020-04-06

共2个答案

一尘不染

我发现可以将JSON数据应用于方法json.loads()的输出get_data()

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]
2020-04-06
一尘不染

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>
2020-04-06