How to test the python backend of a flask application?
Question:
I have a draft of a flask application with a html/javascript frontend and a python backend, to which the frontend communicates through the flask API.
I want to test the python backend using the API using python only (no javascript etc involved in the testing). I found this page with some suggestion but I guess something is missing.
I have tried the following test code in tests/test1.py
:
from flask import Flask
app = Flask(__name__)
def test_1():
"""Example test"""
response = app.test_client().get('/')
print(response)
but the response returns a 404 error. I usually start the web server with flask run --host 0.0.0.0
using this server.py
script:
import sys
import json
from flask import Flask, request, render_template
app = Flask(__name__)
from mf import gameplay
game = gameplay.Game()
@app.route('/')
def index():
return render_template('mainmap.html')
@app.route('/api', methods=['POST'])
def api():
data_json = request.data.decode()
data = json.loads(data_json)
return game(data_json)
if __name__ == '__main__':
app.run('0.0.0.0', 5000, threaded=True)
I guess I am missing something to start the test?
I found some examples HERE and HERE that use something like
flask_app = create_app('flask_test.cfg')
but 1. flask
does not have a method create_app
and 2. what is the content of the config file (even not shown on the documentation of flask itself: HERE …???)? I did not find one example…
Answers:
Forget flask
for these tests! You start the server as usual, and then in your test code you make request
calls like
import json, requests
r = requests.post('http://192.168.1.28:5000/api', data=json.dumps(data))
with whatever data (defined as a python dict). The URL is as defined in your python flask start script (the http
is important, and no not end the path with a slash ("/")), and api
is the interface you also define in the python flask start script.
Now you can make tests with a single running instance of your flask server!
You’re creating a new application in your test module – meaning that you have no registered endpoints.
You’ll need to import the app
created in your server
module.
from your_package.server import app
and use that as you’re currently doing.
Ideally your server.py and your app.py are separate – meaning you have app.py with your app configuration and server.py imports the app required, and tests import the app required, so on and so forth.
Example:
application.py
import sys
import json
from flask import Flask, request, render_template
app = Flask(__name__)
from mf import gameplay
game = gameplay.Game()
@app.route('/')
def index():
return render_template('mainmap.html')
@app.route('/api', methods=['POST'])
def api():
data_json = request.data.decode()
data = json.loads(data_json)
return game(data_json)
server.py
from application import app
app.run('0.0.0.0', 5000, threaded=True)
test.py
from application import app
def test_1():
"""Example test"""
with app.test_client() as client:
response = client.get('/')
print(response)
That should work!
I have a draft of a flask application with a html/javascript frontend and a python backend, to which the frontend communicates through the flask API.
I want to test the python backend using the API using python only (no javascript etc involved in the testing). I found this page with some suggestion but I guess something is missing.
I have tried the following test code in tests/test1.py
:
from flask import Flask
app = Flask(__name__)
def test_1():
"""Example test"""
response = app.test_client().get('/')
print(response)
but the response returns a 404 error. I usually start the web server with flask run --host 0.0.0.0
using this server.py
script:
import sys
import json
from flask import Flask, request, render_template
app = Flask(__name__)
from mf import gameplay
game = gameplay.Game()
@app.route('/')
def index():
return render_template('mainmap.html')
@app.route('/api', methods=['POST'])
def api():
data_json = request.data.decode()
data = json.loads(data_json)
return game(data_json)
if __name__ == '__main__':
app.run('0.0.0.0', 5000, threaded=True)
I guess I am missing something to start the test?
I found some examples HERE and HERE that use something like
flask_app = create_app('flask_test.cfg')
but 1. flask
does not have a method create_app
and 2. what is the content of the config file (even not shown on the documentation of flask itself: HERE …???)? I did not find one example…
Forget flask
for these tests! You start the server as usual, and then in your test code you make request
calls like
import json, requests
r = requests.post('http://192.168.1.28:5000/api', data=json.dumps(data))
with whatever data (defined as a python dict). The URL is as defined in your python flask start script (the http
is important, and no not end the path with a slash ("/")), and api
is the interface you also define in the python flask start script.
Now you can make tests with a single running instance of your flask server!
You’re creating a new application in your test module – meaning that you have no registered endpoints.
You’ll need to import the app
created in your server
module.
from your_package.server import app
and use that as you’re currently doing.
Ideally your server.py and your app.py are separate – meaning you have app.py with your app configuration and server.py imports the app required, and tests import the app required, so on and so forth.
Example:
application.py
import sys
import json
from flask import Flask, request, render_template
app = Flask(__name__)
from mf import gameplay
game = gameplay.Game()
@app.route('/')
def index():
return render_template('mainmap.html')
@app.route('/api', methods=['POST'])
def api():
data_json = request.data.decode()
data = json.loads(data_json)
return game(data_json)
server.py
from application import app
app.run('0.0.0.0', 5000, threaded=True)
test.py
from application import app
def test_1():
"""Example test"""
with app.test_client() as client:
response = client.get('/')
print(response)
That should work!