kevinmmartins / python-flask-connexion-example-openapi3

Basic REST project with Flask , Connexion by Zalando , OpenApi3, Docker and tox
Apache License 2.0
10 stars 5 forks source link

Tox tests fail in Python version 3.9 #79

Open chrisinmtown opened 2 weeks ago

chrisinmtown commented 2 weeks ago

Thank you very much for providing this minimal Connexion V3 project, especially the tox tests! I am trying to learn from your example. I don't have Python 3.6, instead I created a venv with 3.9. I changed the tox.ini envlist entry from 3.6 to 3.9 then ran tox. The result was a complaint from coverage, possibly the "test" argument is no longer valid. Would you please update?

I'm not sure of the best practice, it helped me to add tox to the test-requirements.txt file, please consider.

Here's partial output from tox showing the error:

/Users/me/git/github/python-flask-connexion-example-openapi3/.tox/py39/lib/python3.9/site-packages/coverage/control.py:892: CoverageWarning: No data was collected. (no-data-collected)
  self._warn("No data was collected.", slug="no-data-collected")
usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
   or: setup.py --help [cmd1 cmd2 ...]
   or: setup.py --help-commands
   or: setup.py cmd --help

error: invalid command 'test'
py39: exit 1 (1.83 seconds) /Users/me/git/github/python-flask-connexion-example-openapi3> coverage run --source=./basic '--omit=*/test*' -a setup.py test pid=46991
py39: FAIL ✖ in 14.21 seconds
chrisinmtown commented 2 weeks ago

I made an attempt at updating tox.ini, to upgrade from python3.6 to 3.9 and update the coverage invocation also. Here's the diff:

**diff --git a/tox.ini b/tox.ini
index 39fc782..0751e28 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,6 @@
 [tox]
 envlist =
-    clean, py36, stats
+    clean, py39, stats

 [testenv]
 deps =
@@ -8,7 +8,8 @@ deps =
     -r{toxinidir}/test-requirements.txt

 commands=
-    coverage run --source=./basic --omit="*/test*" -a setup.py test
+    coverage run -m pytest {posargs}
+    coverage report -a

 [testenv:clean]
 commands=

I also added pytest to the test-requirements.txt file. With those changes in place, tox runs tests as expected, but the test apparently fails to reach the Connexion/Flask server. Here's most of the error message:

self = <basic.tests.test_alive_controller.BaseTestAliveController testMethod=test_get_alive>

    def test_get_alive(self):
>       response = self.client.open("/v1/basic/ping", method="GET")

basic/tests/test_alive_controller.py:10: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/py39/lib/python3.9/site-packages/flask/testing.py:235: in open
    response = super().open(
.tox/py39/lib/python3.9/site-packages/werkzeug/test.py:1116: in open
    response_parts = self.run_wsgi_app(request.environ, buffered=buffered)
.tox/py39/lib/python3.9/site-packages/werkzeug/test.py:988: in run_wsgi_app
    rv = run_wsgi_app(self.application, environ, buffered=buffered)
.tox/py39/lib/python3.9/site-packages/werkzeug/test.py:1264: in run_wsgi_app
    app_rv = app(environ, start_response)
.tox/py39/lib/python3.9/site-packages/flask/app.py:1498: in __call__
    return self.wsgi_app(environ, start_response)
.tox/py39/lib/python3.9/site-packages/flask/app.py:1476: in wsgi_app
    response = self.handle_exception(e)
.tox/py39/lib/python3.9/site-packages/flask_cors/extension.py:178: in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
.tox/py39/lib/python3.9/site-packages/flask/app.py:1473: in wsgi_app
    response = self.full_dispatch_request()
.tox/py39/lib/python3.9/site-packages/flask/app.py:882: in full_dispatch_request
    rv = self.handle_user_exception(e)
.tox/py39/lib/python3.9/site-packages/flask_cors/extension.py:178: in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
.tox/py39/lib/python3.9/site-packages/flask/app.py:772: in handle_user_exception
    return self.ensure_sync(handler)(e)  # type: ignore[no-any-return]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <connexion.apps.flask.FlaskApp object at 0x103aee070>, exc = <NotFound '404: Not Found'>

    def _http_exception(self, exc: werkzeug.exceptions.HTTPException):
        """Reraise werkzeug HTTPExceptions as starlette HTTPExceptions"""
>       raise starlette.exceptions.HTTPException(exc.code, detail=exc.description)
E       starlette.exceptions.HTTPException: 404: The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.

.tox/py39/lib/python3.9/site-packages/connexion/apps/flask.py:245: HTTPException

I can work up a tiny PR for the tox etc. changes, if you would consider it, but I'm not sure how to clear this next error.

chrisinmtown commented 2 weeks ago

I finally found this section of the Connexion doc: https://connexion.readthedocs.io/en/latest/testing.html

I think this teaches that tests need to create a /Connexion/ test client, not a /Flask/ test client.

chrisinmtown commented 2 weeks ago

I extended test_alive_controller.py with the following, ran tox and shock! it passed :)

from basic import init_api

def test_homepage():
    conn_app = init_api()
    with conn_app.test_client() as c:
        response = c.get("/v1/basic/ping")
        assert response.status_code == 200