mgi*_*uca 21 python google-app-engine
我正在使用Google App Engine testbed框架编写带有模拟对象的测试用例.这在此处记录.我已经使用mock database(Testbed.init_datastore_v3_stub)很好地运行了数据存储区测试,这使我的测试用例可以在一个快速,新鲜的数据库上运行,并为每个测试用例重新初始化.现在我想测试依赖于当前用户的功能.
还有一个名为testbed的服务Testbed.init_user_stub,我可以激活它来获取"假的"用户服务.不幸的是,这个似乎没有任何文档.我正在激活并使用它:
import unittest
from google.appengine.ext import testbed
from google.appengine.api import users
class MyTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
self.testbed.init_user_stub()
def testUser(self):
u = users.get_current_user()
self.assertNotEqual(u, None)
Run Code Online (Sandbox Code Playgroud)
问题是我没有找到任何方法告诉"假"用户服务来验证"假"用户.所以运行那个测试,我(可以预见)得到
AssertionError: None == None
Run Code Online (Sandbox Code Playgroud)
意味着假用户服务告诉我的应用程序当前用户没有登录.如何判断虚假用户服务假装用户已登录?理想情况下,我希望能够指定假用户的昵称,电子邮件,user_id以及他们是否是管理员.这似乎是一个非常普遍的想要(因为你需要测试应用程序的行为时a)没有人登录,b)用户登录,和c)管理员登录),但谷歌搜索"init_user_stub"几乎没有返回任何内容.
注意:如果要测试上述程序,则需要将其添加到顶部:
import sys
sys.path.append('/PATH/TO/APPENGINE/SDK')
import dev_appserver
dev_appserver.fix_sys_path()
Run Code Online (Sandbox Code Playgroud)
这到底:
if __name__ == '__main__':
unittest.main()
Run Code Online (Sandbox Code Playgroud)
mgi*_*uca 17
好吧,我认为没有正式的方法可以做到这一点,但我一直在阅读源代码,我找到了一种"黑客"方式来做到目前为止运作良好.(通常我会担心使用未记录的行为,但它是一个测试套件,所以只有它在dev服务器上运行才有意义.)
开发服务器根据三个环境变量计算出当前登录的用户:
您可以像使用os.environ任何其他环境变量一样设置它们,它们立即生效(显然这在生产服务器上不起作用).但是您可以将它们与testbed的user_stub一起使用,并且当您停用测试平台时它们将被重置(您应该这样做tearDown,因此您可以为每个测试用例获得一个全新的环境).
由于设置环境变量有点笨拙,我写了一些包装函数来打包它们:
import os
def setCurrentUser(email, user_id, is_admin=False):
os.environ['USER_EMAIL'] = email or ''
os.environ['USER_ID'] = user_id or ''
os.environ['USER_IS_ADMIN'] = '1' if is_admin else '0'
def logoutCurrentUser():
setCurrentUser(None, None)
Run Code Online (Sandbox Code Playgroud)
Bij*_*jan 11
以下是模拟已登录用户的工作原理:
self.testbed.setup_env(USER_EMAIL='usermail@gmail.com',USER_ID='1', USER_IS_ADMIN='0')
self.testbed.init_user_stub()
Run Code Online (Sandbox Code Playgroud)
sie*_*z0r 10
除了Bijan的回答:
实际办理登机手续google.appengine.api.users如下:
def is_current_user_admin():
return (os.environ.get('USER_IS_ADMIN', '0')) == '1'
Run Code Online (Sandbox Code Playgroud)
因此,关键是将环境变量设置USER_IS_ADMIN为'1'.这可以通过多种方式完成,但请注意您正在修改全局变量,因此这可能会影响其他代码.关键是要做好适当的清理工作.
可以使用Mock库来修补os.environ,使用Testbed或滚动他们自己的创作方式.我更喜欢使用,Testbed因为它暗示黑客是与appengine相关的.在3.3之前的Python版本中不包含Mock,因此这增加了额外的测试依赖性.
额外注意:当我使用我更喜欢使用的unittest模块addCleanup而不是tearDown因为setUp失败时也会调用清理.
示例测试:
import unittest
from google.appengine.api import users
from google.appengine.ext import testbed
class AdminTest(unittest.TestCase):
def setUp(self):
tb = testbed.Testbed()
tb.activate()
# ``setup_env`` takes care of the casing ;-)
tb.setup_env(user_is_admin='1')
self.addCleanup(tb.deactivate)
def test_is_current_user_admin(self):
self.assertTrue(users.is_current_user_admin())
Run Code Online (Sandbox Code Playgroud)
注意: Testbed.setup_env 应该在之后调用 Testbed.activate.在激活时Testbed拍摄快照,os.environ在停用时恢复该快照.如果Testbed.setup_env在激活之前调用,os.environ则修改real 而不是临时实例,从而有效地污染环境.
这表现得如下:
>>> import os
>>> from google.appengine.ext import testbed
>>>
>>> tb = testbed.Testbed()
>>> tb.activate()
>>> tb.setup_env(user_is_admin='1')
>>> assert 'USER_IS_ADMIN' in os.environ
>>> tb.deactivate()
>>> assert 'USER_IS_ADMIN' not in os.environ
>>>
Run Code Online (Sandbox Code Playgroud)
这会污染环境:
>>> import os
>>> from google.appengine.ext import testbed
>>>
>>> tb = testbed.Testbed()
>>> tb.setup_env(user_is_admin='1')
>>> tb.activate()
>>> assert 'USER_IS_ADMIN' in os.environ
>>> tb.deactivate()
>>> assert 'USER_IS_ADMIN' not in os.environ
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3240 次 |
| 最近记录: |