我一直在将TDD应用到一些新项目上,以了解更多内容,并且我了解基本流程:编写失败的测试,编写代码以通过测试,必要时进行重构,重复。
为了保持测试的快速和脱钩,我将网络请求和文件I / O之类的内容抽象出来。这些通常被抽象到使用依赖注入的接口中。
通常,开发非常顺利,直到最后我意识到我需要实现这些抽象接口。对它们进行抽象的全部目的是使其易于测试,但是在TDD之后,我需要在编写实现代码之前编写一个测试,对吗?
例如,我正在看tdd-tetris-tutorial https://github.com/luontola/tdd-tetris-tutorial/tree/tutorial/src/test/java/tetris。如果我想增加键盘演奏的功能,可以将基本控件抽象到Controller类内的方法中,例如“ rotateBlock”,“ moveLeft”等可以测试的方法。
但是最后,在实现控制器类时,我需要添加一些逻辑来检测键盘的击键。一个人如何编写测试来实现这一目标?
也许有些东西无法测试,在某些情况下不可能达到100%的代码覆盖率?
答案 0 :(得分:1)
也许有些东西无法测试,在某些情况下不可能达到100%的代码覆盖率?
我使用的拼写稍有不同:并非所有事物都可以在相同的成本效益水平下进行测试。
可以说,“技巧”是将您的代码分为两类:易于测试的代码和显而易见的代码,您无需测试-或不需要经常测试。
关于简单适配器的好处是(一旦您使它们完全可用),它们通常不需要进行很大的更改。所有的 logic 生活在其他地方,并且易于测试。
例如,考虑从文件读取字节。这种接口看起来像一个函数,它接受文件名作为参数,并返回字节数组或某种异常。 实施在大多数语言中都是直截了当的练习,并且代码对教科书非常熟悉,以至于它显然属于“如此简单,显然没有缺陷”的类别。
由于代码简单且稳定,因此您无需在定期重构代码的频率附近进行测试。因此,成本效益分析支持以下结论:您可以将偶尔对该代码的测试委派给更昂贵的技术。
100%的声明覆盖率从来都不是TDD的目标(尽管很容易理解您和一小撮其他人是如何得出该结论的)。这主要是关于推迟详细设计。因此,从某种程度上说,从一开始就简单,很少更改的代码是“越界”的。
答案 1 :(得分:0)
您不能使用TDD 单元测试来测试所有内容。但是,如果您还具有集成测试,则可以测试那些I / O接口。您可以使用TDD进行集成测试。
在实践中,有些事情无法自动测试。某些罕见错误条件或种族危险的错误处理最困难。