为什么要这样枚举呢?
对于以下函数,
KEYS = {}
def get(kind):
"returns a new key of a particular kind"
global KEYS
try:
return KEYS[kind].pop(0)
except (KeyError, IndexError):
handmade_key = Key.from_path(kind, 1)
start, end = allocate_ids(handmade_key, 3)
id_range = range(start, end+1)
KEYS[kind] = [Key.from_path(kind, id) for id in id_range]
for key in KEYS[kind]:
print "within get() -> %s:%s"%(key, key.id())
return get(kind)
我编写了以下单元测试
def testget2000(self):
s = set()
for i in range(0, 7):
key = keyfactory.get("Model1")
print "from get() -> %s:%s"%(key, key.id())
s.add(key)
self.assertEqual(len(s), 7)
self.assertEqual(len([k.id for k in s]), 2000)
并收到以下错误
<小时>失败:testget2000(keyfactory_test.ModelTest)
回溯(最近一次调用最后一次): 文件“/home/vertegal/work/ei-sc/appengine/keyfactory_test.py”,
第 36 行,在 testget2000 中 self.assertEqual(len(s), 7) 断言错误:断言错误:5!= 7
-------------------->>开始捕获标准输出 <<
来自 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAQw:1 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAQw:1 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBAw:4 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBQw:5 在 get() 内 -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBgw:6 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBAw:4 从 get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBQw:5
我真的不明白为什么第一次要在“within”之前打印“from”。另外,为什么它会两次分配相同的前几个 id 呢?我是否创建了一些奇怪的闭包?异常处理程序中的 KEYS 与外部的对象是否不同?我迷路了。
For the following function
KEYS = {}
def get(kind):
"returns a new key of a particular kind"
global KEYS
try:
return KEYS[kind].pop(0)
except (KeyError, IndexError):
handmade_key = Key.from_path(kind, 1)
start, end = allocate_ids(handmade_key, 3)
id_range = range(start, end+1)
KEYS[kind] = [Key.from_path(kind, id) for id in id_range]
for key in KEYS[kind]:
print "within get() -> %s:%s"%(key, key.id())
return get(kind)
I have written the following unit test
def testget2000(self):
s = set()
for i in range(0, 7):
key = keyfactory.get("Model1")
print "from get() -> %s:%s"%(key, key.id())
s.add(key)
self.assertEqual(len(s), 7)
self.assertEqual(len([k.id for k in s]), 2000)
And get the following error
FAIL: testget2000 (keyfactory_test.ModelTest)
Traceback (most recent call last): File "/home/vertegal/work/ei-sc/appengine/keyfactory_test.py",
line 36, in testget2000
self.assertEqual(len(s), 7)
AssertionError: AssertionError: 5 != 7-------------------- >> begin captured stdout <<
from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAQw:1 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAQw:1 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAgw:2 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYAww:3 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBAw:4 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBQw:5 within get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBgw:6 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBAw:4 from get() -> agpkZXZ-cXVpenJ5cgwLEgZNb2RlbDEYBQw:5
I really don't understand why it is that "from" is being printed before "within" the first time. Also, why is it that it allocates the same first few ids twice? Am I creating some weird closure? Is KEYS a different object in the exception handler than outside it? I am lost.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
因此,看起来当您捕获的输出开始时,数据存储区为空,但 KEYS[kind] 已填充两个值。数据存储不会两次分配相同的 ID,您只是拥有从未分配过的剩余 ID。要么追踪写入
KEYS
的其他内容,要么在测试开始时将其清除。另外,您似乎正在传递实际的模型类。
Key.from_path
需要一个字符串,例如'Model1'
而不是Model1
。So it looks like when your captured output begins, the datastore is empty but
KEYS[kind]
has two values already populated. The datastore isn't allocating the same IDs twice, you just have leftover IDs that have never been allocated. Either track down what else is writing toKEYS
, or just wipe it out at the beginning of your test.Also, you seem to be passing the actual model class around for kind.
Key.from_path
expects a string, e.g.'Model1'
instead ofModel1
.正如 Drew 所建议的,您可能会添加
到测试的顶部(或者更好的是添加到
setUp
方法),但问题的根源在于设计:使用延迟初始化、可变全局的函数状态很难测试。创建一个 KeyFactory 类,以 KEYS 作为实例变量,可能会更好。您想通过这样做来实现什么目的?
As Drew suggests, you might add
to the top of your test (or better, to a
setUp
method), but the root of your problem is in the design: Functions that use use lazily initialized, mutable global state are difficult to test. Making a KeyFactory class, with KEYS as an instance variable, might serve you better.What is it that you're trying to achieve by doing this?
看起来好像在单元测试开始捕获之前有东西正在调用
get(kind)
,或者在开始之前以某种方式填充KEYS
。也许只需添加一个引发异常或以其他方式在 get(kind) 中打印回溯,并确保它第一次运行是在您的代码中。
It looks like something is calling
get(kind)
before your unit test starts capturing, orKEYS
is being filled somehow before things start.Maybe just add a
raise Exception
or otherwise print the traceback inget(kind)
and make sure the first time it runs is from within your code.