pallets / flask

The Python micro framework for building web applications.
https://flask.palletsprojects.com
BSD 3-Clause "New" or "Revised" License
67.56k stars 16.15k forks source link

unittest loader discover throwing "AssertionError: View function mapping is overwriting an existing endpoint function" #1046

Closed docapotamus closed 10 years ago

docapotamus commented 10 years ago

I have have an issue with unittest.TestLoader().discover() throwing the error "AssertionError: View function mapping is overwriting an existing endpoint function".

I have an application as a package. I brake the package up logically into sub-packages (no blueprints). Each sub-package has a 'tests.py' file, which holds the units tests for that sub-package. Outside of the application package I have a script called 'run_tests.py', it uses the following code to discover the tests:

import unittest

suite = unittest.TestLoader().discover('<application package>', pattern='*tests.py')
unittest.TextTestRunner().run(suite)

All views are stored in the sub-packages as 'views.py' these are loaded by the applications package 'init.py' when the application is run. This is also the same file the Flask() application is created.

When I run the script 'run_tests.py' I get the following issue:

AssertionError: View function mapping is overwriting an existing endpoint function: <endpint name>

If however I point discover at '.<sub-package' I do not get the issue.

It would appear that 'unittest' loads the modules each time in tries to discover.

I know this is not a good idea for people Googling in future but I have a GH repo branch which replicates the issue: https://github.com/pjuu/pjuu/tree/0.3dev

I am guessing I can fix this issue with an application factory instead of an 'app' variable inside the applications 'init.py'.

I have fixed the issue by moving all tests to a separate sub package called 'tests' in which no views/endpoints are loaded.

I have asked on IRC and been informed this may be as issue. I will happy to find out it isn't and a pointer to my own mistake/misunderstanding.

Is this a Flask issue, a unittest issue or something else?

danielchatfield commented 10 years ago

This is because the views.py files are being imported twice. When __init__.py is executed the views.py files are imported using .views however unittest will import them another way (probably pjuu.auth.views for example).

When unittest imports auth.tests, auth/__init__.py gets evaluated and thus the views.py file also gets imported. I suggest you remove the import .views from the __init__.py file and then in the main __init__.py file use import auth.views etc.

docapotamus commented 10 years ago

@danielchatfield I thought I was being silly with this. Thank you very much for your help! That's fixed my issue

danielchatfield commented 10 years ago

No problem, glad I could help :)

docapotamus commented 10 years ago

:)