Java 具有非平凡算法的tdd

Java 具有非平凡算法的tdd,java,algorithm,unit-testing,tdd,Java,Algorithm,Unit Testing,Tdd,这几天我正在用Java编写一些数据结构。它们中的许多(如果不是全部的话)提供了一个非常简单的界面(添加、包含、删除),但是在幕后有一些非平凡的算法 在这种情况下如何使用tdd技术 我认为问题在于tdd(以及一般的单元测试)是关于测试接口而不是实现的。我说得对吗?我该怎么处理 如果你知道任何处理这种情况的技巧,请告诉我 谢谢您的帮助。您是正确的,TDD是关于测试接口,而不是实现。 也就是说,为什么要测试实际的实现呢?关键是,如果您充分测试了接口,那么实现并不重要 当您在实现中发现一个bug时,这意

这几天我正在用Java编写一些数据结构。它们中的许多(如果不是全部的话)提供了一个非常简单的界面(添加、包含、删除),但是在幕后有一些非平凡的算法

在这种情况下如何使用tdd技术

我认为问题在于tdd(以及一般的单元测试)是关于测试接口而不是实现的。我说得对吗?我该怎么处理

如果你知道任何处理这种情况的技巧,请告诉我


谢谢您的帮助。

您是正确的,TDD是关于测试接口,而不是实现。 也就是说,为什么要测试实际的实现呢?关键是,如果您充分测试了接口,那么实现并不重要


当您在实现中发现一个bug时,这意味着它在某个地方违反了您向外界公开的接口。您需要跟踪到它违反接口的地方。这就是您编写测试用例的地方。

您正确地认为TDD是关于测试接口,而不是实现。 也就是说,为什么要测试实际的实现呢?关键是,如果您充分测试了接口,那么实现并不重要


当您在实现中发现一个bug时,这意味着它在某个地方违反了您向外界公开的接口。您需要跟踪到它违反接口的地方。这就是您编写测试用例的地方。

测试接口远远优于测试实现。稍后,当您重构实现时,您的测试仍然有效


如果您觉得您的方法过于复杂,无法进行充分的单元测试,那么这可能表明您需要重构代码,并将其分解为几个较小的(可能是私有的)方法,这些方法可以单独测试。

测试接口比测试实现要好得多。稍后,当您重构实现时,您的测试仍然有效


如果您觉得您的方法过于复杂,无法进行充分的单元测试,这可能表明您需要重构代码,并将其分解为几个较小的(可能是私有的)方法,这些方法可以单独测试。

测试实现是否包含一些限制(例如:比较数量、性能等)您可以使用测试来TDD这些约束

我觉得这段推特对话很有见地:

它讨论了这个想法:快速排序。我们知道快速排序比气泡排序快。这两种算法将提供相同的输出(排序集合),但它们具有不同的约束

因此,您在测试中显式地添加了算法的约束(显然,您需要测试您的算法是否达到了预期的效果)


我同意在这个例子中,你正在做一些你已经知道答案的事情。然而,如果你必须找到一个复杂的算法,你可能不会一直去TDD它。但是测试和约束测试将帮助您知道是否找到了答案。

要测试实现是否包含一些限制(即:比较数量、性能等),您可以使用测试来确定这些约束

我觉得这段推特对话很有见地:

它讨论了这个想法:快速排序。我们知道快速排序比气泡排序快。这两种算法将提供相同的输出(排序集合),但它们具有不同的约束

因此,您在测试中显式地添加了算法的约束(显然,您需要测试您的算法是否达到了预期的效果)


我同意在这个例子中,你正在做一些你已经知道答案的事情。然而,如果你必须找到一个复杂的算法,你可能不会一直去TDD它。但是测试和约束测试将帮助您知道您是否找到了答案。

我发现RSpec书中的示例TDD/BDD非常有用-这可能是rails面向的一些内容,但在书中作者从定义问题开始,以直观的方式识别简单测试用例到复杂用例。这本书中的例子是关于开发一个游戏及其通过所有测试的进展


这对您也很有用,因为您讨论的是接口,而BDD是关于测试应用程序的行为(在您的案例算法中)

我发现RSpec书中的示例TDD/BDD非常有用-这可能是rails所面向的,但在书中,作者从定义问题开始,以直观的方式识别简单测试用例到复杂用例。这本书中的例子是关于开发一个游戏及其通过所有测试的进展


这对您也很有用,因为您讨论的是接口,而BDD是关于测试应用程序的行为(在您的案例算法中)

如果您的实现很复杂,那么最好将其分解为较小的模块。这些较小的模块将拥有自己的接口,您可以对其进行单元测试。例如,如果您通过深度优先搜索来解决数独问题,那么单独开发深度优先搜索算法和数独位置枚举算法是值得的。不久前我在博客上写过这一点:

如果您的实现很复杂,那么最好将其分解为更小的模块。这些较小的模块将拥有自己的接口,您可以对其进行单元测试。例如,如果您通过深度优先搜索来解决数独问题,那么单独开发深度优先搜索算法和数独位置枚举算法是值得的。我写博客