任务 3 – 编写第一个测试:设计和定义SimpleStack类
根据任务2定义好上下文描述,我们将从编写测试开始设计和建立SimpleStack类。同时,利用VS的Smart Tag功能帮助加入一些必需的语句、创建代码等工作。
- 首先,从创建一个新的测试方法开始,验证当一个栈被创建后,它应该是个空白的栈(没有推入任何条目)。我们将测试方法命名为ThenItShouldBeEmpty 。普通方法加上TestMethodAttribute 就可以将其识别为测试方法。来看一下测试类的名称和测试方法的名称的关系:WhenAStackIsCreated.ThenItShouldBeEmpty() —— 哇,多么直白啊,一眼就看到这个测试是用来干啥的!
[TestMethod ]
public void ThenItShouldBeEmpty ()
{
}
- 接下来,声明和初始化一个新的SimpleStack 对象,再验证它的IsEmpty 属性是否返回true。我们先声明和初始化一个新的SimpleStack对象:
[TestMethod]
public void ThenItShouldBeEmpty()
{
SimpleStack theStack = new SimpleStack ();
}
- 注意,VS会再次给你Smart Tag提示,这次的提示有所不同,它告诉我们它不知道SimpleStack是什么类,所以它提供了生成该类的选项给我们。
- 在选项列表里选择Generate class for "SimpleStack" 。SimpleStack.cs文件会被自动创建并帮我们做好了新类的一些基本语句的编写。从Solution Explorer打开此文件。
- 特别注意:选项列表中还有另外一个选择:Generate a new type.... 。默认情况下,Smart Tag会在当前项目中创建代码文件,但我们知道SimpleStack.cs这个新类应该放置于我们最开始建立的SimpleDataStructures项目中,而不是放置在测试项目中。如果我们选择了Generate a new type...选项,在新建类型的对话框中,Project location可以允许我们将代码创建在目前解决方案的其它项目中。
- 重要的一点是,TDD使用Smart Tag帮忙在当前项目直接生成代码。这样就可以鼓励我们开发人员尽可能在测试项目完善好组件的开发、测试后,才尽可能晚地将组建转移到目标项目中。
- 在设计周期中,代码文件要转移到什么位置的决定放到最后才去考虑,意味着我们对整个系统的潜在依存关系有着更清晰的画面,更有利于帮助我们确定代码文件该放置到什么位置。所有这些都回到一个基础原则,就是做最少的事情使测试能得以通过!
- 回到测试方法,现在我们要验证新建的对象是空的,我们使用Assert 类来断言它的IsEmpty属性是真:
[TestMethod]
public void ThenItShouldBeEmpty()
{
SimpleStack theStack = new SimpleStack();
Assert.IsTrue (theStack.IsEmpty);
}
- 再一次,VS给出Smart Tag,告诉我们IsEmpty错误,给出Generate property stub for IsEmpty in SimpleDataStructures.Tests.SimpleStack 的提示。既然这么热情,那我们怎能拒绝呢?VS在SimpleStack类中帮我们生成了IsEmpty的属性。
- 打开SimpleStack.cs文件, 我们能看到生成的属性代码:
class SimpleStack
{
public bool IsEmpty { get; set; }
}
- 到目前我们写好了测试方法,也确保测试方法用到的类、成员等已经无误,那依着我们“失败、成功、重整 ”的原则,先运行测试,千万要保佑它先是失败的!回到测试方法,通过右键点击,从菜单中选择Run Test ,或者按CTRL+R,T 运行测试。我们会看到,在断言IsEmpty是否为真的时候,会出现失败,同样测试也失败了。感谢上帝!
- 做最少的事情使测试能得以通过!那最简单的办法就是,直接让IsEmpty属性返回true。
- 你会说这样做很愚蠢也毫无道理,是的,地球人都知道这样做很无聊。但这样做着有非常明显的好处:首先,可以帮助我们刚才写的测试方法是否有误。如果我们将IsEmpty直接设置为true,而测试还是没有通过的话,那测试方法肯定有bug,例如我们是不是用错了Assert的IsFalse方法,本来应该用IsTrue的;其次,再次强调了做最少的事情让测试通过的原则!
- 很明显,我们将IsEmpty属性改为只读属性,直接返回true,这样做就是最简单也最少代码的方法。要明白,我们现在要测试是Then It Should Be Empty,而不是让我们实现栈的其它功能。头脑中一点要时刻记住:看着测试要求来写最少的代码(因为大家都知道,越少代码 = 出现bug的机会越低)。
class SimpleStack
{
public bool IsEmpty
{
get { return true; }
}
}
- 下一步我们要回到测试方法去运行它。这里教一个窍门,使用VS的Quick Search 对话框可以帮助我们快速定位(Navigate)到所需的类、方法、成员的定义位置。按CTRL+, (逗号),在出现的Quick Search对话框,输入ThenItShou等文字,VS会根据你输入的文字进行搜索,以帮助我们快速定位。同时我们可以使用名字中的大写字母来搜索,例如输入TISB等文字,同样能帮我们找到要搜索的名称。通过上下箭头移动到所需条目,再按Enter就可以了。
- 现在回到测试方法,来吧,运行一下测试,这次它肯定能通过,实现了从失败到成功!(Red to Green)