2010-01-13 71 views
4

我见过很多关于为什么测试驱动开发很好的文章,它减少了开发时间等。但是在搜索了很多论坛之后,我仍然没有得到TDD的具体优势。我并不是说测试是一件坏事,但我的观点是,如果在编写源代码之后编写我的单元测试,而不是TDD提出的反之亦然,那会有什么危害。测试用例一旦完成就会像回归测试一样行事。我在尝试遵循传统代码中的TDD时遇到了很多问题。我想现在大部分代码都是遗留代码,我们必须在没有预先存在的测试的情况下修改代码。 TDD也仅限于单元测试,甚至系统级和集成测试。我只是无法想象如何在不编写源代码的情况下进行集成测试。TDD和编写源代码之前或之后的测试?

回答

4

我不会说TDD缩短开发时间。它甚至可能更长。但TDD导致“干净的代码有效”。该软件在单元测试的同时同时,而不是一个接一个地测试,因此只要它被写入就被测试。这给开发人员带来了信心,也给了他“他在哪里”的好主意,因为他知道他迄今所做的工作是“完成了”。

也事后写单元测试可能很难。作者“Working effectively with legacy code”(一个非常好的资源顺便说一句)甚至说没有单元测试编写的代码确实是遗留代码。

而且是TDD限于单元测试仅 或甚至系统层面和集成 测试。我只是无法想象 如何在不编写源代码的情况下做集成测试 。

TDD是一种开发技术,它不打算取代其他类型的测试。

然而,人们可以在要测试的代码存在之前编写集成测试。这允许问自己如何测试将要生成的代码。

13

让我问一个反问回答:

如果你曾经编写软件,你会不会启动,比方说,收集和写下你的软件的要求吗?

TDD的基本原理意味着您的测试用例您的要求。因此,首先写下你的测试,首先写下你的要求。你只是以不同的方式去做。

现在这是做事情的最佳方式吗?这是主观的。但这就是为什么TDD首先写测试的原因。

+0

需要注意的是需求会经常变化,因此计划和编写错误版本的需求的详细测试用例所花费的时间将会浪费。一个很好的折中方案可能会稍微宽一点,并延迟编写测试,直到你有一个组件的松散工作原型,并相当确定它需要做什么。 – FactualHarmony 2014-03-04 14:01:18

+0

@AUser非常棒的一点,但你正在深入细节,我没有打扰。在TDD中,您通常会构建更高级别的特定于需求的*集成测试*。这些简单的测试可以用作回归测试,以确保对代码的更改不会违反要求。当这些需求发生变化时,这些集成测试会发生变化以适应变化的需求但是,这很重要,集成测试只是测试套件的一部分。你仍然应该做更复杂的灰盒测试 - 内部和/或子组件的黑盒测试。 – Randolpho 2014-03-04 17:18:54

+0

您能举一个“特定需求集成测试”的例子吗?我发现需求描述过于抽象,无法首先编写测试,而无需执行某些活动。你的意思是像为你的组件写作存根和测试他们如何相互交谈? – FactualHarmony 2014-03-05 20:48:48

6

如果您在编写代码(特别是您编写的代码)之后编写测试,最终会出现编写测试代码将会通过的风险,而不是编写能够确保正确行为的测试。就像在开发软件后编写需求文档一样。

另外,测试驱动开发并不一定意味着你编写了所有的测试,然后坐下来编写满足它们的东西。通常,你会编写测试,然后编写通过这些测试的代码,并迭代该过程。

6

我在尝试遵循传统代码中的TDD时也遇到了很多问题。

这就是在编写测​​试代码之前编写测试通常更好的原因之一。如果您编写代码然后尝试测试它,您可能会发现需要重新设计或完全重写您的类,以便于测试。如果你先写测试,你会鼓励自己写一个干净的,可测试的接口给你的课程。

4

先写测试确保实际上可以单元测试被测系统(SUT)。

如果之后编写测试,您会发现在很多情况下,您无法对SUT进行单元测试,因为您对运行时环境做出了假设,这可能并非如此。

2

写作测试首先让你进入软件单元的“客户端”。如果您先尝试编写测试,那么您将倾向于编写最容易使用的代码,而不是最易于编写的代码。

当我第一次写测试的时候,我也倾向于进入思维状态,你试图想象“嘿,如果我把这个,这个或那个传递给这个方法,我应该怎么做”,因此最后再多一次考虑设计,需求等...在我花费太多时间编写代码之前,结果是无用的。

但是的确如此,有时你只是没有太多的想法,你将如何编写代码,你只需要就可以去写它,然后编写一些测试,也许重构。没关系。只要最终你得到了一个明智的设计,足够干净的代码,并进行测试以保存回归时发生的一天...

当然,要编写集成测试,您必须有代码进行集成,这样很难完全TDD它(但也许,写集成测试给你一个模块接口的好主意,并可以作为单元测试的准备。)

2

我认为其中一个具体的优点是,您倾向于编写比您真正需要的代码更多的代码。至少这就是理论的走向。通过TDD,您可以开始编写您认为需要解决特定需求的所有测试。然后你写出尽可能多的代码,以便让所有测试通过。我无法确定这是否确实会产生更好的代码,但它可以让您免于浪费时间摆弄代码,因为您没有意识到自己已经完成了。

另外,编写代码之前或之后编写测试的区别在于,在您真正考虑需要解决问题之前编写测试之前,如果您在代码之后编写测试,那么运行风险只是代表测试中的代码。

我也经历了很多的问题 而试图按照TDD在传统 代码。

TDD和遗留代码的问题是众所周知的。我读过的关于测试的每本书或论文都明确指出,将TDD应用于现有代码要困难得多。

基本上,这不是一个只有你有的问题,它已被TDD防御者认可。我认为解决方案之一就是慢慢地开始将TDD应用于您正在工作的代码的各个部分,而不是潜入并且不知所措。

我在哪里工作,我们做了很多单元测试,但我们并不严格遵循TDD。然而,当我修复一个错误时,我发现有助于获得TDD的诀窍遵循其规则。对一个小问题进行测试通常会比较容易,并且看看TDD如何帮助您找到问题并修复问题,而不是将TDD应用于一个巨大的功能。

1

但是经过很多论坛的搜索,我还没有得到TDD的具体优势。

我通过练习TDD了解了模块化设计的原理。我逐渐提高了检测和消除重复的技巧,检测命名问题,将代码隔离为可重用的引擎,并保持相关性松散。实践TDD给了我一种学习所有这些技能的方法。我认为这是TDD最大的具体优势。

你可以阅读更多关于为什么TDD在这里工作:http://bit.ly/peWDS

1

TDD是一个方法,以确保所有功能保护。将测试添加到已有代码意味着的某些功能将受到保护。

相关问题