代码改变世界

测试驱动开发札记 1

2011-08-12 11:30  skylinee  阅读(486)  评论(0)    收藏  举报

勇气为何物

很多东西都是仁者见仁智者见智,今天我来说说自己对驱动测试开发(简称TDD)的一些学习心得。

TDD对程序猿提出的首要条件是:勇气!?我对此的理解是,敢于往编译器里敲入各种测试用例的勇气,不管他们是对是错。然而这种勇气又来源于,对产品Backlog中“故事”的业务逻辑有一定程度的认知。其次是对TDD开发思维方式和流程有深刻认识。当然,不是说新手就对TDD无所适从,理想状况是Scrum中提到的结对编程,即老带新;否则就只有自己多加练习了。记住,不是用工作代码哦…

经验还是三角法

紧接着要做的是,在一堆繁杂的测试用例中使用上一篇文章“Triangulation – TDD开发中的问题解决技术”中提到的三角法去精炼、抽取你真正需要的业务逻辑算法。在这一步中,即验证了测试用例的可用性,也展现了我们在对业务算法无从下手的情况下,该如何通过“错+对“测试用例的角度来化解问题。

代码整洁之道

其实最核心的,把代码从零乱、繁杂变为整洁可以用的步骤是重构(整洁代码之道)。重构又分为大概两种。实时重构,比如把占位伪代码替换为通过测试想到的一般实现,这种在TDD开发流程中始终贯穿的局部重构。后期重构,比如在某个功能开发出来以后,利用熟悉的设计模式去消除重复设计,最典型的有工厂方法(Factory Method)这种用来消除对子类过分依赖的耦合设计。

实时重构

public new bool Equals(object dollar)
{
    return true;
}

通过测试用例

[Test]
public void TestEqual()
{
    Assert.IsTrue(new Dollar(5).Equals(new Dollar(5)));
    Assert.IsTrue(new Dollar(5).Equals(new Dollar(6)));
}

重构为

public new bool Equals(object dollar)
{
    return Amount == ((Dollar) dollar).Amount;
}

后期全局重构

[Test]
public void TestDollarMultiplication()
{
	var five = new Dollar(5);
	Assert.AreEqual(Money.DollarFactory(10), five.Times(2));
	Assert.AreEqual(Money.DollarFactory(15), five.Times(3));
}

通过测试用例

[Test]
public void TestDollarMultiplication()
{
	var five = Money.DollarFactory(5);
	Assert.AreEqual(Money.DollarFactory(10), five.Times(2));
	Assert.AreEqual(Money.DollarFactory(15), five.Times(3));
}

重构为

public static Dollar DollarFactory(int amount)
{
	return new Dollar(amount);
}

public static Franc FrancFactory(int amount)
{
	return new Franc(amount);
}

末了

文章的最后放个自己画的草图吧,大家讨论下喽

image

图一 驱动测试开发简易流程图