如何使用 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 应用程序?我应该如何构建我的应用程序才能实现这一点?我必须使用模块
吗?
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 module
s ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您使用环境变量的直觉是正确的。但是,使用错误的数据库运行单元测试存在一些危险。另外,您可能不希望在每个请求以及想要使用 db 的任何地方都使用 connect_db。您可以使用显式设置的配置目录和环境变量。这是迄今为止我想出的最好的办法。
所以,配置文件可能是:
所以
,我可以在我的基本测试用例中显式设置数据库:
然后,对我来说,
main/__init__.py
:然后,在其他文件中,我知道我想运行什么配置,可能:
也许
..到目前为止最好的:P。
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 usedb
. You can use a config directory and environment variables which you set explicitly. This is the best I've come up with so far.so, the config files may be:
and
So, I can explicitly set the db in my base TestCase:
Then, the
main/__init__.py
, for me:Then, in the other files, where I know what config I want to run, potentially:
and
Maybe .. best so far :P.
您不希望在导入时连接到数据库。继续在导入时配置您的应用程序,因为您始终可以在尝试测试或运行应用程序之前调整测试中的配置。在下面的示例中,您的数据库连接将位于一些使用应用程序配置的函数后面,因此在单元测试中,您实际上可以更改数据库连接以指向不同的文件,然后继续并在您的设置中显式连接。
假设您有一个包含 myapp.py 的 myapp 包,如下所示:
您的测试文件 myapp/test_myapp.py 将如下所示:
当然,如果您想使用 SQLAlchemy,则必须适当更新 connect_db 和 init_db 函数,但是希望你能明白。
You won't want to make connecting to the db happen at import time. Go ahead and configure your app at import time because you can always tweak the configuration in your tests before attempting to test or run your app. In the example below you'll have your db connection behind some functions that use the application config so in a unittest you can actually change the db connection to point to a different file and then go ahead and connect explicitly in your setup.
Say you have a myapp package containing myapp.py which looks like:
Your test file myapp/test_myapp.py will look like this:
Of course if you'd like to use SQLAlchemy you'll have to update the connect_db and init_db functions appropriately but hopefully you get the idea.
首先,您不是直接在脚本中实例化 Flask 应用程序,而是使用应用程序工厂。这意味着您创建一个以配置文件作为参数的函数,并返回实例化的应用程序对象。然后,您创建不带参数的全局 SQLAlchemy 对象,并在创建应用程序时配置它,如此处所述。
要运行该应用程序,您只需执行以下操作:
要运行单元测试,您可以执行以下操作:
在我的例子中,我直接使用 SQLAlchemy 和scoped_session 而不是 Flask-SQLAlchemy。
我也做了同样的事情,但是使用了Lazy SQLAlchemy 设置。
First, instead of instantiating Flask app directly in your script, you use an application factory. It means you create a function that takes your config file as parameter, and return the instantiated app object. Then, you create the global SQLAlchemy object without parameter, and you configure it when creating the app, as explained here.
To run the app, you simply do something like:
To run unittests, you can do something like:
In my case, I'm using SQLAlchemy directly with scoped_session instead of Flask-SQLAlchemy.
I did the same, but with Lazy SQLAlchemy setup.