通过导入Google App Engine的测试平台打破了Flask-Login软件包

时间:2012-04-03 19:59:19

标签: python google-app-engine unit-testing flask

使用带有testbed 0.8的Google App Engine 1.6.4 Flask,特别是Flask-Login 0.1包(source)时,我遇到了一个奇怪的问题线单元测试。

以下是演示此问题的示例。注意注释行(from google.appengine.ext import testbed)。评论此行时,测试按预期工作。

取消注释此行时,Flask-Login的{​​{3}}装饰器停止识别登录用户,即current_user.is_authenticated()返回False。似乎罪魁祸首是导入testbed

#!/usr/bin/env python2.7
import unittest
import sys
from flask import Flask, current_app, url_for
from flaskext import login

sys.path.append('/usr/local/google_appengine')

# Go ahead and uncomment this:
# from google.appengine.ext import testbed

app = Flask('test')
app.secret_key = 'abc'

login_manager = login.LoginManager()
login_manager.setup_app(app)
login_manager.login_view = 'index'

class User(login.UserMixin):
    def get_id(self):
        return "1"

@login_manager.user_loader
def load_user(user_id):
    return User()

@app.route('/')
@login.login_required
def index():
    pass

@login_manager.unauthorized_handler
def unauthorized():
    raise Exception("Unauthorized.")

class MyTest(unittest.TestCase):
    def setUp(self):
        self.app = app
        self.client = app.test_client()

    def test_user(self):
        with self.app.test_request_context():
            logged_in = login.login_user(User())
            r = self.client.get('/')

if __name__ == '__main__':
    unittest.main()

具体例外是:

ERROR:test:Exception on / [GET]
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/app.py", line 1504, in wsgi_app
    response = self.full_dispatch_request()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/app.py", line 1264, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/app.py", line 1262, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask-0.8-py2.7.egg/flask/app.py", line 1248, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask_Login-0.1-py2.7.egg/flaskext/login.py", line 479, in decorated_view
    return current_app.login_manager.unauthorized()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Flask_Login-0.1-py2.7.egg/flaskext/login.py", line 250, in unauthorized
    return self.unauthorized_callback()
  File "./test.py", line 34, in unauthorized
    raise Exception("Unauthorized.")
Exception: Unauthorized.

我期望的行为是导入(和使用)testbed对Flask上下文堆栈没有影响,并且,通过扩展,Flask-Login将继续在单元测试环境中工作,即使{{已导入1}}。

我已经盯着这一点,但无济于事,并且对于解决这个问题的任何见解和建议表示感谢。

感谢您的阅读。

1 个答案:

答案 0 :(得分:4)

测试平台为许多GAE服务使用单独的存根,包括数据存储和用户服务。

我不熟悉flask,但如果登录需要用户存在于数据库中,那么它将失败,因为testbed使用单独的数据库。您必须首先将用户数据加载到测试数据库中。

此外,如果您包含测试平台,则必须先进行一些初始化调用以设置存根,然后才能使用它。 https://developers.google.com/appengine/docs/python/tools/localunittesting