我对这个问题的处理方法可能完全错误,所以请不要犹豫,纠正它。我还在问题标题中添加了ATDD,因为我试图测试我的web api的输出,这比单元测试更大。
我正在使用:
我使用样板代码设置我的测试:
self.testbed = testbed.Testbed()
self.testbed.activate()
self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
self.testbed.init_datastore_v3_stub()
然后我调用模拟对象设置来设置我的实体并将它们保存到testbed数据存储区。我使用计数器添加5位艺术家,其中包括artist_id 1 - 5:
def add_mock_artist_with(self, artist_id, link_id, name):
new_artist = dto.Artist(key_name=str(artist_id),
name=name,
link_id= str(link_id))
new_artist.put()
我的测试是我的网络API返回:
{
"artists": [
{
"artist": {
"name": "Artist 1",
"links": {
"self": {
"href": "https://my_server.com/artist/1/"
}
}
}
},
.
.
.
{
"artist": {
"name": "Artist 5",
"links": {
"self": {
"href": "https://my_server.com/artist/5/"
}
}
}
}
],
"links": {
"self": {
"href": "https://my_server.com/artists/"
}
}
}
最初,我认为如果每次运行测试时我都要启动一个新的测试床,我可以指望我的艺术家按顺序进入数据存储,因此会得到ID 1 - 5.我的测试最初通过,但随着时间的推移,由于ID不匹配而开始失败(我会得到一个类似的链接:“href”:“https://my_server.com/artist/78/”)。依靠依次生成的ID我感到有点内疚,所以我决定解决它。我偶然发现密钥的概念是名称或生成的id。我更新了我要使用的返回JSON的模板:
artist.key().id_or_name()
对于模拟对象,我在构造时提供了键名:
key_name=str(artist_id)
对于非模拟构造,我没有包含该行代码并让GAE分配id。
由于我的模板使用key()。id_or_name()来输出属性,所以一切顺利,测试通过。
但是,现在当我测试单个艺术家的回归时,可以通过http://my_server.com/artist/5/跟随,我的测试失败了。要从数据存储中抓取艺术家,我使用以下代码:
def retrieve_artist_by(id):
artist = dto.Artist.get_by_id()
在制作中,这样可以正常工作,因为它都是基于id的。但是,在我的测试中,它没有找到任何东西,因为我在我的模拟构造中使用了key_name = str(artist_id),并且名称与id不同。
我希望有类似的东西:
artist = dto.Artist.get_by_id_or_name()
有什么想法吗?
答案 0 :(得分:0)
也许不是您正在寻找的答案,但可以了解您是在生产服务器还是部署服务器上运行并执行不同的代码路径。
In Python, how can I test if I'm in Google App Engine SDK? http://code.google.com/appengine/docs/python/runtime.html#The%5FEnvironment
os.environ['SERVER_SOFTWARE'].startswith('Development')
答案 1 :(得分:0)
这就是我现在正在使用的内容。我不喜欢它,但它应该在prod中具有高效性,因为我将使用生成的ID。在测试中,如果它没有通过id找到它,它将尝试按名称查找。
def retrieve_artist_by(id):
artist = dto.Artist.get_by_id(id)
if artist is None:
artist = dto.Artist.get_by_key_name(str(id))
return artist