我已经阅读了很多有关测试驱动设计的信息。我的项目正在使用测试,但是目前它们是在编写代码之后编写的,我不清楚如何从另一个方向进行测试。
一个简单的例子:我有一个类Rectangle
。它具有private
字段width
和height
以及相应的获取器和设置器。通用Java。现在,我想添加一个函数getArea()
,该函数返回两者的乘积,但我想先编写测试。
我当然可以编写单元测试。但这不是失败的情况,但甚至没有编译,因为还没有getArea()
函数。这是否意味着编写测试总是已经涉及更改生产代码以引入没有功能的虚拟对象?还是我必须使用自省的方式编写测试?我不喜欢后一种方法,因为它会使代码的可读性降低,以后使用工具进行重构将不会发现它并破坏测试,而且我知道我们进行了很多重构。另外,添加“虚拟对象”可能会包含很多更改,即,如果我需要其他字段,则必须更改数据库才能使Hibernate继续工作,……对于“仅编写测试”的我来说,这似乎对代码进行了许多有效的更改。我想遇到的一种情况是,我实际上只能在src/test/
内编写代码,根本不碰src/main
,而没有内省。
有办法吗?
答案 0 :(得分:4)
嗯,TDD并不意味着在编写测试之前生产代码中不能包含任何内容。
例如:
getArea(param1, param2)
为空。 然后更改生产代码并再次运行测试。
例如,可以在此处找到快速介绍:codeutopia -> 5-step-method-to-make-test-driven-development-and-unit-testing-easy
答案 1 :(得分:1)
我想遇到的一种情况是,我实际上只能在src / test /内编写代码,根本不接触src / main,而没有内省。
我从未见过一种方法来编写依赖于API新部分的测试,并且无需首先扩展测试对象的API即可立即编译该测试。
内省还是什么都没有。
但这并不是失败的情况,但是甚至没有编译,因为还没有getArea()函数
从历史上看,编写无法编译的代码是TDD节奏的一部分。编写一些测试代码,编写一些生产代码,编写一些测试代码,编写一些生产代码,等等。
罗伯特·马丁(Robert Martin)将其描述为nano-cycle of TDD
...目标始终是促进我很久以前与Kent合作时所经历的逐行粒度。
我在自己的工作中放弃了纳米循环约束。也许我不欣赏它,因为我从未与肯特结伴。
但是我非常高兴编写不编译的测试,然后在测试处于令人满意的状态时回填我需要的生产代码。这对我来说效果很好,因为我通常在一个开发环境中工作,该开发环境只需几个关键步骤即可生成生产实现。
另一种可能性是考虑像TDD as if you meant it这样的学科,该学科在将代码移入生产层次结构之前,会在测试源层次结构中完成大量的实际工作。
答案 2 :(得分:0)
我有时候一直在从事Android开发,但从未在Android中完全采用TDD。但是,我最近尝试开发具有完整TDD的新应用。所以这是我的看法。
这是否意味着编写测试总是已经涉及更改生产代码以引入没有功能的虚拟对象?
我认为是的。据我了解,每个测试都等同于我对该软件的所有规格/用例。因此,首先编写一个失败测试是关于尝试用测试代码填充需求规范的尝试。然后,当我尝试填充生产性代码以通过刚刚编写的TC时,我真的试图使其生效。经过一段时间后,我很惊讶我的生产代码很小,但是它能够满足多少需求。
对我个人而言,我在生产代码之前编写的所有失败的TC实际上都来自问题列表,我就这些问题进行了头脑风暴,有时我用它来探索需求的极端情况。
所以基本工作流程是红色-绿色-重构,这是我从布莱恩·布雷汉姆(Bryan Breecham)的演讲中获得的-https://www.infoq.com/presentations/tdd-lego/
关于
我想遇到的一种情况是,我实际上只能在src / test /内编写代码,根本不接触src / main,而没有内省。
对我来说,我认为有可能,当您首先编写所有生产逻辑时,UT便会扮演满足要求的角色。这只是另一种方式。因此,总的来说,我认为TDD是方法,但是人们可以出于不同目的使用单元测试,例如减少测试时间等。