2013-10-31 49 views
1

我正在做一個簡單的燒瓶web應用程序的樂趣,我想用nosetests。我被困在如何使用Flask-SQLAlchemy連接到測試文件中的內存中測試數據庫。當我運行我的測試時 - Flask連接到我的主應用程序的數據庫,更重要的是,每次測試後都無法清除它。下面是我的測試代碼:燒瓶nosetests - 無法連接到測試db

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 

的db_setup.create_db()在app/__init__.py函數看起來簡直就像這樣:

from app import db 
from app.models import Post 
def create_db(): 
    db.create_all() 
    db.session.commit() 

我試圖實例化應用程序和數據庫在測試文件中,但然後我的模型不起作用,因爲它們是from app import db,其中db是生產數據庫對象。我還在print db這樣的測試案例中散佈了一些打印語句,他們打印出類似<SQLAlchemy engine sqlite://>的東西,但它仍然寫入生產數據庫。

我真的很感激有關如何解決這個問題的任何提示。謝謝!

回答

2

爲什麼不使用關於環境的東西來確定應用程序是以測試還是實時模式啓動?

if 'testing' in os.environ: 
    site.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
else: 
    site.config['SQLALCHEMY_DATABASE_URI'] = config.db_uri 

有這麼多的方法來剝皮這隻特定的貓。如果您不喜歡讓if塊垃圾代碼的想法,則可以根據應用是否在測試或實時模式下啓動,從完全獨立的模塊中導入設置。

+0

我做這樣的事情,凡在我節目的根源我有許多的一個裝我的配置配置文件(請參閱[使用文件配置](http://flask.pocoo.org/docs/config/#configuring-from-files)),並使用環境變量來控制在應用程序啓動之前加載哪個配置。也可用於現場與分期對比開發配置。另見[配置最佳實踐](http:// flask。pocoo.org/docs/config/#configuration-best-practices),其中談到了單元測試。 –

+0

@MarkHildreth,aychedee - 非常感謝這些想法和提示。我能夠自己找到這個錯誤(它與導入等有關),但是我將重構我的項目以按照您的概述使用配置文件。非常感謝您的幫助,我非常感謝。 – Protagonist

0

我能夠找出問題,它與我在我的__init__.py文件中啓動到數據庫的連接有關,我不應該這樣做。

的罪魁禍首是

from app import db_setup 
db_setup.create_db() 

代碼。實質上,每次我做了from app import db,我認爲app被實例化,它調用db_setup.create_db(),它使用生產配置創建表。從那裏開始,儘管嘗試將flask應用配置SQLALCHEMY_DATABASE_URI設置爲內存數據庫,但db對象將繼續使用__init__.py文件中實例化的數據庫。

我所要做的就是撥打create_all(),這個環境我會在當時運行。希望這可以幫助任何人如何碰到類似的東西。

0

我有同樣的問題,但我沒有在我的init .py文件中使用db.create_all()類型的語句。

最後,我圍繞這個問題可以的唯一途徑是使用

def setUp(self): 
    with app.app_context(): 
       db.create_all()