转自 http://www.cnblogs.com/confach/archive/2005/04/01/129853.html
作为软件开发,客户的参与是软件成功的基础.作为程序员,我们需要一种方法来理解客户的需求,只有理解了客户的需求才能写出最好的软件.那么这种理解客户需求的方法是什么呢?这种方法有可能是利用文档,有可能是利用工具,或者是其他.
对于我目前工作而言,主要是通过EMail的形式来了解需求.就我个人而言,这种需求的方法不是令人满意.因为需求都是以叙述文本的形式发给我们,很少有出现类似表格,图等形式的文档,这样就造成不是完全能理解客户的需求,并且有时候会出现对需求的理解的偏差,当然所开发软件的周期相应的变长,事实上也确实如此.令我苦不堪言..
好,前几天在翻译一本书<<Test-Driven Development in Microsoft .NET>>时,上面介绍了一种叫FIT的工具,我觉得相当好,因为这种工具一种方法使程序员和客户精确的交流,和有规则的协作.我试了一下,相当不错,效果也很好.
这个工具 由WardCunningham 开发, JimShore.维护,我想 大家对于他们肯定不是很陌生.,对吧.
下面我将介绍这种工具,包括其作用和用法.
FIT FOR Dot NET 介绍了我是如何发现这个工具的.下面我将介绍这个工具.
在写本文时,参考了FIT的站点http://fit.c2.com/.其中有些是直接翻译的.
1)如何得到FIT工具
FIT工具分为.NET 版本和Java版本,你可以到http://www.sourceforge.net/projects/fit去下载.
2)FIT的介绍
2.1 介绍
首先,FIT只是一个测试框架,这个需要明白.
Fit允许客户,测试者,程序员知道他们的软件应该是什么样子.并且FIT会自动的比较客户的期望值和由软 件产生的实际值.
在客户和程序员的开发中,FIT会建立一个反馈的循环.具体的说,就是客户产生一个软件的实际例子,然后程序员在自己的软件中加入FIT框架,验证自己的程序产生的结果是否与客户给出的一样.这样的礼尚往来,就是一个反馈的循环.
通过上面的描述,你应该知道FIT实际构造了业务和软件工程之间的一个简单而有用的桥梁.
下面,我将简单的介绍如何使用它,至于他的详细使用,我在以后的文章中有所体现:
(主要来自与http://fit.c2.com/)
2.2 如何使用FIT
FIT的文档通过整个软件产品组的协作产生,客户,测试员,程序员必须一起工作才能成功.最后的结果是一个“可执行的详细说明“,是一个可阅读的文档.这个文档不仅描述了软件,而且也描述了实际上软件是一个什么样子.
下面给出一张图(来源于http://fit.c2.com/)
在上面的图中,就是一个FIT文档的测试结果,绿色的表示通过,红色的表示未通过.
从概念到完成:制作一个特征的FIT
这个过程从一个客户(可以是领域专家,业务元,产品经理等)描述的新特征开始,并且客户提供了它应该怎样去做.
上图是一个白板对话
和测试员,程序员一起工作的客户,提取这些例子到一个表中(处理这个表可以用Excel,Word等),把它变成一个文档.测试员和程序员建议附加的域,确保这个表对FIT适合.
客户的初始例子
测试员和程序员的附加物
适合FIT的格式
这个文档以HTML的格式保存,开发者可以创建“fixture“:一点可以理解文档中例子的程序代码,并在正在开发的软件项目上试试这些代码.幸运的是,FIT框架使它变得非常简单.下面就是这些代码:
一个FIT Fixture(使用C#编程)
既然FIT fixture已经完成,等待我们的是在文档上运行,并且得到测试结果.首先,例子失败了,标记未红色(参看图1).既然测试失败,程序员必须修复它,最后例子变为绿色(参看图2).
在这里我想问一个问题,就是如何把文档里面值取出到软件的对应域呢,我记得当时我就是这样问我自己的.
?我想细心的人发现了一个现象.代码里的类名WeeklyCompensation不正好和表里的第一行相同吗,然后是类的成员不正好和表的列名相同,这意味什么呢?我想大家都明白了,其实表里面的值是和类的成员对应的.至于如何实现,我就不细说了.
图1.
程序员问客户一些期望讨论问题,同时,客户改进文档的清晰度,因此文档在将来可以作为参考文档了.测试审查这些例子,确保他们可以覆盖特性的所有重要方面.
如果他们发现新的东西,他们可以和剩余组分享这些新东西.这样FIT文档就越来越成熟了.
图2,结束的FIT 文档
最后,还有一点需要补充,就是如何运行FIT文档,参看下图
客户的参与对软件成功是关键的.作为一名程序员,你需要一种方法来理解客户的需求,因此你才能写出很好的软件.FIT为你和你的客户提供了一种方法来精确的交流和协作.
对于其核心,FIT只是一个非常简单的工具.是一个“集成测试的框架“(Framework For Integrate Test,其实就是FIT的全称),也就是说,它是一个翻译HTML编写的文档,在你的软件上运行他们,然后以HTML格式报告结果的框架.这些是你的客户编写例子的测试.用来钩住这些测试到你的软件中去的fixture则由你自己来编写.
. FIT的简单掩盖了它的实用性.尽管FIT运行测试,但是它不是关于测试.它给你的客户提供一种你的软件做什么的方法.以及给你提供一种你和你客户讨论详情的途径.
因为FIT可以读写HTML,又因为Word和类似的商业工具可以读写HTML,所以你的客户可以直接编写FIT文档.这是至关重要的.需求文档的一个问题是这些文档通常不是由客户自己来编写的.甚至客户很少阅读他们. 结果,我们失去了宝贵的合作机会.这种事情的发生不计其数...对于大项目也是如此.我们每个错误的详情就是软件中的一个Bug.我们需要一种方式让客户考虑细节,并且和我们一起讨论.
FIT是一种方法.它允许客户提供正确行为的实例,并且看软件利用这些实例可以作什么.他允许客户拥有这些实例.这是非常重要的.鼓励他们这样去做.给他们反馈和他们将得到的控制.客户的参与对软件成功来说非常重要.FIT将帮助你得到这些,如果你这样去做,你的软件会更好.
使用FIT和客户一起工作
使用FIT的一大部分是帮助客户参与,因此你应该从阅读IntroductionToFit 和CustomersQuickStartGuide.开始.注意FIT的生命周期,查找你能帮助客户参与的方式,从程序员的角度上,本节不会反映CustomersQuickStartGuide .
当你开始开发一个新的特性时,你应该和你的客户讨论(在这里,对于“客户“,我们是指:“从业务的角度上说,知道特性最多的人“,“有些人称他们为'主题事件专家“)通过白板收集,倾听客户的解释.然后要求他/她描述特性使用的例子.
许多客户更乐意讨论应用程序的界面,而不是底层的需求.在初期,你可能得到用户讨论的例子,而不是底层的业务规则.这些例子模糊了客户的真正的需要,并且他们非常难以编写和维护.
你应该逐步掌舵你的客户朝讨论围绕业务规则的例子的方向上去.例如,如果客户说“会计师按这个按钮,将会得到一个时间卡,然后计算雇员的薪资“,你可以问时间卡和最后薪资的例子.
你的客户描述例子,你应该尽可能的想问题.利用这些问题得到描述问题答案的额外例子.有时候你的客户不知道,或者被这个问题缠绕住.在这种情况下,把它放在一边.
你有一些关键例子后,帮助你的客户把例子转化为表.现在就要试着将表格和FIT Fixture工作.(下面有更多的fixture),得到例子.一旦你对表感到满意,重新定义他们的格式,使你能容易的用FIT实现.在你做的时候,当心不要遗漏了客户的观点.
你实现特征时,你肯会越过实例没有覆盖到的问题.把这些问题反馈给客户,和前面一样,使用他们帮助你指导客户产生额外的例子.
FIT不仅是从客户得到详情的途径,也是你的客户从你的程序里得到反馈的方法.向你的客户展示如何使用FIT,描述他/她如何对FIT作出改变,返回FIT,和查看结果.这将允许你的客户试验和产生更多的例子.你想让你的客户说:“我想知道软件如何处理这种情况...?“,然后通过在FIT文档增加额外的例子来得到答案.
运行FIT
剩下的文档讨论使用FIT的技术方面.为了得到你的FIT版本的更多信息,参看TechnicalReference.我们快速覆盖了许多方面,因此你也可以在FitDocumentation,看其例子,像SimpleExample.
FIT是命令行工具(参看“TechnicalReference.的FIT Command Line“),这允许你在你的脚本里很容易的包含他.它得到一单个HTML文件,处理它,输出结果(其实时输入文件的一个备份,只不过单元格用红色和绿色标记)
许多商业级的工具保存文档为HTML,例如.Word.仅需要“File-->Save As“,然后选择HTML.FIT对保存为HTML的文件工作良好.
Excel也可以将文档保存为HTML.但是它保存整个文档为一个巨大的表格.结果,FIT不能直接对Excel文档工作.可以将Excel文档剪切复制到Word里.他们将作为表格跨越,而且工作良好.
表和 Fixtures
FIT实例存贮在表里.FIT通过查询HTML的<table>,<tr>和<td>标记得到他们.一般情况下,它实际不知到如何分解HTML.这个有意的设计决定允许FIT保持简单,并且可以和更多复杂的,甚是是很难看的HTML工作.
FIT从文档的第一个表开始,接着处理每个表.每个表都有一个fixture和它相关.这个fixture就是用来处理这个表的.Fixture运行代码,对他们的表做出改动(比如标记为红色和绿色),以及返回结果给FIT.
Fixture由你自己编写(参看 TechnicalReference.的“Fixture基础“),一个Fixture就像是表的一个小型翻译器.每个客户创建的表需要一个Fixture,但是你为多个表可以使用他们.
. 例如,在下面的图中,表由一个称为 "Payroll.Fixtures.WeeklyCompensation"来处理,FIT需要知道那个fiture执行哪个表.把fixture的全名放在表的最左上单元格里.例如,在下图中,表格由Payroll.Fixtures.WeeklyCompensation".来处理.
Fixture内幕
你的fixture对表可以做任何他们想做的,包括增加行和单元格(参看TechnicalReference ,查找如何进行),但是大多数fixture仅仅标志单元格为对和错.这里由一些标记的规则:
- 绿色 Fixture比较单元格和软件,他们匹配
- 红色 (包括 "expected" 和 "actual" 部分): Fixture比较单元格和软件,他们不匹配
- 黄色: fixture有错误
- 灰色文本 在白底: 单元格是空,因此fixture显示自己的答案
- 黑色文本 灰底: fixture忽略单元格
这里有Fixture在表中查找的一些关键词:
- 一个完全的空格(Blank cell):Fixture试着在里面填充答案(它将给单元格着上面描述的灰白颜色)
- 单词"Blank":Fixture把它翻译为一个空字符串.(它这样做是因为一个实际是空的单元格意味者"给我一个答案",如前面提到一样)
- 单词"error": Fixture期望一个错误.如果错误发生,单元格将标着绿色,不是正常的黄色.
这些跟随你可以达到你自己目的的fixture.他们描述如下.简单的说,他们是:
- ColumnFixture
- RowFixture
- ActionFixture
- SummaryFixture
ColumnFixture 是最简单的一种编程fixture,也是最有用的一种,你应该经常使用ColumnFixture
一个ColumnFixture 是为表格里的单行所表达的例子的.一个表可以包含多个实例,一行一个,见下面:
为什么称之为"column"fixture呢?因为表中的每列映射你的fixture里的一个对象或者方法.FIT使用第二行列头实现映射.
当一个列头以括号结尾,fixture调用一个方法,而不是设置一个变量.fixture看看从方法返回的值,然后把它和表里面的值比较,然后根据情况着红色获绿色.
结果,所有这些使你编写自己的ColumnFixture显得几乎微不足道的.下图描述了上面用C#编写的Fixture:
ColumnFixtures从左到右,从上到下处理.根据上面的2个图,它好像是你和客户已经写了类似如下的代码:
// Row 1 StandardHours = 40; // the StandardHours column HolidayHours = 0; // the HolidayHours column Wage = new Currency("20"); // the Wage column CompareResults(new Currency($800), Pay()); // the Pay() column// Row 2 StandardHours = 45; HolidayHours = 0; Wage = new Currency("20"); CompareResults(new Currency($950), Pay());
// etc...
注意变量在行之间没有清除.
后面的文章将对FIT的ColumnFixture和RowFixture两个重要的类作介绍
(---Continued--)
以上来于来源http://fit.c2.com/wiki.cgi?ProgrammersQuickStartGuide,一部分自己所写,一部分翻译原文档.
前面简要讲了关于FIT的用法(参看FIT For .NET(0) ,FIT For .NET(1) FIT FOR .NET(2)),在接下来的文章中,我将详细介绍FIT的用法.由于FIT的不断更新,其文档也是不断进步,所以为了得到最近的信息,请访问http://fit.c2.com .
首先介绍ColumnFixture:
Coulmn映射测试数据的列到子类的方法或变量.
一个新的Column fixture为每个使用它的表创建,同样的Column fixture会从上到下处理每行,从左到右处理每列.CalculatorExample这个例子就是这样.x()因数时第一个方法列,不管Key如何改变,都可以得到检查
你可以参看一下资源:
还是举个例子详细解释一下吧.
拿个算术的例子.这个算术包括加减乘除.
我们可以写测试案例为(以表的形式):
eg.ArithmeticColumnFixture | |||||
x | y | plus() | times() | divide() | floating() |
2 | 3 | 5 | 6 | 0 | 0.6666667 |
0 | 0 | 0 | 0 | error | error |
0 | 0 | 0 | 0 | ||
200 | 300 | 500 | 60000 | 0 | 0.6666667 |
2 | 3 | 10 | 10 | 10 | |
200 | 3 | 5 | 6 | 0 | 0.6666667 |
2 | -3 | -1 | -6 | -0 | -0.6666667 |
然后写出加载FIT框架的代码:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

下面解释一下:
注意到表的第一行:
eg.ArithmeticColumnFixture
什么意思?看看源代码,你发现了什么呢?,没错,表的第一行就是源代码所描述的类的名称.你可能已经想到这个类的方法和表的关系了.
很明显,表的x,y分别对应代码12行的public int x;13行的public int y;(这里x,y必须为public).
后面的plus(),times(),divide(),floating()那就分别对应类的其他方法了.
所以,我们可以想象得到FIT框架其实就是读取以表格形式描述的客户测试案例的数据到测试类里面去,然后配上NUnit的协作,最终完成了自动化测试.