首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

ETDD历程——可视化

2013-01-26 
ETDD过程——可视化下面用一个简单示例,展示ETDD一般过程,使用的工具是Visual Unit。我们要编写一个函数,其功

ETDD过程——可视化

       下面用一个简单示例,展示ETDD一般过程,使用的工具是Visual Unit。我们要编写一个函数,其功能是删除字符串左边空格。

       步骤一,编写函数框架,能通过编译就行:

char* strtrml(char *str)
    {

    return str;

}

 

        步骤二,明确代码的最基本功能,就是确定程序最普通的输入是什么,应该产生什么输出。下图是填写最普通输入输出的界面,这也是第一个用例,填写完成后,工具就可以生成测试代码,并且将数据移到表格中。

ETDD历程——可视化

        步骤三,进一步明确代码功能,就是确定代码的各个功能点,把想到的输入分类都列出来,并且指定对应的正确输出。下图是生成数据的界面和数据表格。

ETDD历程——可视化

        步骤四,编写代码。ETDD促进开发的最主要效益在于程序行为可视。编写几行代码、就可以查看程序行为,然后修改错误、继续编写,直到测试全部通过。

假设编写strtrml()的思路是:首先计算左边空格的数量,然后再把字符串朝左边移动。先编写计算左边空格数量的代码(粗体且带下划线的为新增代码):

char* strtrml(char *str)

{

   int count = 0; //左边空格数量

   while(*str++ == ' ')

           count++;

 

      return str;

}

 

        每当想看看代码会做什么时,就可以编译当前源文件,通过编译后,测试自动执行,并显示测试结果,下图是上面的代码产生的行为:

ETDD历程——可视化

       如果想看看左边空格数计算结果对不对,由于这是局部变量,在内部动态变化,所以需指定打印。指定方式有两种:一是在测试工具中指定,好处是不污染产品代码,二是在产品代码中指定,好处是维护比较自由。这里采用第二种方式:

char* strtrml(char *str)

{

      int count = 0; //左边空格数量

      while(*str++ == ' ')

           count++;

     //>>int,count

 

      return str;

}

 

程序行为如下图,可以看到,左边空格的计算结果是正确的。

ETDD历程——可视化

接下来继续编写代码,把字符串朝左边移动:

char* strtrml(char *str)

{

      int count = 0;//左边空格数量

      while(*str++ == ' ')

           count++;

      //>>int,count

 

      while(*str)

      {

           *str = *(str+count);

           str++;

      }

 

      return str;

}

 

       现在已经完成移动了,结果对不对呢?看看程序行为:

 

ETDD历程——可视化

       结果是完全不对的。未出现红色代码,表示当前输入执行了全部代码。查看代码可以发现,在计算左边空格后,指针已经偏移,移动操作针对的是已偏移后的指针,且再次使指针偏移,结果当然不对了。所以要先把指针保存,每次偏移后恢复:

char* strtrml(char *str)

{

      char* ptr = str;

      int count = 0;//左边空格数量

      while(*str++ == ' ')

           count++;

      //>>int,count

 

      str = ptr;

      while(*str)

      {

           *str = *(str+count);

           str++;

      }

 

    str = ptr;

      return str;

}

       程序行为如下图:

ETDD历程——可视化

       现在可以看到,输出已经正确,再看用例的测试结果,6个用例,只报告了一个异常,其他都已经通过。点击异常信息,对应的程序行为如下图:

ETDD历程——可视化

       输入为空指针时,产生了异常,代码未判断和处理空指针。用例数据中,并无空指针输入,这是工具自动添加的用例。在产生异常的代码前加上判断空指针的代码:if(str == 0)return str;,测试即可全部通过。从上图可以看出,一种输入下,往往只执行部分代码,程序行为不仅仅在于产生了什么输出,还包括执行了哪些代码,即程序行为=输入+所执行的代码+输出。

       到这里,代码写完了,测试工作也同步完成。在这个过程中,付出了什么?获得了什么?

所付出的是明确程序功能的步骤二和步骤三,即根据程序的设计功能将输入输出数据列出来,这不需要多少时间,因为在编写代码前,程序员本来就需要想清楚这些,只不过用这种简单的方式记录下来而已。

       所获得的主要有三点:

       1) 在编写代码过程中,程序行为一目了然。写代码很难一气呵成,要频繁回顾上下文,但代码与文字不同,它的真正意义在于执行起来会做什么,这是眼睛看不出来的,需要在头脑中推理。推理是隐性的但高强度的脑力劳动,ETDD省略了这种推理,减轻了头脑的负担,能够比较轻松地整理思路,思路有偏差的时候,能够及时做出调整,这可以大幅提升编码效率,并降低劳动强度。

     2) 基本上免除调试,调试是最花费时间的。ETDD与TDD不同,首先关注的是程序行为而不是测试是否通过。很多函数,一个功能点的实现就需要大量代码,甚至代码基本写完时,第一个用例才能通过,在这个过程中,关注测试是否通过没有意义。ETDD可以更频繁地执行测试,在最短时间内发现错误并改正,且程序行为已经很清楚了,基本上不再需要调试。

     3) 测试与开发同步完成。传统开发模式下,很多程序员都将单元测试视为包袱,而ETDD使单元测试变成开着走的“车子”,而不是背着走的“包袱”。

      ETDD并不要求测试所有代码,程序员可以只在编写有一定复杂度的函数时,才使用ETDD,这种时候,程序行为可视化对编码过程帮助很大,形成强烈的吸引力,使单元测试由“要我做”转换为“我要做”。

       无处不在的80-20规则,在软件开发中同样存在,也就是说,80%的编程时间消耗在20%的代码上,这20%就是功能逻辑复杂的代码。当一个函数的功能比较复杂的时候,ETDD可以节约一半以上的编码时间,复杂度越高,效率提升越大。假如我们只在编写这20%代码时,使用ETDD,理论上可以提升编码进度40%以上。排除阅读资料、中间休息、会议等时间,实际上可以提升进度15-30%。ETDD更大的效益在于产出的代码质量可控,使后期调试排错的时间减少60-80%。总的来说,引入ETDD,项目所耗费的人月可以减少大约30-50%。由于软件开发无法做到同条件重复比较,难以得出精确的实验数据,上述数据只是根据经验得出的大致估计,您可以通过体验和评估来得出自己的数据。

       先写产品代码的框架,会不会有违测试先行的理念?当然不会。在编写一个类的测试代码前,难道不需要在心里想清楚类名是什么,父类是什么?在编写一个函数的测试代码前,难道不需要想清楚函数原形是什么?如果这些不确定,如何编写测试代码?在心里想清楚和写出来有本质区别吗?所以,先把这些确定的东西写出来,并不违背测试先行的理念,而好处很明显:工具可以根据代码框架自动生成测试代码。

热点排行