2017-10-09 11 views
0

J'essaie d'écrire des tests unitaires pour une application Flask en utilisant pytest. J'ai une usine d'application:Générer des URL pour le client de test Flask

def create_app(): 
    from flask import Flask 
    app = Flask(__name__) 
    app.config.from_object('config') 
    import os 
    app.secret_key = os.urandom(24) 
    from models import db 
    db.init_app(app) 
    return app 

Et une classe de test:

class TestViews(object): 

    @classmethod 
    def setup_class(cls): 
     cls.app = create_app() 
     cls.app.testing = True 
     cls.client = cls.app.test_client() 

    @classmethod 
    def teardown_class(cls): 
     cls.app_context.pop() 

    def test_create_user(self): 
     """ 
     Tests the creation of a new user. 
     """ 
     view = TestViews.client.get(url_for('create_users')).status_code == 200 

mais quand je lance mes tests, je reçois l'erreur suivante:

RuntimeError: Attempted to generate a URL without the application context being pushed. This has to be executed when application context is available. 

googler cela me dit (je pense) que l'utilisation du client de test devrait créer un contexte d'application automatique. Qu'est-ce que je rate?

Répondre

1

La réalisation de requêtes avec le client de test pousse effectivement un contexte d'application (indirectement). Cependant, vous confondez le fait que url_for est visuellement dans l'appel de demande de test avec l'idée qu'il est réellement appelé à l'intérieur. L'appel url_for est évalué en premier, le résultat est passé à client.get.

url_for est typiquement destiné à générer des URL au sein de l'application, les tests unitaires sont externe. Généralement, vous écrivez exactement l'URL que vous essayez de tester dans la requête au lieu de la générer.

self.client.get('/users/create') 

Si vous voulez vraiment utiliser url_for ici, vous devez le faire dans un contexte d'application. Notez que lorsque vous vous trouvez dans un contexte d'application mais pas dans un contexte de demande, vous devez définir la configuration SERVER_NAME et également transmettre _external=False. Mais encore une fois, vous devriez probablement écrire l'URL que vous essayez de tester.

app.config['SERVER_NAME'] = 'localhost' 

with self.app.app_context(): 
    url = url_for(..., _external=False) 

self.client.get(url, ...)