我正在制作一个简单的Flask Web应用程序以获得乐趣,我想使用nosetests。我坚持如何使用Flask-SQLAlchemy连接到我的测试文件中的内存测试数据库。当我运行我的测试时 - Flask连接到我的主应用程序的数据库,更重要的是,在每次测试后都无法清理它。这是我的测试代码:
import nose
from nose.tools import *
from pyquery import PyQuery as pq
from flask.ext.sqlalchemy import SQLAlchemy
from app import site, db
from app.models import Post
class TestApp(object):
def setUp(self):
site.config['TESTING'] = True
site.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
self.test_app = site.test_client()
db.create_all()
def tearDown(self):
# db.session.remove()
db.drop_all()
def test_posts_index(self):
db.session.add(Post('title', 'body'))
db.session.add(Post('title2', 'body'))
db.session.commit() # this writes to production db ie app.db file
# instead of sqlite://
rv = self.test_app.get('/posts')
d = pq(rv.data)
print len(d('h1'))
assert len(d('h1')) == 2
这是我的app/__init__.py
代码:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from app import config
site = Flask(__name__)
site.config['SQLALCHEMY_DATABASE_URI'] = config.db_uri
db = SQLAlchemy(site)
site.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
from app import db_setup
db_setup.create_db()
import controllers, models
app/__init__.py
函数中的db_setup.create_db()看起来像这样:
from app import db
from app.models import Post
def create_db():
db.create_all()
db.session.commit()
我尝试在测试文件中实例化应用程序和数据库,但是我的模型不起作用,因为它们是from app import db
,其中db是生产db对象。我还在测试用例中添加了一些打印语句,如print db
,它们打印出类似<SQLAlchemy engine sqlite://>
的内容,但它仍然会写入生产数据库。
我真的很感激如何解决这个问题。谢谢!
答案 0 :(得分:2)
为什么不使用有关环境的内容来确定应用是以测试还是实时模式启动?
if 'testing' in os.environ:
site.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
else:
site.config['SQLALCHEMY_DATABASE_URI'] = config.db_uri
有很多方法可以为这只特殊的猫提供皮肤。如果您不想让if
块乱丢您的代码,您可以根据应用程序是在测试模式还是实时模式下从完全独立的模块导入您的设置。
答案 1 :(得分:0)
我能够找出问题,这与我在__init__.py
文件中启动与数据库的连接有关,我不应该这样做。
罪魁祸首是
from app import db_setup
db_setup.create_db()
代码。基本上,每次我做from app import db
时,我认为app
被实例化,它调用db_setup.create_db()
,它使用生产配置创建表。从那时起,尽管尝试将烧瓶app config SQLALCHEMY_DATABASE_URI
设置为内存数据库,db对象仍将继续使用__init__.py
文件中实例化的数据库。
我所要做的就是从当时运行的环境中调用create_all()
。希望这有助于任何人遇到类似的事情。
答案 2 :(得分:0)
我遇到了同样的问题,但我根本没有在 init .py文件中使用db.create_all()类型语句。
最后,解决问题的唯一方法就是使用
def setUp(self):
with app.app_context():
db.create_all()