How to send post data to flask using pytest-flask

stories2 picture stories2 · Aug 16, 2017 · Viewed 11.3k times · Source

Project setting

  • Python 3.5.3
  • flask 0.12.2

Directory

.
├── Core
│   ├── BackgroundProcessManager.py
│   ├── FirebaseDatabaseManager.py
│   ├── LearningManager.py
│   ├── __init__.py
│  
├── FrontEnd
│   ├── HomePage.py
│   ├── __init__.py
│  
├── LICENSE
├── README.md
├── Route
│   ├── RouteManager.py
│   ├── __init__.py
│  
├── Settings
│   ├── DefineManager.py
│   ├── __init__.py
│   
├── Utils
│   ├── LoggingManager.py
│   ├── __init__.py
│   
├── index.py
└── runner.sh

Expected behavior

  • All the route link is in Route/RouteManager.py

  • Flask main source is in index.py

  • I want send fake request and test response using pytest-flask.

Actual behavior

  • I don't know how to send fake post data and testing.

Source

index.py

from flask import Flask
from Settings import DefineManager
from Route import *
import imp
import sys

imp.reload(sys)

app = Flask(__name__)
app.register_blueprint(routes)

if __name__ == '__main__':
    app.debug = True
    app.run(host=DefineManager.SERVER_USING_HOST, port=DefineManager.SERVER_USING_PORT)

Route/RouteManager.py

@routes.route("/")
def IndexPage():
    LoggingManager.PrintLogMessage("RouteManager", "IndexPage", "web page connection!", DefineManager.LOG_LEVEL_INFO)
    return HomePage.RenderIndexPage()

@routes.route("/upload/", methods=['POST'])
def UploadRawDatas():
    content = request.get_json(silent=True)
    LoggingManager.PrintLogMessage("RouteManager", "UploadRawDatas", "json data: " + str(content), DefineManager.LOG_LEVEL_INFO)
    return BackgroundProcessManager.UploadRawDatas(content['Data'], content['Date'], content['Day'])

@routes.route("/forecast/", methods=['POST'])
def ForecastDatas():
    content = request.get_json(silent=True)
    LoggingManager.PrintLogMessage("RouteManager", "ForecastDatas", "json data: " + str(content), DefineManager.LOG_LEVEL_INFO)
    return BackgroundProcessManager.ForecastDatas(content['ProcessId'])

Test case

/upload/

Request data

  • header

Content-Type application/json

  • body

{ "Data": [20.0, 30.0, 401.0, 50.0], "Date": ["2017-08-11", "2017-08-12", "2017-08-13", "2017-08-14"], "Day": 4 }

Response data

  • header

Content-Type application/json

  • body

    {"Result": 39}

Expect test process

  • Send fake post data.
  • Receive response data.
  • Assert check Result is not equal -1

Answer

lee-pai-long picture lee-pai-long · Aug 18, 2017

pytest-flask provide several fixtures, including a client one. With it you can make a test function similar to this:

def test_upload(client):

    mimetype = 'application/json'
    headers = {
        'Content-Type': mimetype,
        'Accept': mimetype
    }
    data = {
        'Data': [20.0, 30.0, 401.0, 50.0],
        'Date': ['2017-08-11', '2017-08-12', '2017-08-13', '2017-08-14'],
        'Day': 4
    }
    url = '/upload/'

    response = client.post(url, data=json.dumps(data), headers=headers)

    assert response.content_type == mimetype
    assert response.json['Result'] == 39