当前位置: 动力学知识库 > 问答 > 编程问答 >

python - How can I test my flask application using unittest?

问题描述:

I'm trying to test my flask application using unittest. I want to refrain from flask-testing because I don't like to get ahead of myself.

I've really been struggling with this unittest thing now. It is confusing because there's the request context and the app context and I don't know which one I need to be in when I call db.create_all().

It seems like when I do add to the database, it adds my models to the database specified in my app module (init.py) file, but not the database specified in the setUp(self) method.

I have some methods that must populate the database before every test_ method.

How can I point my db to the right path?

def setUp(self):

#self.db_gd, app.config['DATABASE'] = tempfile.mkstemp()

app.config['TESTING'] = True

# app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE']

basedir = os.path.abspath(os.path.dirname(__file__))

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \

os.path.join(basedir, 'test.db')

db = SQLAlchemy(app)

db.create_all()

#self.app = app.test_client()

#self.app.testing = True

self.create_roles()

self.create_users()

self.create_buildings()

#with app.app_context():

# db.create_all()

# self.create_roles()

# self.create_users()

# self.create_buildings()

def tearDown(self):

#with app.app_context():

#with app.request_context():

db.session.remove()

db.drop_all()

#os.close(self.db_gd)

#os.unlink(app.config['DATABASE'])

Here is one of the methods that populates my database:

def create_users(self):

#raise ValueError(User.query.all())

new_user = User('Some User Name','[email protected]','admin')

new_user.role_id = 1

new_user.status = 1

new_user.password = generate_password_hash(new_user.password)

db.session.add(new_user)

Places I've looked at:

http://kronosapiens.github.io/blog/2014/08/14/understanding-contexts-in-flask.html

http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xvi-debugging-testing-and-profiling

And the flask documentation:

http://flask.pocoo.org/docs/0.10/testing/

网友答案:

one issue that your hitting is the limitations of flask contexts, this is the primary reason i think long and hard before including a flask extension into my project, and flask-sqlalchemy is one of the biggest offenders. i say this because in most cases it is completely unnecessary to depend on the flask app context when dealing with your database. Sure it can be nice, especially since flask-sqlalchemy does a lot behind the scenes for you, mainly you dont have to manually manage your session, metadata or engine, but keeping that in mind those things can easily be done on your own, and for doing that you get the benefit of unrestricted access to your database, with no worry about the flask context. here is an example of how to setup your db manually, first i will show the flask-sqlalchemy way, then the manual plain sqlalchemy way:

  1. the flask-sqlalchemy way:

    import flask
    from flask_sqlalchemy import SQLAlchemy
    
    app = flask.Flask(__name__)
    db = SQLAlchemy(app)
    
    # define your models using db.Model as base class
    # and define columns using classes inside of db
    # ie: db.Column(db.String(255),nullable=False)
    # then create database
    db.create_all() #  <-- gives error if not currently running flask app
    
  2. the standard sqlalchemy way:

    import flask
    import sqlalchemy as sa
    from sqlalchemy.ext.declarative import declarative_base
    
    # first we need our database engine for the connection
    engine = sa.create_engine(MY_DB_URL,echo=True) 
    # the line above is part of the benefit of using flask-sqlalchemy, 
    # it passes your database uri to this function using the config value        
    # SQLALCHEMY_DATABASE_URI, but that config value is one reason we are
    # tied to the application context 
    
    # now we need our session to create querys with
    Session = sa.orm.scoped_session(sa.orm.sessionmaker())
    Session.configure(bind=engine)
    session = Session()
    
    # now we need a base class for our models to inherit from 
    Model = declarative_base()
    # and we need to tie the engine to our base class
    Model.metadata.bind = engine
    
    # now define your models using Model as base class and 
    # anything that would have come from db, ie: db.Column
    # will be in sa, ie: sa.Column
    
    # then when your ready, to create your db just call
    Model.metadata.create_all()
    # no flask context management needed now
    

if you set your app up like that, any context issues your having should go away.

分享给朋友:
您可能感兴趣的文章:
随机阅读: