go/appengine: 更快的数据存储测试

huangapple go评论95阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2015年11月26日 07:37:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/33928295.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定