5

I am developing my first Flask app. It is my side project, so I focus on good practises and design and take my time. I am a bit stuck on testing - I found some examples in docs and here on SO, but they either do not apply to my app or do not seem Pythonic/well designed.

The relevant pieces of code are:

# application module __init__.py
def create_app(config):
    app = Flask(__name__)
    app.config.from_object('config.%s' % config.title())
    return app  

config = os.getenv('CONFIG', 'development')
app = create_app(config)
db = SQLAlchemy(app)

# config.py
class Testing(Base):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = \
        'sqlite:///' + os.path.join(_basedir, 'testing.sqlite')

# models.py
class User(db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(60), unique=True, nullable=False)
    password_hash = db.Column(db.String(60), nullable=False)

# testing.py
class TestCase(unittest.TestCase):
    
    def setUp(self):
        self.app = create_app('testing')
        # TODO: create connection to testing db

    def tearDown(self):
        # TODO: abort transaction
        pass

The question is: how to implement setUp and tearDown so that in my tests I can use my models and connection do testing database? If I just import db, it would work on development database.

If it helps anything, I do not need to create testing db from scratch, I use Flask-Migrate and tests can assume the testing db is initialized and empty.

Any comments are welcome, I do not mind refactoring if my design is flawed.

1 Answer 1

6

It looks like you should just be able to run CONFIG=Testing python -m unittest discover and have everything just work. The only think you may want to change is, instead of calling create_app in your tests, simply import it from __init__.py:

# testing.py
from . import config, db

class TestCase(unittest.TestCase):

    def setUp(self):
        self.app = create_app(config)
        # db is properly set up to use the testing config
        # but any *changes* you make to the db object
        # (e. g. monkey-patching) will persist between tests
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()

See here for an example.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot, thats not exactly how I fixed it, but you showed me the rigtht direction.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.