英文:
go/appengine: faster datastore tests
问题
最近我一直在尝试使用golang和Google的App Engine。
在实现存储库时,我发现单元测试执行非常慢。
我在每个测试中调用ctx,_ := aetest.NewContext(nil)
以获取一个干净的数据库。这会在每个测试中启动一个新的服务器,导致测试变慢。
最近,我一直在尝试通过在TestMain中启动来解决这个问题。
var ctx aetest.Context
func TestMain(m *testing.M) {
ctx,_ = aetest.NewContext(nil)
code := m.Run()
ctx.Close()
os.Exit(code)
}
func TestMyRepository(t *testing.T){
cleanDatastore()
repo := &MyRepository{ctx}
repo.DoSomething()
}
在函数cleanDatastore
中,我执行了一个bash脚本,基本上运行了一个SQLite命令来清理保存在/tmp
中的本地数据库。
#!/usr/bin/env bash
PATH=$1
cd $PATH
echo "Cleaning datastore..."
/usr/bin/sqlite3 datastore "delete from \"dev~testapp!!EntitiesByProperty\";"
/usr/bin/sqlite3 datastore "delete from \"dev~testapp!!Entities\";"
echo "Datastore is clean."
我正在尝试的方法有意义吗?还是有更简单的方法来提高测试时间?
英文:
Recently I've been playing around with golang and google's app engine.
I've been experiencing really slow unit test executions when implementing repositories.
The thing I do is to call ctx,_ := aetest.NewContext(nil)
in each test in order to obtain a clean database. This starts a new server in each test and thus leads in slow testing.
Lately I've been trying to work this around by starting it in TestMain.
var ctx aetest.Context
func TestMain(m *testing.M) {
ctx,_ = aetest.NewContext(nil)
code := m.Run()
ctx.Close()
os.Exit(code)
}
func TestMyRepository(t *testing.T){
cleanDatastore()
repo := &MyRepository{ctx}
repo.DoSomething()
}
In the function [cleanDatastore](https://gist.github.com/NewestUser/9468b0a7b763c84a8625 "gist") I've been executing a bash script that basically runs a SQLite command to clean the local database saved in /tmp.
#!/usr/bin/env bash
PATH=$1
cd $PATH
echo "Cleaning datastore..."
/usr/bin/sqlite3 datastore "delete from \"dev~testapp!!EntitiesByProperty\";"
/usr/bin/sqlite3 datastore "delete from \"dev~testapp!!Entities\";"
echo "Datastore is clean."
Is what I am trying to do making any sense or is there a simpler way to achieve better testing time.
答案1
得分: 1
一个无类型、仅包含键的查询(获取所有实体的键,无论类型如何)应该可以帮助:
q := datastore.NewQuery("").KeysOnly()
然后,你可以循环遍历所有这些键,并删除每一个,例如:
for t := q.Run(ctx); ; {
key, err := t.Next(nil)
if err == datastore.Done {
break
}
if err != nil {
serveError(c, w, err)
return
}
datastore.Delete(ctx, key)
}
将键放入数组并使用DeleteMulti
可能会稍微快一些,但在本地数据存储中,我怀疑这不会产生可测量的差异。
英文:
A kindless, keys-only query (getting the keys of all entities, regardless of kind) should help:
q := datastore.NewQuery("").KeysOnly()
and then, you loop over all such keys and delete each of them, e.g:
for t := q.Run(ctx); ; {
key, err := t.Next(nil)
if err == datastore.Done {
break
}
if err != nil {
serveError(c, w, err)
return
}
datastore.Delete(ctx, key)
}
It may be slightly faster to get the keys into an array and use DeleteMulti
, but, on a local datastore, I suspect that would not make a measurable difference.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论