【发布时间】:2014-04-10 15:35:11
【问题描述】:
我正在尝试学习 Java,同时实施测试驱动开发 (TDD) 方法。我在面向对象的编程概念方面有一些经验,可以理解 Java,但不是 TDD。我编写了一个非常简单的 Java 程序以及单元测试,但在解决问题时遇到了一些问题。我认为这里的某个人可能能够澄清我的问题。我已经列出了问题、我的最终单元测试类、类实现逻辑、我解决问题的方法以及我遇到的问题。
问题:
我利用CodingBat 网站上列出的第一个问题SleepIn 来尝试实现简单的单元测试。这是网站上所述的问题。
如果是工作日,则参数 weekday 为 true,如果我们正在休假,则参数 Vacation 为 true。如果不是工作日,或者我们正在度假,我们就睡在外面。如果我们睡着了,则返回 true。
单元测试:
我编写了单元测试类并创建了四种方法来测试上述问题的可用输入的结果。
package com.codingbat.practice.unit;
import static org.junit.Assert.*;
import org.junit.Test;
import com.codingbat.practice.SleepIn;
public class SleepInTest {
@Test
public void weekend_and_not_vacation() {
SleepIn sleepIn = new SleepIn();
sleepIn.setWeekday(false);
sleepIn.setVacation(false);
assertTrue(sleepIn.allow());
}
@Test
public void weekend_and_vacation() {
SleepIn sleepIn = new SleepIn();
sleepIn.setWeekday(false);
sleepIn.setVacation(true);
assertTrue(sleepIn.allow());
}
@Test
public void weekday_and_not_vacation() {
SleepIn sleepIn = new SleepIn();
sleepIn.setWeekday(true);
sleepIn.setVacation(false);
assertFalse(sleepIn.allow());
}
@Test
public void weekday_and_vacation() {
SleepIn sleepIn = new SleepIn();
sleepIn.setWeekday(true);
sleepIn.setVacation(true);
assertTrue(sleepIn.allow());
}
}
类实现:
这是解决上述问题的类实现。
package com.codingbat.practice;
public class SleepIn {
boolean weekday;
boolean vacation;
public SleepIn() {
}
public void setWeekday(boolean weekday) {
this.weekday = weekday;
}
public void setVacation(boolean vacation) {
this.vacation = vacation;
}
public boolean allow() {
return (!this.weekday || this.vacation);
}
}
我采取的方法:
编写了方法
SleepIn.allow()来简单地返回false。实现了四个单元测试并传递了适当的参数,并根据我认为应该是类实现的结果使用了必要的断言方法。
执行了测试用例。其中 3 次失败,1 次成功。
测试
weekday_and_not_vacation()成功,因为它期望 false 并且实现当前仅返回 false。在方法
SleepIn.allow()中实现了必要的逻辑来解决问题。再次执行测试。 4 项测试全部通过。
将实现逻辑中的
||替换为&&以破坏解决方案并再次运行测试以验证至少有一个测试失败。 4 次测试中有 2 次失败。再次将正确的逻辑放回方法中,以验证所有测试是否成功。
问题:
我对 TDD 的理解是在编写实现逻辑之前让测试失败。在这种情况下,该方法返回一个 boolean。因此,我只能返回 true 或 false。我不能让所有的测试一开始就失败。推荐的 TDD 方法是否与我解决问题所采取的步骤相匹配?
在各个网站上阅读有关TDD的信息,我推断每个单元测试应该相互独立。基于此,我在每个单元测试中创建了一个
SleepIn的实例,以将所有测试逻辑限制在每个单元测试方法中。单元测试通常是这样实现的吗?在实现类中,我可以创建带有两个参数的构造函数来实例化实例变量。但是,我创建了 setters,因为调用方法名称来传递值似乎更有意义。我知道如果不调用适当的设置器,这种情况下的实例变量将包含 false 。 Java 或一般的面向对象编程实现中推荐的方法是什么?我没有实现 getters,因为我觉得不需要这个问题。
我假设在编写单元测试时有必要知道任何给定输入的结果是什么,以便我们可以使用适当的断言。在这种情况下,输入是两个 布尔值,我知道输出是什么,因为问题非常简单。所以,我相应地选择了合适的
assertTrue或assertFalse。这是应该如何编写单元测试的方式吗?当逻辑变得复杂时,例如在现实世界的应用程序中,它将如何扩展?如果它变得复杂,是否意味着问题应该被分解并保持尽可能小,以便我们可以轻松地使用单元测试进行测试?
【问题讨论】:
标签: java unit-testing tdd