So I have setted up my flask in this way:
def create_app(config_name):
app = Flask(__name__, static_folder='../designs/UI', template_folder='../designs/UI', instance_relative_config=True)
app.config.from_object(app_config[config_name])
app.config.from_pyfile('config.py')
db.init_app(app)
login_manager.init_app(app)
login_manager.login_message = "You must be logged in to access this page."
login_manager.login_view = "auth.login_page"
migrate = Migrate(app, db)
from app import models
from .api import blueprint as api_blueprint
app.register_blueprint(api_blueprint, url_prefix='/api/v1.0')
@app.route('/')
def homepage():
return redirect('/api/v1.0')
return app
And my unittest setup:
def setUp(self):
"""setup test variables"""
self.app = create_app(config_name="testing")
self.client = self.app.test_client
# binds the app with the current context
with self.app.app_context():
#create all tables
db.session.close()
db.drop_all()
db.create_all()
When I import my models into the test file and try to access anything from the database I get the following error:
RuntimeError: application not registered on db instance and no applicationbound to current context
Is there any better way to set up the entire thing so that it may work?
Tests are typically located in the tests folder. Tests are functions that start with test_ , in Python modules that start with test_ . Tests can also be further grouped in classes that start with Test .
I decided to explain the problem(and solution) in detail.
1) Why your way doesn't work?
Because you trying to push app context
using Context Manager. What does it mean? current context
will be available only inside with
block. You bind context
and he available only in setUp
, but not in tests. app
will works without context
when setUp()
is finished. Let's look at this example:
app = Flask(__name__)
class TestCase(TestCase):
def setUp(self):
with app.app_context():
# current_app is available(you will see <Flask 'app'> in terminal)
print current_app
# out of context manager - RuntimeError: Working outside of application context.
print current_app
def test_example(self):
pass
Run test. You'll be see Flask 'app' + exception. The error will disappear if you remove last print(out of with
block).
2) How to fix the problem?
You can bind app context
without Context Manager.
class TestCase(TestCase):
def setUp(self):
ctx = app.app_context()
ctx.push()
# after this you can use current_app
print current_app
def test_example(self):
# available because we pushed context in setUp()
print current_app
Run test:
<Flask 'app'> # from setUp()
<Flask 'app'> # from test_example
So, let's sum up. current_app
is available ONLY 'inside' Context Manager. But you can bind context without Context Manager.
I hope that I have explained the details and answered your questions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With