0

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...

Alex
  • 41,580
  • 88
  • 260
  • 469
  • 1
    You are testing a new (empty) `app`. You have to import the real app. – Klaus D. Mar 26 '23 at 07:30
  • And how do I do that? – Alex Mar 26 '23 at 07:31
  • Use the real app that you're creating in server.py instead of creating a new one. – ndc85430 Mar 26 '23 at 07:40
  • How do I create the real app? What are the code lines? Ideally I start the backend server as one single server and use the tests on this one server (to have the same data in the backend ) – Alex Mar 26 '23 at 07:41
  • I tried to use `app = Flask(__name__) app.run('0.0.0.0', 5000, threaded=True)` before the tests but then no test is executed... – Alex Mar 26 '23 at 07:43
  • I also tried to use `app.create` but that does not seem to exist... – Alex Mar 26 '23 at 07:45
  • https://stackoverflow.com/questions/17375340/testing-code-that-requires-a-flask-app-or-request-context – Julian Camilleri Mar 26 '23 at 08:30
  • Does this answer your question? [Testing code that requires a Flask app or request context](https://stackoverflow.com/questions/17375340/testing-code-that-requires-a-flask-app-or-request-context) – Julian Camilleri Mar 26 '23 at 08:30

2 Answers2

2

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!

Julian Camilleri
  • 2,975
  • 1
  • 25
  • 34
  • Thanks for the explicit example, but when running this I get a 500 Server error... (I created the test file with the application definition in a single file) – Alex Mar 26 '23 at 08:43
-1

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!

Alex
  • 41,580
  • 88
  • 260
  • 469
  • `flask` provides you with what is needed to test an application. - You don't have to do that. – Julian Camilleri Mar 26 '23 at 08:26
  • But nobody seems to know how. I am totally satisfied with my solution. It does not interfere with the server at all and I know exactly what is going on. – Alex Mar 26 '23 at 08:30
  • You need context - I've left a comment in the question above - have a look there. - Once you provide context to the request you're doing, it should work just fine (: – Julian Camilleri Mar 26 '23 at 08:31
  • Don't create a new app - import your original app from your setup. – Julian Camilleri Mar 26 '23 at 08:35
  • from server import app app.test.......... – Julian Camilleri Mar 26 '23 at 08:35
  • I tried the linked solution but I get a 500 server error. My solution still works! Why would I use a more complicated, hard-to-use solution? – Alex Mar 26 '23 at 08:37
  • I do not know what you mean by "importing the original(?) app from your setup". I have no idea ehat you mean by that! Does not make sense to me as the python startup script neither is a library nor a module I can import stuff frrom. – Alex Mar 26 '23 at 08:38
  • It's not complicated - I overlooked the fact that you're creating a new app and not importing the original app - thats your issue 99.9%. - should be as simple as importing the original app. – Julian Camilleri Mar 26 '23 at 08:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252784/discussion-between-alex-and-julian-camilleri). – Alex Mar 26 '23 at 08:39