TDD的限制是什么?

时间:2009-04-23 13:40:02

标签: tdd

我刚刚发现我喜欢以TDD的方式开发代码:我觉得我对开发的方向有了更多的控制。在我花费大量时间预先设计数据结构和算法之前,现在我从小开始,有机地“增长”我的代码。在每个红色/绿色/重构周期后,我都有代码 。感觉我的代码是一个有生命的东西,我指导它应该在哪里成长。我不知道每个人进入TDD时的感受是否如此,但这是我的经验。令我感到震惊的是,这与成功而非设计的自由软件项目的成功程度非常相似。

然而,现在我已经开始考虑测试驱动的开发,我开始想知道它的极限是什么。它似乎对开发功能代码非常有用:将此输入提供给该函数,您就会得到这个结果。但这只是软件开发的一小部分。那么GUI开发,网络,数据库开发,Web应用程序呢?你有什么经历?您是否尝试过使用这些类型的开发TDD?你知道任何工具或框架吗?你能推荐一些文章或书籍吗?

5 个答案:

答案 0 :(得分:9)

“GUI开发,网络,数据库开发,Web应用程序怎么样?”

为什么不起作用?

<强> GUI 即可。 TDD唯一不能做的就是评估界面的“外观”。但它可以评估行为。如果您的设计很好(分离模型,视图和控制),您可以轻松地将控件和模型作为TDD进行测试。但是,查看更难以编写测试。 (“断言按钮位于字段下方”是不明智的。)

<强>网络即可。不确定这意味着什么。但是,通过TDD完成定义RESTful Web服务非常好。定义URI,编写测试用例,然后构建提供预期响应的服务。

网络应用。 Django Web框架直接支持TDD进行开发。他们对Web数据模型和控制层进行了单元测试。此外,他们还对HTML页面呈现和行为进行了单元测试。

答案 1 :(得分:8)

我想知道如果你还没有找到最困难的地方,那么你使用TDD的框架/语言是什么:

  • 图形用户界面 - 某些环境和平台,特别是Windows窗体和ASP.NET Web表单,存在实际不可测试性,因为没有简单的方法来隔离或模拟其行为。这是ASP.NET MVC的主要推动力之一。

  • 持久性 - 任何类型的持久性,无论是磁盘存储,数据库连接,网络连接还是其他形式的外部系统都是一种限制,因为所有它们是持久性测试,它们过分依赖外部组件的状态才能成功。然后,这些集成测试被视为脆弱测试。模拟用于减轻此类外部系统的影响。

  • 采用 - 即使您精通TDD,尝试让其他开发人员 - 更不用说整个开发商店 - 使用它也是一场艰苦的战斗。许多人只是没有看到好处;最初的陡峭学习和生产力曲线很容易将它们关闭。您将遇到这样的情况:您是唯一一个在您的项目中练习TDD的人,即使您执行它,其他开发人员也会引入低质量,无意义的测试。这种非技术性原因是我在现实生产系统中使用TDD的最大障碍,当您非常了解其中的好处时,这是一个痛苦的实现。

答案 2 :(得分:3)

进行TDD需要一些费用:

  • 更新代码时,必须维护单元测试以检查新的正确行为。
    • 一旦你进行了大量的单元测试,当你重构时,你需要重写单元测试

我喜欢TDD很多东西。请记住,保持工作单元测试的上述维护成本可能意味着虽然您的代码变得更加模块化,但选择的模块化组织更难以改变。如果没有重写所有单元测试的额外成本,则无法重新组织代码。这确实是我在TDD中发现的最大限制。后来当你意识到自己犯了一个错误时,现在你已经拥有了所有这些开销,你必须经历重构,而在这些变化发生之前可能更加流畅。所以要好好使用TDD我会说你在第一次开发模块时需要做出正确的决定。在我们生活的不断变化的敏捷世界中并不总是那么容易;)。

还要考虑:

  • 并非所有内容都可以通过类方法进行纯黑盒测试。 IE是一种方法,其结果完全取决于自上次调用以来已经过了多少微秒。你需要添加钩子来控制已经过了多少时间,看看你是否得到了正确的响应。
  • 单元测试真的不适合所有事情。查看GUI是否可供人类使用,实际上无法通过unittest证明。

答案 3 :(得分:2)

至于限制,重要的是要记住TDD是关于稳定性和管理变更 - 可以说它并没有特别帮助你设计更好它只是强制执行你的设计*。实际上,提出良好的系统架构仍然需要与任何其他开发方法一样多的思考。

存在各种限制,其中大多数是因为软件仍然需要人类:

  • TDD无助于帮助GUI布局和一般用户体验等无形资产
  • TDD无法解决您设计中的垃圾垃圾问题
  • TDD无法解决环境问题(即网络,I18N和时间依赖的漏洞容易通过裂缝)
  • 单元测试本身需要设计(根据框架或多或少地解决)
  • 单元测试可以增加重构时所需的工作量(但希望通过漂亮的设计将其最小化)。
  • 经典:单身人士很难 - 不可能进行单元测试(这里的一般解决方案是避免单身人士)

*即使我已经写过,我也不确定如何正确地说出来。

答案 4 :(得分:-2)

在grails上尝试groovy。 您将自动生成测试。

每次自动创建控制器类时,都会生成单元测试类。

从“关于grails的权威指南”一书中可以看出:

Grails将测试分为“单元”和“集成”测试。集成测试引导 整个环境包括数据库,因此往往运行得更慢。此外, 集成测试通常用于测试多个类之间的交互 因此,在运行它们之前需要更完整的应用程序。 另一方面,单元测试是快速运行的测试,但它们需要您进行广泛的测试 使用模拟和存根。存根是用于测试的类,模仿真实的行为 返回任意硬编码值的方法。模拟基本上做同样的事情,但是 通过“期望”表现出更多的智慧。例如,模拟可以指定 它“期望”一个给定的方法至少被调用一次,如果需要甚至十次。