首页 文章

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

提问于
浏览
19

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

假设我想测试以下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 中定义),我还没有想出如何断言JSON响应是否符合预期(即 {'hello': 'world'} ) . 这是因为它是 flask.wrappers.Response 的实例(可能本质上是一个Werkzeug响应对象(参见http://werkzeug.pocoo.org/docs/0.11/wrappers/)),而且我无法找到 requests Response对象的 json() 方法的等价物 .

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

4 回答

  • 27

    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 Testing Docs

  • 22

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

    当你对 endpoints 进行实际的http调用并测试交互时,你做了什么integration testing .

    问题的 Headers 或方法都不准确 .

  • 17

    使用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给出了解释 .

相关问题