【问题标题】:How can I test my flask application using unittest?如何使用 unittest 测试我的烧瓶应用程序?
【发布时间】:2016-02-14 13:29:42
【问题描述】:

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

我现在真的一直在努力解决这个单元测试问题。这很令人困惑,因为有请求上下文和应用程序上下文,当我调用 db.create_all() 时,我不知道我需要进入哪一个。

似乎当我添加到数据库时,它会将我的模型添加到我的应用程序模块 (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

还有烧瓶文档: http://flask.pocoo.org/docs/0.10/testing/

【问题讨论】:

    标签: python flask sqlalchemy flask-sqlalchemy python-unittest


    【解决方案1】:

    您遇到的一个问题是烧瓶上下文的限制,这是我在将烧瓶扩展包含到我的项目中之前长时间思考的主要原因,而烧瓶-sqlalchemy 是最大的违规者之一。我这样说是因为在大多数情况下,在处理数据库时完全没有必要依赖于烧瓶应用程序上下文。当然它会很好,特别是因为 flask-sqlalchemy 在幕后为您做了很多事情,主要是您不必手动管理会话、元数据或引擎,但请记住,这些事情可以很容易地由您自己完成,并且为此,您可以不受限制地访问您的数据库,而不必担心烧瓶上下文。这是一个如何手动设置数据库的示例,首先我将展示flask-sqlalchemy方式,然后是手动普通sqlalchemy方式:

    1. 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
      
    2. 标准的 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
      

    如果您这样设置应用程序,您遇到的任何上下文问题都应该消失。

    【讨论】:

      【解决方案2】:

      作为一个单独的答案,实际上只是强制您需要工作,您可以使用 test_request_context 函数,即:在设置中执行:self.ctx = app.test_request_context() 然后只需激活它,self.ctx.push() 完成后摆脱它,即拆解:self.ctx.pop()

      【讨论】:

        猜你喜欢
        • 2021-12-19
        • 1970-01-01
        • 2021-12-19
        • 2016-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-11
        • 1970-01-01
        相关资源
        最近更新 更多