Python 如何使用unittest测试我的烧瓶应用程序?

Python 如何使用unittest测试我的烧瓶应用程序?,python,flask,sqlalchemy,flask-sqlalchemy,python-unittest,Python,Flask,Sqlalchemy,Flask Sqlalchemy,Python Unittest,我正在尝试使用unittest测试我的flask应用程序。我不想做烧瓶测试,因为我不想超越自己 我现在真的在为这个单元测试而挣扎。这很混乱,因为有请求上下文和应用上下文,我不知道调用db.create_all()时需要在哪个上下文中 似乎当我添加到数据库时,它会将我的模型添加到我的应用程序模块(init.py)文件中指定的数据库,而不是安装(self)方法中指定的数据库 我有一些方法必须在每个测试方法之前填充数据库 如何将数据库指向正确的路径 def setUp(self): #self

我正在尝试使用unittest测试我的flask应用程序。我不想做烧瓶测试,因为我不想超越自己

我现在真的在为这个单元测试而挣扎。这很混乱,因为有请求上下文和应用上下文,我不知道调用db.create_all()时需要在哪个上下文中

似乎当我添加到数据库时,它会将我的模型添加到我的应用程序模块(init.py)文件中指定的数据库,而不是安装(self)方法中指定的数据库

我有一些方法必须在每个测试方法之前填充数据库

如何将数据库指向正确的路径

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)
我看过的地方:

以及烧瓶文件:

您遇到的一个问题是flask上下文的局限性,这是我在将flask扩展纳入我的项目之前考虑了很久的主要原因,flask sqlalchemy是最大的罪魁祸首之一。我这样说是因为在大多数情况下,在处理数据库时完全没有必要依赖flask应用程序上下文。当然,这很好,特别是因为flask sqlalchemy在幕后为您做了很多事情,主要是您不必手动管理会话、元数据或引擎,但请记住,这些事情可以轻松地由您自己完成,这样您就可以不受限制地访问数据库,不用担心烧瓶的上下文。下面是一个如何手动设置db的示例,首先我将展示flask sqlalchemy方法,然后是手动普通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
  • 炼金术的
    方法:

    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
    

  • 如果你像这样设置你的应用程序,任何上下文问题都应该消失

    作为一个单独的答案,要真正强制您需要的工作,您可以使用test\u request\u context函数,即:在setup do:
    self.ctx=app.test\u request\u context()
    中,然后激活它,
    self.ctx.push()
    完成后,即在tearDown:
    self.ctx.pop()