【问题标题】:How to implement BDD on very complex business rules?如何在非常复杂的业务规则上实现 BDD?
【发布时间】:2013-12-03 05:29:59
【问题描述】:

我正在学习单元测试和 BDD 的艺术,在我的公司中没有人遵循这种方法。我尝试了很多自己学习它,但在尝试了几天后卡在某个地方并放弃了。一段时间后,我再次从某人那里获得灵感,并尝试再次学习在这些水域游泳。

我最近开发了一个 Windows 服务,它开始时很小,但最终变成了一大堆杂乱的业务规则。以下是该服务功能的简要概述。

  1. 登录到数据库“服务正在启动...”

  2. 从需要发布到另一个 Web 服务的数据库中获取数据

  3. 如果没有数据要发布日志到数据库“没有数据要处理...” 并退出服务

  4. 如果数据包含重复值记录到数据库“重复数据 找到,将跳过这条记录。”

  5. 更新发现重复数据的记录的状态 对某事,例如302

  6. 如果数据为空,则记录到数据库“记录包含空值,无法处理。”

  7. 适当地更新记录的状态,例如310

  8. 如果由于某种原因数据库不可用或宕机,登录文件“Database is down…”

  9. 如果服务宕机,我们必须将数据日志发布到数据库“接收器服务宕机”。

  10. 登录数据库“Exiting service…”

所以我的服务基本上从数据库中检索一些数据,从中创建 JSON 请求并将其发布到另一个服务。

它还解析来自该服务的响应并记录数据是否成功发布。我刚刚输入了一些当前在服务中实施的业务规则,让您了解底层的内容。我正在学习 BDD 和单元测试,并且很想知道专家将如何编写测试这些复杂业务规则的测试用例?

据我了解,BDD 不需要在内部关注服务的编写方式,而是会测试服务应该满足的场景,例如

使用重复数据执行windows服务时

  • 它应该记录到数据库“发现重复数据,这条记录将被 跳过。”
  • 应该将记录的状态更新为 302

我可以编写多个场景来测试服务的某些功能。这是正确的方法还是我应该纠正在每个测试中测试每个业务规则的大量场景?

其次,由于服务与数据库以及 Web 服务通信,我如何测试服务发送和接收的 HttpRequest 和 HttpResponse?

最后,我如何实际测试像我上面写的业务规则这样复杂的东西,如果我简单地断言服务调用了某个类的某个特定方法就足够了吗?我们怎么知道只需调用某个方法就能执行正确的任务?

【问题讨论】:

    标签: web-services unit-testing moq bdd mspec


    【解决方案1】:

    一些简单的想法可以帮助您正确看待它:

    1. 你说学习...
      记住这一点,不要纠结于完美、正确或适当的事情。你正在学习,可以随意犯错,并且知道你会随着你的进步而进步。坚持下去,不断练习,你会变得更好,你做的越多,思考的越多,就会感觉越自然。
    2. BDD 测试行为。
      你用它来表示系统应该以特定的方式运行,这意味着它必须是系统。有时,您可能仍会存留一些虚拟服务(如假信用卡处理服务),但在大多数情况下,您希望这能证明系统按需要工作。将它们视为更多的集成测试。
    3. 您的 BDD 测试应该推动您的单元测试。
      编写 BDD 测试以使其失败,然后让它决定应该编写哪些单元测试,以使您的系统按预期运行。这实质上意味着您的每个 BDD 测试也将引入一组单元测试。
    4. 总之,让BDD驱动TDD 您将获得适当的测试平衡。起点是您的第一个 BDD 测试。

    在您的场景中,如果您的系统应该提醒用户他们正在尝试添加副本,那么这是一个有效的测试。

    测试 Http 请求和响应的烦人之处在于您最终会进行字符串比较,但这是可行的。 BDD 测试应该只关心系统是否按照您的预期做出响应。

    单元测试应该与您正在做的事情相隔离,因此您将在 Web 服务内部进行单元测试以确保其正确响应,但您不会在外部进行单元测试来调用 Web 服务;而是将其提取出来。

    这一切都可以变得非常哲学化,这可能会涉及到什么是好的单元测试与什么是好的行为测试,但希望这可以帮助您开始前进。

    【讨论】:

    • 非常感谢您的宝贵回答。它消除了我脑海中的许多困惑。在我非常具体地了解我当前的场景之前,我想问一下我编写的示例场景当执行带有重复数据的 windows 服务时,它应该记录到数据库“找到重复数据,这条记录将被跳过”。它应该将记录的状态更新为 302 从 BDD 的角度来看,这种情况是否对您有效,因为它没有描述完整的服务行为,只是一种情况......
    • @AfrazAli 那部分我不完全确定。在我看来,当您尝试复制记录时,您会提醒用户。更新记录以指示“用户”尝试插入重复记录似乎也是有效的。但是,您将该尝试记录为“302”这一事实似乎有点太低级了,至少就 BDD 测试而言。类似于对接口进行编程,您可能希望公开一些处理该逻辑的方法,但对 API(以及 BDD 测试)隐藏这些细节。它应该可以调用类似wasDupeAttempted()
    • 更进一步,我认为您的 BDD 测试真的不应该关心写入数据库的内容,只要您的应用程序按预期运行即可。写入数据库的信息可能对 BDD 来说太低级了,无法关心,但是 BDD 应该能够验证该对象上的内容,例如它是否已保存,并且保存会导致它找到一个重复的条目,并且它正确地暴露了重复输入的尝试,以便您可以对其做出反应。不过,它不应该关心实际写入数据库的内容。
    • 好的,谢谢达蒙。您能否告诉我您将如何测试我用来发布和接收 json 请求的 HttpWebRequest 或 HttpWebResponse 类?还是我应该为此发布一个单独的问题?
    • 标记为答案,因为它确实向我展示了该做什么。现在我需要研究如何做部分:)
    猜你喜欢
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多