你如何用SQLAlchemy设置Flask应用程序进行测试? [英] How do you set up a Flask application with SQLAlchemy for testing?

查看:137
本文介绍了你如何用SQLAlchemy设置Flask应用程序进行测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Flask中看起来很常见,就像这样开始:

  from flask import Flask 
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__ name__)
SQLALCHEMY_DATABASE_URI ='something'
app.config.from_object(__ name__)
db = SQLAlchemy(app)

然后导入并使用 app db 无处不在。但是当你像这样创建 db 时,它会从应用程序获取配置,而且看起来这个配置一旦发生就不能被覆盖。在Flask的网站上有一些关于制作应用程序工厂的网页,但是我还不清楚如何继续使用 app db

如何编写一个脚本来用不同的数据库测试我的Flask应用程序?我应该如何构建我的应用程序,使之成为可能?我不得不使用 module s?

解决方案

环境变量是正确的。但是,使用错误的db运行单元测试存在一些危险。另外,您可能不希望 connect_db 与每个请求以及要使用的任何地方 db 相关。您可以使用明确设置的配置目录和环境变量。

  run.py 
shell.py $ b $这是迄今为止最好的。 b
config / __ init__.py
config / test.py
config / postgres.py
...

main / __ init__.py
main / someapp / __ init__.py
main / someapp / models.py

...
main / tests / __ init__.py
main / tests / testutils.py

所以,配置文件可能是:

 #config / test.py 
SQLALCHEMY_DATABASE_URI =sqlite://



 #config / postgres.py 
SQLALCHEMY_DATABASE_URI ='postgresql :// user:pw @ localhost / somedb'

所以,我可以明确的设置db base TestCase:

 从flask.ext.testing导入os 
import TestCase

os .environ [DIAG_CONFIG_MODULE] =config.test
来自主导入应用程序,db


class SQLAlchemyTest(TestCase):

def create_app(self):
(self):
db.create_all()
$ b $ def tearDown(self):
db.session.remove()返回应用程序

def setUp
db.drop_all()

然后, main / __ init__ .py ,对我来说:

  import os 

from flask import烧瓶,render_template,g
from flask.ext.sqlalchemy导入SQLAlchemy

#默认情况下,我们使用一个我们不关心
#的数据库,但是,我们可以覆盖if我们想要
config_obj = os.environ.get(DIAG_CONFIG_MODULE,config.test)
app = Flask(__ name__)
app.config.from_object(config_obj)
db = SQLAlchemy(app)

@ app.before_request
def before_request():
g.db = db
g.app = app

#...
@ app.route('/',methods = ['GET'])
def get():
return render_template('home.html')
#...
from main.someapp.api import mod as someappmod
app.register_blueprint(someappmod)

然后,在其他文件中,我知道要运行的配置,可能是:
$ $ b pre $ #run.py
import os
os.environ [DIAG_CONFIG_MODULE] =config.postgres
from main import app
app.run(debug = True)

 #shell.py 
import os
os.environ [DIAG_CONFIG_MODULE] =config.postgres

from main.symdiag.models import *
from main.auth.models import *
print sort(k for k in locals()。keys( )如果不是k.startswith(_))
导入IPython
IPython.embed()

可能..迄今为止最好的:P。


It seems common practice in Flask to start like this:

from flask import Flask
from flaskext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
SQLALCHEMY_DATABASE_URI = 'something'
app.config.from_object(__name__)
db = SQLAlchemy(app)

And then import and use app and db everywhere. But when you create db like this, it grabs configuration from the app, and it seems that this configuration can't ever be overridden once it happens. There are some pages on Flask's website about making application factories, but it's not clear how I would be able to still use app and db everywhere if I did that.

How do I write a script to test my Flask application with a different database? How should I structure my application to make this possible? Do I have to use modules ?

解决方案

Your instinct to use environment variables is correct. However, there is some danger of running unit tests with the wrong db. Also, you may not want to connect_db with every request and everywhere you want to use db. You can use a config directory and environment variables which you set explicitly. This is the best I've come up with so far.

run.py
shell.py

config/__init__.py
config/test.py
config/postgres.py
...

main/__init__.py
main/someapp/__init__.py
main/someapp/models.py

...
main/tests/__init__.py
main/tests/testutils.py

so, the config files may be:

# config/test.py
SQLALCHEMY_DATABASE_URI = "sqlite://"

and

# config/postgres.py
SQLALCHEMY_DATABASE_URI = 'postgresql://user:pw@localhost/somedb'

So, I can explicitly set the db in my base TestCase:

import os
from flask.ext.testing import TestCase

os.environ["DIAG_CONFIG_MODULE"] = "config.test"
from main import app, db


class SQLAlchemyTest(TestCase):

    def create_app(self):
        return app

    def setUp(self):
        db.create_all()

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

Then, the main/__init__.py, for me:

import os

from flask import Flask, render_template, g
from flask.ext.sqlalchemy import SQLAlchemy

# by default, let's use a DB we don't care about
# but, we can override if we want
config_obj = os.environ.get("DIAG_CONFIG_MODULE", "config.test")
app = Flask(__name__)
app.config.from_object(config_obj)
db = SQLAlchemy(app)

@app.before_request
def before_request():
    g.db = db
    g.app = app

# ...
@app.route('/', methods=['GET'])
def get():
    return render_template('home.html')
# ...    
from main.someapp.api import mod as someappmod
app.register_blueprint(someappmod)

Then, in the other files, where I know what config I want to run, potentially:

# run.py
import os
os.environ["DIAG_CONFIG_MODULE"] = "config.postgres"
from main import app
app.run(debug=True)

and

# shell.py
import os
os.environ["DIAG_CONFIG_MODULE"] = "config.postgres"

from main import app, db
from main.symdiag.models import *
from main.auth.models import *
print sorted(k for k in locals().keys() if not k.startswith("_"))
import IPython
IPython.embed()

Maybe .. best so far :P.

这篇关于你如何用SQLAlchemy设置Flask应用程序进行测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆