我试图使用unittest测试我的烧瓶应用程序。我想避免进行烧瓶测试,因为我不想超越自己。
我现在真的在努力解决这个问题。这是令人困惑的,因为有请求上下文和应用程序上下文,当我调用db.create_all()时,我不知道我需要在哪一个。
似乎当我添加到数据库时,它会将我的模型添加到我的app模块( init .py)文件中指定的数据库,但不会添加到setUp中指定的数据库(self方法。
我有一些必须在每个test_方法之前填充数据库的方法。
如何将数据库指向正确的路径?
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'])
以下是填充我的数据库的方法之一:
def create_users(self):
#raise ValueError(User.query.all())
new_user = User('Some User Name','xxxxx@gmail.com','admin')
new_user.role_id = 1
new_user.status = 1
new_user.password = generate_password_hash(new_user.password)
db.session.add(new_user)
我看过的地方:
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
答案 0 :(得分:1)
一个问题是你的命中是烧瓶环境的限制,这是我认为包括烧瓶延伸到我的项目之前的漫长而艰难的主要原因,而flask-sqlalchemy是最大的罪犯之一。我这样说是因为在大多数情况下,在处理数据库时完全没有必要依赖于烧瓶应用程序上下文。当然它可以很好,特别是因为flask-sqlalchemy为你做了很多幕后工作,主要是你不必手动管理你的会话,元数据或引擎,但要记住这些事情可以很容易地自己完成,并且为此,您可以获得对数据库的无限制访问权限,而无需担心烧瓶上下文。这里是一个如何手动设置数据库的示例,首先我将显示flask-sqlalchemy方式,然后是手动普通sqlalchemy方式:
flask-sqlalchemy
方式:
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
标准sqlalchemy方式:
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
如果你像这样设置你的应用程序,任何上下文问题都应该消失。
答案 1 :(得分:0)
作为一个单独的答案,实际上只是强制你需要工作,你可以使用test_request_context函数,即:在设置中执行:self.ctx = app.test_request_context()
然后只需激活它,self.ctx.push()
当你的完成摆脱它,即在tearDown:self.ctx.pop()