Testbed中的数据存储区键不正确

时间:2012-01-17 00:55:42

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

我正在尝试测试在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子类。

1 个答案:

答案 0 :(得分:0)

要回答我自己的问题,这个问题是由我在项目中使用的名为migrations.py的文件引起的,该文件使用具有不同属性的类重新定义了我的模型。当我运行测试时,nose尝试导入所有可用文件以发布覆盖结果,这导致模块定义冲突,从而导致所有混淆。