我正在编写一些使用Riak DB的代码,我希望在每次测试开始时将数据库重置为已知状态。
有没有办法彻底截断riak数据库?如何在测试结束时在事务内部执行并回滚?
目前我使用了一些像这样的代码:
riak.buckets.each do |bucket|
bucket.keys.each do |key|
bucket.delete(key)
end
end
但我想在每次测试开始时这样做都会很慢。
答案 0 :(得分:3)
我认为每个面向测试的开发人员在与Riak合作时都面临着这种困境。正如Christian所提到的,Riak没有回滚的概念。并且没有可以发出的单个“truncate database”命令。
您可以使用3种方法:
清除测试群集上的所有数据。这实质上意味着发出shell命令(假设您的测试服务器与您的测试套件在同一台机器上运行)。如果您使用的是内存后端,则表示在每次测试之间发出riak restart
。对于其他后端,您必须停止节点并删除整个数据目录并再次启动它:riak stop && rm -rf <...>/data/* && riak start
。 PROS:在每次测试之间擦除群集数据。缺点:这很慢(当你考虑关机和重启时间),从你的测试套件发出shell命令通常很尴尬。 (旁注:虽然每次测试之间可能会很慢,但您可以在每次运行整个测试套件之前随时清除数据目录。)
如上所述,在测试群集上循环遍历所有存储桶和密钥并将其删除。 PROS:易于理解和实施。缺点:也很慢(在每次测试之间运行)。
让每个测试自行清理。因此,如果您的测试创建了User对象,请确保在测试结束时为该对象发出DELETE命令。 (可选)在创建用户之前,首先测试用户不存在。 (以确保先前的测试清理完毕)。 PROS:易于理解和实施。快速(绝对比在每个测试之间循环遍历所有桶和密钥更快)。缺点:开发人员在每次插入后都很容易忘记清理。
在讨论了这些方法之后,我决定使用#3(经常在每个测试套件运行之前擦除测试服务器数据目录)。
关于减轻'每个测试的缺点的一些想法清理自己,手动'的方法:
使用以随机顺序运行测试的测试框架。很多框架,比如Ruby的Minitest,开箱即用。这通常有助于捕获依赖于其他测试的测试,方便忘记清理
在测试运行后定期检查测试集群(通过列表存储桶),以确保没有任何剩余。实际上,您可以在每个测试套件的末尾以编程方式执行此操作(就像执行存储桶列表并确保它为空一样简单)。
(这是一般的良好测试实践,但与Riak特别相关)编写较少的测试数据。保持单元测试之间的严格划分(测试对象状态和行为,而不是命中数据库)和集成或功能测试(确实击中了数据库)。 Make sure there's a lot more of the former than the latter.换句话说 - 您不必测试数据库的工作情况,每个单元测试。相信它(尽管很明显,在集成测试期间验证)。
例如,如果您正在使用Riak和Ruby on Rails,并且您正在测试模型,请不要调用test_user.save!
来验证用户实例是否有效(就像我曾经做过的那样,入门)。您只需测试test_user.valid?
,并了解在实际使用过程中,save的调用将相应地起作用(或失败)。考虑使用Mockist-style testing,它验证是否实际调用 save!
函数,而不是实际保存到数据库然后回读。等等。
答案 1 :(得分:1)
这里几乎没有答案。
答案 2 :(得分:0)
由于Riak中没有交易或回滚的概念,这是不可能的。然而,内存后端通常用于测试,因为它支持Bitcask(自动到期)和LevelDB(二级索引)的功能。每当需要清除数据库时,只需要重新启动节点。
如果在测试时使用Bitcask或LevelDB,清除数据库的最有效方法是关闭节点并简单地删除数据目录。