您的位置:首页 > 其它

第5、6、7、8、9章测试驱动开发过程

2015-09-15 22:06 239 查看

User Story(用户故事)

作为一位酒店大堂服务员,我想在大堂的城市时钟不准时,用设置自己手机时间的方法,自动统一调整这些城市时钟的时间,来避免逐一根据时差调整这些时钟的繁琐工作。

写测试用例

HotelWorldClocksTest.java

public class HotelWorldClocksTest {

private HotelWorldClockSystem hotelWorldClockSystem;
private PhoneClock phoneClock;

@Before
public void init() {
this.hotelWorldClockSystem = new HotelWorldClockSystem();
this.phoneClock = new PhoneClock(8);
}

@Test
public void the_time_of_clock_London_should_be_1_after_the_phone_clock_is_set_to_9_Beijing_time() {
// Arrange
CityClock londonClock = new CityClock(0);
hotelWorldClockSystem.attach("london", londonClock);

// Act
phoneClock.setHotelWorldClockSystem(hotelWorldClockSystem);
phoneClock.setTime(9);

// Assert
assertEquals(1, londonClock.getLocalTime());
}

@Test
public void the_time_of_clock_NewYork_should_be_20_after_the_phone_clock_is_set_to_9_Beijing_time() {
// Arrange
CityClock newYorkClock = new CityClock(-5);
hotelWorldClockSystem.attach("newYork", newYorkClock);

// Act
phoneClock.setHotelWorldClockSystem(hotelWorldClockSystem);
phoneClock.setTime(9);

// Assert
assertEquals(20, newYorkClock.getLocalTime());
}

@Test
public void the_time_of_clock_London_and_NewYork_should_be_1_and_20_respectively_after_the_phone_clock_is_set_to_9_Beijing_time() {
// Arrange
CityClock newYorkClock = new CityClock(-5);
CityClock londonClock = new CityClock(0);
hotelWorldClockSystem.attach("london", londonClock);
hotelWorldClockSystem.attach("newYork", newYorkClock);

// Act
phoneClock.setHotelWorldClockSystem(hotelWorldClockSystem);
phoneClock.setTime(9);

// Assert
assertEquals(1, londonClock.getLocalTime());
assertEquals(20, newYorkClock.getLocalTime());
}

@Test
public void the_time_of_the_phone_clock_should_be_set_correctly_after_its_setTime_method_is_invoked() {
// Arrange

// Act
phoneClock.setTime(9);

// Assert
assertEquals(9, phoneClock.getLocalTime());
}
}


生成并调试代码

HotelWorldClockSystem.java

public class HotelWorldClockSystem {

private Map<String, Clock> cityClocks = new HashMap<String, Clock>();

public void attach(String name, Clock londonClock) {
cityClocks.put(name, londonClock);
}

public void updateCityClockWithUtcZeroTime(int utcZeroTime) {
for (Clock clock : cityClocks.values()) {
clock.setLocalTime((utcZeroTime + clock.utcOffSet + 24) % 24);
}
}

}


Clock.java

public class Clock {

protected int utcOffSet;
protected int localTime;

public Clock(int utcOffSet) {
this.utcOffSet = utcOffSet;
}

public int getLocalTime() {
return this.localTime;
}

public void setLocalTime(int localTime) {
this.localTime = localTime;
}
}


PhoneClock.java

public class PhoneClock extends Clock {

private HotelWorldClockSystem hotelWorldClockSystem;

public PhoneClock(int utcOffSet) {
super(utcOffSet);
}

public void setLocalTime(int localTime) {
super.localTime = localTime;
if (this.hotelWorldClockSystem != null)
this.hotelWorldClockSystem
.updateCityClockWithUtcZeroTime((localTime
- super.utcOffSet + 24) % 24);
}

public void setHotelWorldClockSystem(
HotelWorldClockSystem hotelWorldClockSystem) {
this.hotelWorldClockSystem = hotelWorldClockSystem;
}
}


最终的类图



测试驱动开发的过程

1.”尽量简单”的标准选取第一个测试
a)用User Story的格式描述产品特性。用‘产品特性’这样基于沟通的字眼替换带有强制、专制和持久色彩的‘需求’一词

b)从User Story中选取一种简单情况编写第一个测试函数,测试函数名写的长一点作为易于阅读的文档,在一个测试中先写Assert部分,然后推导出Act和Arrange这两部分代码

c)根据测试函数里的符合自己意图的代码驱动生成生产代码,只写能让编译通过的、尽量少的代码

d)列出TODO清单,重构是测试通过

2.”尽量有意思”的标准选取下一个测试
a)写好一个测试的Assert部分后,在以此推导出Act和Arrange部分的意图代码

b)循着意图代码中红色的编译错误的指引来编写最少的代码消除错误

c)调试,用最少的代码使测试通过

d)足够自信时,步子可以迈的大一点

3.迭代的测试
a)完成所有TODO列表之后,重新审阅代码找出还未测到的情况和遗漏的代码“腐臭”

b)将子类构造器中出现的重复成员变量上移到父类中,以消除重复

c)将那些因被替换而不再被调用的代码删掉

d)将子类中签名相同但实现不同的方法,提取一个抽象方法放到父类中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  测试驱动开发