google-app-engine - 延迟测试清理的行为因我调用它的位置而异
问题描述
我有一个遵循以下结构的测试:
var testInstance aetest.Instance // initialized by a TestMain
TestThing(t *testing.T) {
defer cleanupGoogleDatastore(t, testInstance)
// insert basic test fixtures
// insert some new records here
// test assertions, etc.
}
该cleanupGoogleDatastore
方法只是为特定实体类型的所有实体运行数据存储查询,然后将它们一一删除。来源:
func cleanupGoogleDatastore(t *testing.T, testInstance aetest.Instance) {
q := datastore.NewQuery("Order")
ctx := GetContext(t, testInstance)
scanner := q.Run(ctx)
for {
var o model.Order
key, err := scanner.Next(&o)
if err == datastore.Done {
return
}
if err != nil {
t.Fatal(err.Error())
}
err = datastore.Delete(ctx, key)
if err != nil {
t.Fatal(err.Error())
}
}
}
我遇到的问题是,在“基本测试装置”之后插入的记录不会被这个延迟清理语句删除。
如果我将此测试功能更改为如下所示:
var testInstance aetest.Instance // initialized by a TestMain
TestThing(t *testing.T) {
defer cleanupGoogleDatastore(t, testInstance)
// insert basic test fixtures
// insert some new records here
defer cleanupGoogleDatastore(t, testInstance)
// note that I have to call it TWICE - just moving it here is not enough.
// test assertions, etc.
}
那么新创建的记录也会在测试结束时被删除。我的理解是,deferred
函数只是在原始函数范围的末尾被调用,这意味着在测试结束之前不会构造和运行查询,但这里似乎并非如此。似乎在调用 defer 语句然后在测试结束时执行查询时正在构造查询。
我已经尝试过cleanupGoogleDatastore
关闭(例如defer func() { cleanupGoogleDatastore(t, testInstance }()
,这并没有改变任何东西。
我怀疑这是在我调用 defer 而不是在调用函数时评估函数参数的情况,但是由于两者t
都是testInstance
指针而不是直接值,我不确定这是如何发生的。没有其他证据表明这两个值发生了变化。在不同的逻辑评估点打印出两个结构的字段并没有揭示任何新内容。
这里发生了什么?
解决方案
事实证明,这是本地 App Engine Datastore 存根的故意属性,默认情况下会返回弱一致的查询。我能够通过将代码更改为cleanupGoogleDatastore
依赖祖先查询来解决此问题,该祖先查询成功找到并删除了所有实体。另一种方法是将 aetest.Instance 设置为强一致,但我不想在我的所有测试中强制执行强一致的行为 - 只是这个。
推荐阅读
- python - 如何检查我的客户端套接字中的 recv 是否为空
- javascript - 使用 Javascript 更改图像源 - 基本功能不起作用
- rest - 有关 HTTP 请求为何被 403 处理的详细信息
- time - Jmeter在分布式模式下的响应时间突然增加
- .net - 如何在 VB.net 中正确地将字符串转换为十进制
- flutter - 颤振:showDialog() 上的 setState
- c# - 从后面的代码启动命令行 exe (ngrok) 的正确方法
- django - 如何在 JSONField 上使用 django-filter
- c# - 引用由第 3 方可执行文件在构建期间创建的 DLL
- python - 来自 Python request.session() 的请求没有记录在 Charles 中