2

I'm trying to do unit testing of my Flask web app. I'm use a pattern I saw in a Udemy class on Flask and a pattern similar to the Flask Mega-Tutorial online (http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-vii-unit-testing). The problem I'm having is that the test does not actual create it's own database -- rather it uses the production database and messes it up.

Here's what tests.py script looks like:

import os,sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
basedir = os.path.abspath(os.path.dirname(__file__))

import unittest
from myapp import app, db
from user.models import User

class UserTest(unittest.TestCase):

    def setUp(self):
        self.db_uri = 'sqlite:///' + os.path.join(basedir, 'test.db')
        app.config['TESTING'] = True
        app.config['WTF_CSRF_ENABLED'] = False
        app.config['SQL_ALCHEMY_DATABASE_URI'] = self.db_uri
        self.app = app.test_client()
        db.create_all()

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

    def test_models(self):
        #Create a customer user
        user = User("John Doe", "[email protected]", "jdoe", "password", is_consultant=False)
        db.session.add(user)
        db.session.commit()

        #Create 2 consultant users
        user1 = User("Jane Doe", "[email protected]", "janedoe", "password", is_consultant=True)
        db.session.add(user1)
        user2 = User("Nikola Tesla", "[email protected]", "nikola", "password", is_consultant=True)
        db.session.add(user2)
        db.session.commit()

        #Check that all users exist
        assert len(User.query.all()) is 3

My app init is in the same folder and looks like so:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.migrate import Migrate
from flask.ext.login import LoginManager

app = Flask(__name__)
app.config.from_object('config')
db = SQLAlchemy(app)

# flask-login extension setup
login_manager = LoginManager()
login_manager.init_app(app)

# migration setup
migrate = Migrate(app, db)

from user import views

I don't understand what is going on. It never creates the test.db SQLite database. It always creates the app.db production database. And if it's there, it totally messes up the database is there. Afterwards if I do python manage.py runserver -- it doesn't work anymore. It says table not found. Because the teardown dropped all the tables. What is going on? And how do I fix it?

1
  • Omigod I figured it out. I was setting the wrong key for the database URI. It should be: app.config['SQLALCHEMY_DATABASE_URI'] = self.db_uri Commented Jul 30, 2015 at 21:47

2 Answers 2

5

Omigod I figured it out. I was setting the wrong key for the database URI. It should be: app.config['SQLALCHEMY_DATABASE_URI'] = self.db_uri.

So everything is fine. Just do:

class UserTest(unittest.TestCase):

    def setUp(self):
        self.db_uri = 'sqlite:///' + os.path.join(basedir, 'test.db')
        app.config['TESTING'] = True
        app.config['WTF_CSRF_ENABLED'] = False
        app.config['SQLALCHEMY_DATABASE_URI'] = self.db_uri
        self.app = app.test_client()
        db.create_all()

and everything works as intended.

I checked what was going on by putting a break-point in the tests and seeing what app.config was -- and I saw that there was both a SQL_ALCHEMY_DATABASE_URI key (which doesn't do anything and I was setting) and a SQLALCHEMY_DATABASE_URI key (this is the one that matters).

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

Comments

0

I met the same question with you, but the cause is different. my mistake is using the same database name in the DevelopmentConfig and TestingConfig! it should be different name, such as data-dev.sqlite and data-test.sqlite

config.py

class DevelopmentConfig(Config):
   DEBUG = True
   SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 
       'data-dev.sqlite')

class TestingConfig(Config):
   TESTING = True 
   SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 
       'data-test.sqlite')

Comments

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.