Search code examples
pythonflasksqlalchemypython-unittestflask-security

Flask unittest and flask security too issue


i have simple Flask app with flask security too and some unittest.

test.py:

class UserModelCase(unittest.TestCase):
def setUp(self):
    self.app = create_app(TestConfig)
    self.app_context = self.app.app_context()
    self.app_context.push()
    db.create_all()

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

app/init.py

db = SQLAlchemy()
admin = Admin(name='abcd', template_mode='bootstrap4')
security = Security()  

def create_app(config_class=Configuration):
    app = Flask(__name__)
    app.config.from_object(config_class)

    db.init_app(app)
    fsqla.FsModels.set_db_info(db)

    from app.models import User, Role, Comment, Post

    user_datastore = SQLAlchemyUserDatastore(db, User, Role)
    security.init_app(app, user_datastore, register_form=ExtendedRegisterForm)
    ...
    return app

and some tests. any test working, but if i run all tests on second i have an error:

sqlalchemy.exc.InvalidRequestError: Table 'roles_users' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

at self.app = create_app(TestConfig)

but in my case i don't define table "roles_users", it's automatic created and i haven't definition for "roles_users" in my models.py

how can i run all tests avoid errors? help me pls


Solution

  • The main issue here is that you need to create a NEW db instance for each test - since in create_app() you are doing db.init(app) - that is likely where things are failing.

    This likely will apply to your Security and Admin object as well.

    Try not using create_app() and doing the equivalent in your test fixture Setup()