4

我们正在亚马逊网络服务堆栈之上构建一个网络应用程序,到目前为止我很喜欢它。

我们还充分利用了测试驱动开发,这也被证明是非常棒的。

我只是希望有人可以帮助我解决我遇到的与 Amazon SimpleDB 的“最终一致性”相关的问题。

出现问题的最佳示例是在添加用户的单元测试中,然后通过调用获取新添加的用户来检查用户是否已成功添加。

我可以轻松地继续为此编写测试,并且一切都可以正常工作,但是我知道“最终一致性”以及当我调用获取用户时,用户实际上可能不是还添加了。显然如果调用了 fetch user 函数并且用户不在系统中,它会返回 false 或失败。

我想知道处理这个问题的最佳方法是什么?我已经看到了制作一个在请求之间休眠 5 秒并尝试 10 次的函数的建议。我还看到了具有指数退避的解决方案。最佳解决方案是什么?

4

3 回答 3

5

我建议不要使用实际的 SimpleDB 服务来对您自己的代码进行单元测试。您将测试您的代码 + SimpleDB 客户端 + 网络 + SimpleDB 本身。您需要的是模拟 SimpleDB 客户端来运行单元测试。这样,您只测试需要测试的代码。测试驱动的开发要求您不要测试数据库是否在您的代码的单元测试中工作。

如果您正在测试您自己的 SimpleDB 客户端代码,您可以使用模拟 SimpleDB 服务或类似M/DB的东西,它是您可以在本地运行的 SimpleDB 克隆。

But this brings up a larger issue because SimpleDB provides eventual-consistency and not read-your-writes consistency. Your code will absolutely need to be able to deal with the fact that a newly added item will not immediately be returned from a get or a query.

I have no reason to think that your code can't handle it. I'm just saying that as a general rule when you run into problems like these with tests, it hints at issues that need to be considered with the code being tested. You may find that you want either a general layer of caching between your app code and SimpleDB or you may want a session cache that can provide read-your-writes consistency.

于 2009-09-11T17:23:17.080 回答
0

那么,您是在测试数据库还是与之相悖的代码?如果您正在测试针对数据库的代码,那么您应该进行期望代码添加用户的测试,然后直到某个随机时间过去后才返回用户。显然,这是最容易设置的,使用伪造的数据库跟踪自上次请求以来的时间量,并且仅在自初始请求过去后的指定时间后返回预期值。您将进行类似的测试,其中将伪造设置为从不返回值,设置为立即返回,等等。您伪造的仪器以跟踪交互,您可以在测试中设置您想要的代码行为,以便您的代码遵循预期的行为(例如,至少轮询两次)。

于 2009-09-05T13:44:36.860 回答
0

First, as @Mocky stated, hitting the real database in unit tests is wrong. You might do that in integration tests, but these would work because all your unit tests pass.

关于意识到最终一致性的单元测试,这里有一些想法:

  1. 测试用户在写入后从 simpledb 返回(没有 ec 的影响) put user get user test sameness

  2. 测试用户在写入(ec 效果)之后没有从 simpledb 返回用户 put user get user accept an error

  3. 测试处理来自 ec 的错误获取用户 + 接受错误测试错误被处理

我正在考虑使用一层内存缓存(或弹性缓存)来提供缓存用户,因此当用户被写入 simpledb 时,它们也会被发送到缓存。并且当 simpledb 错误发生时,在代码确定确实没有这样的用户之前,接下来会检查缓存。

(实际上很想听听你对最后一段的看法)

于 2011-12-09T11:00:05.343 回答