2013-08-01 16 views
9

Ho problemi con la creazione di blueprints da parte di Flask-Admin quando eseguo il test della mia app.Creazione del blueprint del modulo Flask-Admin durante il test

Questa è la mia opinione classe (utilizzando 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') 

Questo è quanto ho inizializzare la vista:

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

Tuttavia, quando si tenta di eseguire più di una prova (la colpa sempre si verifica nel secondo test e in tutti gli altri test che seguono), viene sempre visualizzato il seguente messaggio di errore:

====================================================================== 
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. 

La cosa strana è che questo accade solo nel secondo test e mai quando eseguo l'app.

Quando ho eseguito il debug dei test, la prima volta ha fatto esattamente quello che mi aspettavo e ho aggiunto il progetto all'app dopo l'init_app (app). La seconda volta tuttavia il processo si interrompe immediatamente quando si raggiunge il passo add_view (che penso sia strano perché i blueprints vengono registrati nella chiamata init_app (app)?)

+0

Quando dici "la prima volta" intendi nel tuo primo test o stai dicendo che il tuo test unitario è completato e stai eseguendo di nuovo l'intero test. – AlexLordThorsen

+0

Intendo il primo test – arnoutaertgeerts

+0

Assicurati di creare una nuova istanza della classe 'Admin' nella tua applicazione per ogni test. Sembra che tu continui ad aggiungere viste all'istanza di classe 'Admin' esistente per ogni esecuzione di test. – Joes

risposta

1

Ho dovuto aggiungere quanto segue al mio caso di prova tearDown. Si pulisce il punto di vista che sono stati aggiunti alla estensione admin nel configurazione di prova

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) 

Questo è certamente un po 'di un hack, ma ha ottenuto il lavoro fatto, mentre ho avuto questo problema.

8

La stessa cosa è successa a me durante l'utilizzo di Flask-Admin e test con pytest. Sono stato in grado di risolverlo senza creare funzioni di teardown per i miei test spostando la creazione dell'istanza admin nella factory dell'app.

Prima:

# 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 

Dopo:

# __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 

Perché pytest gestisce la fabbrica di applicazione ogni volta che non è più tenta di registrare più visualizzazioni su un'istanza di amministrazione globale. Questo non è coerente con l'uso tipico dell'estensione di Flask, ma funziona e manterrà la fabbrica delle app da inciampare sulle viste di Flask-Admin.

1

Solo nel caso che questo aiuta chiunque, un altro modo per gestire questa situazione è quello di fare:

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

questo modo non c'è bisogno di impostare l'inizializzazione Admin() all'interno della fabbrica. Mi sembra più appropriato.

Problemi correlati