I'm currently in the process of writing acceptance tests for a connexion based API in Flask. As a Flask user i'm used to test stuff with py.test and the pip modules: pytest-flask and / or Flask_Testing
Both have helpers to provide some config and start a live server when needed. This doesn't seem to work with the Flask app created by Connexion. This also makes it nearly impossible to use Flask's config system and the url_for() methods.
Is there a way to use the testing plugins or to create a more Flask compliant app?
Possibly related to #489 and #364
This is how I use it now:
I added a construction to the place where the app is inited, so that it can return a flask app when needed, something like:
def run(actually_run=True):
app = connexion.App(__name__, specification_dir='./swagger/')
api = app.add_api(swagger_file)
if actually_run:
app.run(host=HOST, port=PORT, ...)
else:
return app.app
Then a live server can be started from tests that need it:
import requests
from flask_testing import LiveServerTestCase
from main import run_application
class MyTest(LiveServerTestCase):
def create_app(self):
app = run(False)
return app
def test_server_is_up_and_running(self):
response = requests.get(f"{self.get_server_url()}/an_endpoint_for_your_api")
self.assertEqual(response.status_code, 200)
I had a good experience using the WebTest library in the past (pip install webtest): https://docs.pylonsproject.org/projects/webtest/en/latest/
It will test your application on WSGI level which has some benefits:
connexion/Flask and keep working if you decide to go for the gevent or tornado or any other WSGI-compatible backend in the future.The documentation of WebTest is quite extensive and covers all major use cases. A quick example to get started:
from webtest import TestApp
import unittest
from main import app # the connexion Flask app object
class TestEndpoints(unittest.TestCase):
# could also be set up globally outside of this class
@classmethod
def setUpClass(cls):
cls.app = TestApp(app)
def test_some_endpoint(self):
response = self.app.get('/some/endpoint').json()
expected_response = dict(foo='bar', baz='buz')
self.assertDictEqual(response, expected_response)
are there any updates on writing unit tests for controllers?
I found this repo immensely helpful for getting going with testing connexion: https://github.com/hirose31/connexion-tiny-petstore
(it also uses WebTest, as recommended by @dirkschneemann)
There may be a way to get testing working with using flask's internal test client. I have created a PR showing it as an example: #957
Let me know what you think, or if I am missing something that you are looking for.
Most helpful comment
I had a good experience using the
WebTestlibrary in the past (pip install webtest): https://docs.pylonsproject.org/projects/webtest/en/latest/It will test your application on WSGI level which has some benefits:
connexion/Flaskand keep working if you decide to go for thegeventortornadoor any other WSGI-compatible backend in the future.The documentation of
WebTestis quite extensive and covers all major use cases. A quick example to get started: