我是TDD的新手,想知道从哪里开始。我已经阅读了尽可能多的内容,我认为我可以不抛弃,仍然困惑什么测试和什么不测试。例如,我知道,从阅读开始,我们不应该对数据库运行测试,因此进入模拟框架。我们模拟我们的存储库,以便返回虚假数据。我的问题是我们测试数据常量的要求吗?例如,一个要求可能表明,一个人应该总是有一个名字,因此:
Assert.IsNotNull(personObject.Name);
应该永远是真的,但是如何在没有“假”数据的情况下进行测试?我是否愿意测试这种类型的要求?
答案 0 :(得分:4)
让我们按照你的要求“一个人应该总是有一个名字”。我们从哪里开始?
首先,我们需要一些清晰度。我相信当你说“应该总是有一个名字”时,你的意思是“永远不应该有一个空字符串或空字符串”作为名称。
我们在这里的真正含义是“当一个人存储在我们的数据库中时,其名称不能为空或空”。第一道攻击是在数据库中使用约束来强制执行;但是,没有任何东西可以保护您免受流氓DBA删除该约束的影响,因此您可能希望测试您认为对系统的真实情况,如果更改则将由失败的测试标记。为此,您可以编写一个测试,例如“当我的应用程序发送一个具有空名称的人员保存到数据库时,它应该失败”。这不是一个单元测试,它更像是一个集成测试 - 而且它比一个好的旧单元测试更复杂。
但是,这仍然不包括流氓DBA删除约束并直接创建具有空名称的记录的情况。换句话说,您的应用程序无法信任它返回的数据是否正确,因此问题变为:您希望您的域如何处理具有空名称的人的可能性?
一种非常直观的方法可能是强制Person只能使用非null Name构造,否则抛出。这很容易进行单元测试和强制执行,但可能会让开发变得痛苦。更愉快的方法是对Person没有约束,但是Validator类可以验证Person是否有破坏的规则。这更令人满意,因为你现在可以做任何你想要的人(比喻),然后验证该人是否仍然处于有效状态。
这有利于
1)非常容易测试:为这样的验证器创建单元测试是件小事,
2)解决流氓DBA问题:您现在可以通过应用验证器来验证来自应用程序外部或进入应用程序外部的所有内容。
所以,作为我的懒惰开发者,这就是我要开始的地方:使用Validator,因为它解决了我的问题,同时比涉及数据的东西更容易测试。换句话说,一般来说,我倾向于尽可能多地使用单元测试(即完全在内存中),并尽可能多地在代码/域中使用我的业务逻辑,因为它更容易将所有内容整合在一起放置,更容易测试。
答案 1 :(得分:0)
您可以使用验收或集成测试来涵盖数据库和约束。
例如,在一个项目中,我们有一个单独的“集成”包,其中包含仅检查我们的NHibernate绑定的测试。如果您没有使用NHibernate,您可以使用您的存储库执行此操作,保持数据库连接到位。您可以从此级别验证约束,参照完整性等。
如果您仍在寻找有关TDD其他方面的指导,请尝试开始Dan North's post on BDD:
“我遇到了问题......程序员想知道从哪里开始,测试什么,不测试什么,一次测试多少,调用什么测试,以及如何理解测试失败的原因。“