Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
449 views
in Technique[技术] by (71.8m points)

python - 404 Response when running FlaskClient test method

I'm baffled by this. I'm using an application factory in a Flask application and under the test configuration my routes always return 404s.

However when I use Flask-Script and load the app from the interpreter everything works as expected, the response comes back as 200.

Navigating to the URL with the browser works fine

app/__init__.py

def create_app():
 app = Flask(__name__)
return app

sever1.py

from flask import Flask
from flask_script import Manager
from app import create_app  

app = create_app()
app_context = app.app_context()
app_context.push()
manager = Manager(app)


@app.route('/')
def index():
 return '<h1>Hello World!</h1>'

@app.route('/user/<name>')
def user(name):
 return '<h1>Hello, %s!</h1>' % name

@manager.command
def test():
 """Run the unit tests"""
 import unittest
 tests = unittest.TestLoader().discover('tests')
 unittest.TextTestRunner(verbosity=2).run(tests)


if __name__ == '__main__':
 manager.run()

tests/test.py

#imports committed 
def setUp(self):
    self.app = create_app('testing')
    self.app_context = self.app.app_context()
    self.app_context.push() 
    self.client = self.app.test_client()

def test_app_exists(self):
    response = self.client.get('/', follow_redirects=True)
    print(response) #404 :(
    self.assertTrue("Hello World!" in response.get_data()) #this is just an example of how it fails
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're not using the factory pattern correctly. You should use blueprints to collect routes and register them with the app in the factory. (Or use app.add_url_rule in the factory.) Nothing outside the factory should affect the app.

Right now you create an instance of the app and then use that instance to register routes. Then you create a different instance in your tests, which doesn't have the routes registered. Since that instance doesn't have any registered routes, it returns 404 for requests to those urls.

Instead, register your routes with a blueprint, then register the blueprint with the app in the factory. Use the factory to create an app during tests. Pass the factory to the Flask-Script manager. You should not need to push the app context manually.

from flask import Flask, Blueprint
from flask_script import Manager
from unittest import TestCase


bp = Blueprint('myapp', __name__)

@bp.route('/')
def index():
    return 'Hello, World!'

def create_app(config='dev'):
    app = Flask(__name__)
    # config goes here

    app.register_blueprint(bp)

    return app

class SomeTest(TestCase):
    def setUp(self):
        self.app = create_app(config='test')
        self.client = self.app.test_client()

    def test_index(self):
        rv = self.client.get('/')
        self.assertEqual(rv.data, b'Hello, World!')

manager = Manager(create_app)
manager.add_option('-c', '--config', dest='config', required=False)

if __name__ == '__main__':
    manager.run()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...