我正在尝试测试在App Engine上运行的应用程序。我正在使用the Testbed framework,到目前为止,它的作用就像一个魅力,除了以下意外行为:
这样的测试工作得很好(没有框架的简化版本):
from google.appengine.ext import db, testbed
testbed = testbed.Testbed()
testbed.activate()
testbed.init_datastore_v3_stub()
class Foo(db.Model):
pass
# now for the tests:
key = Foo().put()
assert key == db.Key.from_path('Foo', key.id())
assert Foo.all(keys_only=True).get() == db.Key.from_path('Foo', key.id())
assert db.get(db.Key.from_path('Foo', key.id())) # fails!
testbed.deactivate()
但是,以下将失败(再次,简化版):
from google.appengine.ext import db, testbed
testbed = testbed.Testbed()
testbed.activate()
testbed.init_datastore_v3_stub()
from myapp.models import Foo
# now for the tests:
key = Foo().put()
assert key == db.Key.from_path('Foo', key.id()) # fails!
assert Foo.all(keys_only=True).get() == db.Key.from_path('Foo', key.id()) # fails!
assert db.get(db.Key.from_path('Foo', key.id())) # fails!
# however, the following will succeed:
assert key == db.Key.from_path('Model', key.id())
assert Foo.all(keys_only=True).get() == db.Key.from_path('Model', key.id())
assert db.get(key)
testbed.deactivate()
测试期间模型名称在哪里消失?为什么它只发生在导入的模块中?
修改
感谢proppy,拼写错误。
Nick Johnson,让我试着更好地解释一下。
当我从testbed
数据存储区存根查询结果时,我得到一个实体,就像我期望的那样。但是,当我在该实体上调用.key()
方法时,我会得到类似datastore_types.Key.from_path(u'Model', 1L, _app=u'testbed-test')
的内容,而Model
显然不是我的实体的正确类型。
当我尝试获取该密钥的实体(datastore_types.Key.from_path(u'Model', 1L, _app=u'testbed-test')
)时,它的工作正常。
问题是,当我只知道数据存储区实体的id
时,我尝试使用db.Key.from_path(...)
手动构建密钥。
例如,类型应为User
,因此我可以使用db.Key.from_path('User', 1)
构建密钥。但我无法使用该密钥从数据存储区中获取实体。但是,我可以使用db.Key.from_path('Model', 1)
,但正如我所说,Model
不是正确的数据存储类型。
换句话说:
from myapp.models import User
User(email='dont@write.us').kind() # returns 'Model', not 'User'!
请注意,只有在使用testbed
时才会在生产环境或开发服务器中发生此意外行为,并且只有在我的应用程序代码中定义了db.Model
子类时(即不在测试中)案件本身)。
我没有使用Django,我正在使用Pyramid进行遍历,但我在这里运行的单元测试不会调用任何特定于框架的代码。
请注意我还没有尝试使用同样的事情也发生在ndb
但ndb
上。
编辑2:
显然我没有注意到我的所有类都是google.appengine.ext.db.polymodel.PolyModel
子类的子类,因此键实际上已正确设置为Model
,因为类型为Model
所有PolyModel
子类。
答案 0 :(得分:0)
要回答我自己的问题,这个问题是由我在项目中使用的名为migrations.py
的文件引起的,该文件使用具有不同属性的类重新定义了我的模型。当我运行测试时,nose
尝试导入所有可用文件以发布覆盖结果,这导致模块定义冲突,从而导致所有混淆。