2017-01-18 11 views
8

Предположим, что я хотел бы проверить следующее КОЛБУ API (от http://flask-restful-cn.readthedocs.io/en/0.3.5/quickstart.html#a-minimal-api):Как модульного тестирования Колбу, RESTful 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/)), и я не смог найти эквивалент метода json() для объекта requests 'Response.

Как я могу сделать утверждения о содержании JSON второго response?

ответ

8

Я обнаружил, что я могу получить данные в формате 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] 
+0

«Статус: API фляжки в настоящее время не находится в активной разработке». от https://github.com/flask-api/flask-api – TheGrimmScientist

2

С 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 дает объяснение.

8

колба обеспечивает 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

+0

(Добавлено как ответ, чтобы помочь другим, приземляющимся здесь, увидеть более чистый способ написать эти тесты) – TheGrimmScientist

+0

Чистота и консистентность. – Prakhar

7

Что вы там делаете это не модульное тестирование. В каждом случае, когда вы используете библиотеку запросов или клиентский флажок, вы делаете integration testing, когда вы делаете фактические http-звонки на конечные точки и проверяете взаимодействие.

Либо название вопроса, либо подход неточно.