2013-08-01 69 views
9

我在測試我的應用程序時遇到Flask-Admin創建藍圖的問題。測試期間Flask-Admin藍圖創建

這是我的看法類(使用的SQLAlchemy)

## 
# All views that only admins are allowed to see should inherit from this class. 
# 
class AuthView(ModelView): 
    def is_accessible(self): 
     return current_user.is_admin() 

class UserView(AuthView): 
    column_list = ('name', 'email', 'role_code') 

這是我如何初始化觀點:

# flask-admin 
admin.add_view(UserView(User, db.session)) 
admin.init_app(app) 

然而,當我嘗試運行一個以上的測試(故障始終發生在第二次測試和所有其他測試後),我總是得到以下錯誤信息:

====================================================================== 
ERROR: test_send_email (tests.test_views.TestUser) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/lib/python2.7/site-packages/nose/case.py", line 133, in run 
    self.runTest(result) 
    File "/lib/python2.7/site-packages/nose/case.py", line 151, in runTest 
    test(result) 
    File "/lib/python2.7/site-packages/flask_testing.py", line 72, in __call__ 
    self._pre_setup() 
    File "/lib/python2.7/site-packages/flask_testing.py", line 80, in _pre_setup 
    self.app = self.create_app() 
    File "/tests/test_init.py", line 27, in create_app 
    app = create_app(TestConfig) 
    File "/fbone/app.py", line 41, in create_app 
    configure_extensions(app) 
    File "/fbone/app.py", line 98, in configure_extensions 
    admin.add_view(UserView(User, db.session)) 
    File "/lib/python2.7/site-packages/flask_admin/base.py", line 484, in add_view 
    self.app.register_blueprint(view.create_blueprint(self)) 
    File "/lib/python2.7/site-packages/flask/app.py", line 62, in wrapper_func 
    return f(self, *args, **kwargs) 
    File "/lib/python2.7/site-packages/flask/app.py", line 885, in register_blueprint 
    (blueprint, self.blueprints[blueprint.name], blueprint.name) 
AssertionError: A blueprint's name collision occurred between <flask.blueprints.Blueprint object at 0x110576910> and <flask.blueprints.Blueprint object at 0x1103bd3d0>. Both share the same name "userview". Blueprints that are created on the fly need unique names. 

奇怪的是,這隻發生在第二次測試,從來沒有當我只是運行應用程序。

當我調試的測試中,它第一次做了什麼我的預期和init_app(應用程序)後增加的藍圖應用程序。然而,第二次過程在到達add_view步驟時立即停止(我認爲這很奇怪,因爲藍圖已在init_app(app)調用中註冊?)

+0

當你說「第一次」你在你的第一次測試的意思還是你說你的單元測試完成後,你再次運行整個測試套裝。 – AlexLordThorsen

+0

我的意思是第一次測試 – arnoutaertgeerts

+0

確保在每個測試的應用程序工廠中爲您的Admin類創建新實例。看起來像不斷爲每個測試運行添加視圖到現有的'Admin'類實例。 – Joes

回答

1

我不得不將以下內容添加到我的測試用例tearDown中。它清理被添加到管理員擴展測試設置

from flask.ext.testing import TestCase 
from flask.ext.admin import BaseView 

# My application wide instance of the Admin manager 
from myapp.extensions import admin 


class TestView(BaseView): 
    ... 


class MyTestCase(TestCase): 
    def setUp(self): 
     admin.add_view(TestView()) 

    def tearDown(self): 
     admin._views.pop(-1) 
     admin._menu.pop(-1) 

這當然是一個黑客攻擊的一位的意見,但它得到了,而我有這個問題的工作做好。

8

同樣的事情發生在我身上,而使用燒瓶聯繫,並與pytest測試。通過將admin實例的創建移動到應用程序工廠,我能夠修復它,而無需爲測試創建拆卸功能。

前:

# extensions.py 
from flask.ext.admin import Admin 
admin = Admin() 

# __init__.py 
from .extensions import admin 

def create_app(): 
    app = Flask('flask_app') 

    admin.add_view(sqla.ModelView(models.User, db.session)) 
    admin.init_app(app) 

    return app 

後:

# __init__.py 
from flask.ext.admin import Admin 

def create_app(): 
    app = Flask('flask_app') 

    admin = Admin() 

    admin.add_view(sqla.ModelView(models.User, db.session))  
    admin.init_app(app) 

    return app 

因爲pytest每次運行它不再嘗試註冊一個全球性管理實體的多個視圖時應用工廠。這與典型的Flask擴展使用不一致,但是它可以工作,並且它會讓應用程序工廠避免陷入Flask-Admin視圖。

1

以防萬一,這可以幫助任何人, 另一種方式來處理,這是要做到:

class MyTestCase(TestCase): 
    def setUp(self): 
     admin._views = [] 

這樣你就不必設置在工廠內的管理員()初始化。這似乎更適合我。