Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I test a Flask application which uses SQLAlchemy?

I have a working web application on Flask with SqlAlchemy for moderation of news, it has some api methods to handle moderation requests, such as approve, deny currently selected news, list them, etc.

I want to write unit tests to this methods, and I made them work, but I don't understand how to implement executing all requests which I do from test cases in one db session, so that I could remove all changes to database. Or is there another cleaner or proper way to do this?

I've found out that maybe all I need is "scoped_session" in SqlAlchemy, but all my attempts to implement it have failed. If that's correct way, please, tell me where to use this lines of code (in settings, or in test case set_up method).

from sqlalchemy.orm import scoped_session from sqlalchemy.orm import sessionmaker session_factory = sessionmaker() Session = scoped_session(session_factory)  
like image 332
Ellochka Cannibal Avatar asked Jul 22 '13 15:07

Ellochka Cannibal


People also ask

How do I run a Flask in SQLAlchemy?

Step 1 - Install the Flask-SQLAlchemy extension. Step 2 - You need to import the SQLAlchemy class from this module. Step 3 - Now create a Flask application object and set the URI for the database to use. Step 4 - then use the application object as a parameter to create an object of class SQLAlchemy.

Which package can we use for testing Flask application?

Flask provides a way to test your application by exposing the Werkzeug test Client and handling the context locals for you. You can then use that with your favourite testing solution.


2 Answers

This is the way I've been running unit tests recently. I'm assuming since you are using SQLAlchemy that you're using model classes. I'm also assuming that all of your tables are defined as SQLAlchemy model classes.

from flask import Flask import unittest  from app import db from app.models import Log from constants import test_logs  class appDBTests(unittest.TestCase):      def setUp(self):         """         Creates a new database for the unit test to use         """         self.app = Flask(__name__)         db.init_app(self.app)         with self.app.app_context():             db.create_all()             self.populate_db() # Your function that adds test data.      def tearDown(self):         """         Ensures that the database is emptied for next unit test         """         self.app = Flask(__name__)         db.init_app(self.app)         with self.app.app_context():             db.drop_all() 

Since you're using the same DB set up as your app this allows you to build and destroy a test database with every unit test you run.

like image 29
AlexLordThorsen Avatar answered Sep 23 '22 07:09

AlexLordThorsen


I suggest you use the Flask-Testing extension. This is an approved extension which lets you do the unit testing as you desire. It has a specific section for SQLAlchemy as well.

Testing with SQLAlchemy

This covers a couple of points if you are using Flask-Testing with SQLAlchemy. It is assumed that you are using the Flask-SQLAlchemy extension, but if not the examples should not be too difficult to adapt to your own particular setup.

First, ensure you set the database URI to something other than your production database ! Second, it’s usually a good idea to create and drop your tables with each test run, to ensure clean tests:"

from flask.ext.testing import TestCase  from myapp import create_app, db  class MyTest(TestCase):      SQLALCHEMY_DATABASE_URI = "sqlite://"     TESTING = True      def create_app(self):          # pass in test configuration         return create_app(self)      def setUp(self):          db.create_all()      def tearDown(self):          db.session.remove()         db.drop_all() 
like image 78
codegeek Avatar answered Sep 21 '22 07:09

codegeek