TDD可以留下什么样的故障模式?

时间:2010-08-31 13:44:51

标签: tdd

请注意我还没有在TDD上看到“光明”,也没有真正 为什么它拥有主要支持者宣传的所有好处。我并没有解雇它 - 我只是保留了可能由于无知而产生的保留。所以无论如何都要嘲笑下面的问题,只要你能纠正我: - )

使用TDD会让您对实施的意外副作用持开放态度吗? “满足测试的最少量代码”的概念建议用最狭隘的术语思考特定问题而不必考虑更大的图景。

我正在考虑持有或依赖于状态的对象(例如内部字段值)。如果您有单独实例化对象的测试,初始化该对象然后调用测试中的方法,您会如何发现不同的方法留下了一个无效的状态,会对行为产生负面影响第一种方法?如果我已经正确理解了问题,那么你就不应该依赖于测试执行的顺序。

我可以想象的其他失败包括非关闭流,不处置GDI +对象等。

这甚至是TDD的问题域,还是整合和系统测试都会遇到这样的问题?

感谢期待......

4 个答案:

答案 0 :(得分:7)

其中一些属于TDD领域。

Dan North说没有测试驱动开发这样的东西;我们真正做的是示例驱动的开发,只有在被测系统实现后,这些示例才会成为回归测试。

这意味着在设计一段代码时,您需要考虑示例场景并为每种情况设置测试。这些情况应该包括数据无效的可能性,而不考虑为什么数据可能无效。

在练习TDD时,可以并且绝对应该涵盖关闭流的内容。

我们使用类似函数的结构不仅可以减少重复,还可以封装功能。我们通过保持封装来减少副作用。我认为我们从设计角度考虑更大的图景,但是当涉及到实现方法时,我们应该能够将我们的重点缩小到该范围 - 功能单元。当我们开始玩弄外部性时,我们可能会引入缺陷。

无论如何,这是我的看法;其他人可能会有不同的看法。

答案 1 :(得分:3)

TDD不是智能的替代品。最好的程序员使用TDD变得更好。最糟糕的程序员仍然很糟糕。

您提出这些问题的事实是一个好兆头:这意味着您认真对待编程。

  

“最少量的概念”   满足测试的代码“建议   用最狭隘的语言思考   一个特殊的问题没有   必须考虑更大   图片。

采取这种态度很容易,就像“我不需要对此进行测试;我确信它只是有效”。两者都很天真。

这实际上是关于采取小步骤,而不是提前退出。你仍然需要追求一个很好的最终结果,但是你一直都要小心证明验证你编写的每一段代码,并进行测试。

TDD的直接目标非常狭窄:“我怎样才能确定我正在编写的代码是否符合我的意图?”如果您还有其他问题需要回答(比如,“这会在加纳好转吗?”和“我的程序是否足够快?”)那么你需要不同的方法来回答它们。

  

我正在考虑持有或拥有的物体   依赖于国家。

  

你会如何发现不同的   方法留下了无效   状态?

依赖性和状态很麻烦。它们会在最糟糕的时候出现微妙的错误。他们使重构和未来的改进更加困难。他们使单元测试不可行。

幸运的是,TDD非常善于帮助您生成将逻辑与依赖关系和状态隔离开来的代码。这是“TDD”中的第二个“D”。

答案 2 :(得分:2)

  

“最少量的概念”   满足测试的代码“建议   用最狭隘的语言思考   一个特殊的问题没有   必须考虑更大   图片。

它表明,但这并不意味着什么。它意味着强大的眼罩目前。更大的图景就在那里,但会干扰手头的当前任务 - 所以完全专注于当前的任务,然后担心接下来会发生什么。大局出现,在TDD中占了一席之地,但我们在红色阶段暂停对它的关注。只要测试失败,我们的工作就是让测试通过。一旦它和所有其他测试正在通过,那么就应该考虑全局,观察缺点,预测新的故障模式,新的输入 - 并编写测试来表达它们。这让我们重新回到了红色,并重新缩小了我们的注意力。让新测试通过,然后将眼罩放在一边,以便下一步。

是的,TDD给了我们一些眼罩。但它并没有使我们失明。

答案 3 :(得分:1)

好问题。 根据我的个人经验,这是我的两分钱:

  

使用TDD可以让自己开放   你的意想不到的副作用   执行?

是的,确实如此。 TDD不是一个“完全成熟”的选择。它应该与其他技术一起使用,你应该牢记大局(无论你是否对此负责)。

  

我正在考虑持有或拥有的物体   依赖于国家(例如内部领域   值)。如果你有测试   隔离地实例化一个对象,   初始化该对象然后调用   在测试的方法,你会怎么样   发现另一种方法已经离开了   在一个无效的国家背后   对行为产生不利影响   第一种方法?如果我明白了   事情是正确的,那么你不应该   依赖于测试执行的顺序。

每个测试方法都应该执行,而不考虑之前执行的内容,或者之后执行的内容。如果情况并非如此,则出现问题(从TDD的角度来看)。

谈到你的例子,当你写一个测试时,你应该知道你的输入将是什么以及预期的输出是什么。您从已定义状态的已定义输入开始,然后检查所需的输出。你没有100%保证在另一个状态下使用相同的方法可以正常工作而不会出错。但是,“意外”应该减少到最低限度。

如果你设计了这个类,你肯定应该知道两个方法是否可以改变一些共享的内部状态以及如何;更重要的是,如果这个应该真的发生,或者存在关于低凝聚力的问题。

无论如何,“tdd”级别的好设计并不一定意味着你的软件很好,你需要更多,因为Bob叔叔在这里解释得很好:

http://blog.objectmentor.com/articles/2007/10/17/tdd-with-acceptance-tests-and-unit-tests

Martin Fowler写了一篇关于Mocks vs Stubs测试的有趣文章,其中涵盖了您正在讨论的一些主题:

http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting