五一教练组活动全记录(原始记录)

来源:互联网 发布:变声氦气淘宝 编辑:程序博客网 时间:2024/05/02 00:43
记录人:NULL

五一期间,教练组利用传统的长假组织了一次活动,专门来讨论和实践自动化测试方法。

5月5日,雨
早晨起床,正下着小雨,从东校区走到东一基地,正好快9点,realdodo早已在那里等候,继续稍等片刻,人都到齐。参与人员包括:wikiexe、lyide、yeldsd、asile、gump、liyong、realdodo和NULL,培训正式开始。
realdodo首先让大家谈谈自己关于软件测试的看法或经验。大家分别发言,yeldsd提到与陈琦顾问合作开发中的测试工作,同时说到陈琦顾问建议他们多在代码中写 assert ;gump谈了一下公文组的测试工作,他认为参与测试的人越多越好,因为每个人使用软件的习惯及想法都不一样,越多人测试,越能发现问题;wikiexe对目前测试方法下的测试充分性感到担忧;liyong谈到以前在 Java 组时,肖何使用了 JUnit 这个测试工具,并且他们一般都先写测试用例,后编写代码。大家的发言总结起来就是:大家都认为测试非常重要,同时也认为目前的测试工作是不充分的,测试方法及测试流程都还存在一些问题,但是目前又不知道怎样解决这个问题。
realdodo总结了大家的发言,并结合自己的经验,讲述测试相关的内容。他说,软件开发从大体上来看,分为以下三个大的阶段——设计、开发、测试。从另外一个角度来看,整个软件开发过程其实也是一个测试过程,开发测试设计是否合理,而测试则测试开发是否正确。接着realdodo画了一个坐标图,横轴为时间,纵轴为与甲方交流、设计、开发、测试等各项工作投入的工作量,他首先标出了一个比较标准的软件开发过程中在各开发周期各方面的投入量,接着又画出了我们的软件开发过程中各周期各方面的投入。两个图对比发现,其实我们的软件开发过程与标准软件开发过程相比,差别很小,只是测试投入的过晚,测试投入的工作量太少。虽然这在图中只是一个比较小的差别,但是影响是很大的,这点差别直接导致两个开发过程的产品质量上的巨大差别。根据这个对比结果,realdodo给出结论,如果我们对目前的开发过程作一定改进,及早地引入测试,加大测试的投入,我们的软件质量将大大提高,而实现这一点的实际措施就是我们即将介绍的单元测试。
realdodo然后介绍了测试相关的一些理论知识。测试一般来说包括单元测试(UT)、集成测试(IT)和系统测试(ST)。我们目前在系统测试方面有较大投入;集成测试由于其特殊性,在一般的软件开发中可能并不进行;我们缺乏的是单元测试。单元测试的不足,直接导致软件质量上不去,重构困难,先前开发代码重用困难等问题。测试是无法达到完全覆盖的,例如一个简单的实现加法运算的函数 int add ( int a, int b ) ,如果要完全覆盖这个函数的各种情况,则至少有 MAX_INT * MAX_INT 中情况,这是不可能的。因此实际进行测试时,我们只是选择各种典型情况下的典型用例进行测试,例如普通情况、边界情况等等。测试是无法达到完全自动化的。自动化测试只是提高测试效率的一种方式,无法满足所有的测试要求。在实际测试中,都同时采用手动测试和自动测试,两者互补。为了保证测试的有效性,需要制定测试计划,如何制定需要根据各项目的实际情况决定。
最后,realdodo介绍了一般怎样进行单元测试。yeldsd之前提到的在代码中加 assert ,是进行单元测试的一种方式。例如,对于add 函数,assert ( 3 == add ( 1, 2 ) ) ; assert ( 0 == add ( -1, 1 ) ); 就是在进行单元测试。从以上的举例大家都可以感觉到,使用 assert 进行单元测试很不方便,并且过多的 assert 使得代码难看。为了方便测试,我们需要一个满足我们要求的单元测试工具,它要能够管理测试用例,自动执行测试用例,并且测试代码与正式代码分离…… realdodo然后介绍了一下比较流行的 Java 测试工具 JUnit,说明了单元测试工具的必要性和便利性等。接着又介绍了自己开发的、即将开始使用的用于C 语言单元测试的工具 RCUnit(全称Rich CUnit)。
讲述完毕之后,realdodo和我分别在电脑前给大家演示如何使用 RCUnit,并就相关问题进行简单讨论,然后大家各自编写小例子,使用 RCUnit 进行单元测试,进行实际演练。

(大家都做完小例子之后,时间已经到了12点左右,准备去吃饭了,此时正下着大雨。我和lyide共一把伞先走了,去教工的路上接到电话,说打电话订盒饭,让我们回去。于是我们回了,不过这是一个错误的决定。打电话订了盒饭之后,我们便在东一基地等着,可一等再等,就是不见有盒饭送来,真是又困又饿,有的还没吃饭就躺着睡着了。在等了一个多小时之后,盒饭终于到了,看着送来的盒饭,我们都觉得亏,亏在等了这么久,也亏在价格上。不过都饿了,也顾不得那么多,先吃了再说。)

下午的培训从2点开始,realdodo首先总结了上午的培训情况,然后我给大家讲解马上用来演练的程序的已有设计及接口。我们为大家准备的演练程序是一个简单的词法分析程序,要求能够统计一个 C 文件中,关键字、函数名、注释等出现的次数。我们已经先实现了程序输出信息、语义分析都功能,需要大家实现词法分析。大家所需要关注的只是一个接口:BOOL LexicalParseString ( char* pszStr ); 大家需要从输入字符串中解析出 C单词、注释、运算符的信息,并保存到以 g_LexicalItemList 为头的一个链表中去。接口介绍完毕之后,我又说了一下具体的需求,大家就开始自己做了。大家做的过程中,也多次就需求或 RCUnit 使用方面的问题交流。大家都做得非常投入、非常认真,最先对于RCUnit 的使用不熟,速度慢一点,但是过了一段时间之后,大家都逐渐进入了状态。到快吃晚饭时,yeldsd已经基本完成了所有需求,liyong也完成了大部分需求,其他人进度也不错。到了晚饭时间,大家都还在投入地编程中,没有人提出去吃饭,难道是因为realdodo之前“不完成,不能去吃饭”的一句戏言?呵呵~~ 大家太投入了。吃过晚饭,大家继续编程,我和realdodo继续在一旁,就相关问题进行指导。后来yeldsd和liyong完成了全部需求,并通过了realdodo的系统测试工具的测试,他们先离开了。其他人继续努力,一点也没有松懈,到晚上10点左右,基本上大家都完成了所有需求,并通过系统测试。lyide在通过系统测试之后,颇有感慨。“这可能是我写过的最长的 C 程序了,真的没想到我可以完成这个程序,实现所有的需求,我想,如果不是用 RCUnit 这个单元测试工具,这对我来说,基本上是不可能的事情。”

5月6日,晴
昨天大家基本都完成了程序,可见大家的攻击力还是都很强的。今天做什么呢?在实际项目中,甲方经常会变更需求,这逼迫我们在已有代码上修修补补,使得代码质量大大降低,最后都不愿承认代码是自己写的。今天我们也要改改需求,让大家更进一步的体验单元测试工具在实现新需求时起到的作用,体验单元测试工具自动回归测试的作用。
realdodo首先介绍了重构的概念。甲方的需求变更,使得我们不得不对原有代码进行修改,有时甚至对整个设计构架进行修改,但是由于测试工作做的不好,对整个设计构架的修改直接导致软件质量急剧下降,引入很多bug。正因为修改整个设计构架会导致这么多的问题,我们在实际项目中尽量避免这样做,一般都会在已有设计构架下修修改改,即使这个设计构架对于新需求来说根本不太合理。引入单元测试之后,由于单元测试工具会自动进行回归测试,它会保证你修改后的代码的正确性,因此使用单元测试工具会极大地增强重构的勇气和可能性。

我们提出的新需求有三点:
1.    要求支持 ++、--、<=、!= 等复合运算符的识别;
2.    要求尽量的检测错误,例如非法字符等;
3.    要求解析 i++++; 等比较变态的表达式。

需求讲解完毕之后,大家开始干活儿了。可能是昨天大家都那么投入,早熟悉了RCUnit 的使用,熟悉了词法分析的基本过程,大家的进度都比较快。到吃中饭时,大家基本上都完成了所有需求。今天没下雨,中饭在教工吃。下午从2点钟正式开始,大家对自己的代码稍作修整,便基本上都通过了系统测试。这似乎有点出乎realdodo的意料之外,没想到大家这么快就实现了新需求,原计划是下午3点完成。既然大家都已经完成,那么进入我们的下一项内容吧。下一项内容是大家一起讨论这两天来,大家实际使用 RCUnit 进行单元测试的感受和想法。
realdodo首先还是总结了一下上午实现新需求的情况,并谈了一下,在实际项目中,我们在测试方面怎样应对甲方的需求变更,主要是测试框架的选择和使用什么测试方法两方面。两者要共同保证测试易于回归,保证之前已有功能不丢失,使得项目继续正确地进入下一阶段。realdodo总结完毕之后,大家开始谈感受和想法了。

liyong:单元测试工具可以自动监测代码是否正确,感觉这种开发很爽。通过用例之后,感觉很放心,很有信心进入下一阶段的开发。
gump:与liyong的感觉比较象,但是同时也有点担心,会不会因为在通过用例之后过于放心,而导致更多的问题。
wikiexe:每次修改代码之后,进行编译的时候,就会自动执行测试,监测代码是否正确,这让人有一种很强的安全感,尤其是需要对代码甚至设计构架有较大改动时。但我在开发中,潜意识里尽量避免写太多的测试用例,毕竟我们的主产品不是测试代码,而写测试用例还是需要花较多时间的。那如果在项目组中推广这种开发方式,怎样保证组员写的测试用例能够达到测试要求?
yeldsd:我采用的方式是,先写测试用例,然后编写代码,通过测试用例之后,不会再继续写测试用例。建议首先进行设计,然后再编写测试代码和正式代码。
lyide:我之前没有写过较长的 C 程序,使用了这个单元测试工具,我才能完成整个程序。这个单元测试工具能够随时监测程序的执行结果,能够保证代码质量,感觉这个工具非常有用。

从大家的发言来看,效果还不错。之前realdodo和我都担心,如果没有较多的项目经验,如果没有对测试的理解,进行单元测试的培训估计很难达到预期效果。这次培训的结果证明我们错了,也证明大家都需要单元测试工具。大家的发言同时也说出了一些引入单元测试的问题和阻力,这些都是在以后实际操作中,需要注意的问题。不管怎么说,不论是有较多经验的,还是经验相对少一点的,都觉得单元测试很有必要,觉得这个工具比较有用,这就达到了此次培训的目的,这让我和realdodo都比较高兴。

还剩下最后一项内容——向大家介绍一个文档生成工具 doxygen。这个工具能够从原代码中提取信息,生成 html、pdf、xml 等格式的文档,如果能够在代码中按照 doxygen 的格式进行注释,生成的文档更好。这样的文档将是后续开发人员最愿意看到的技术文档。realdodo在自己的笔记本上给大家演示了 doxygen 的使用方法,大家似乎都比较感兴趣,围成一团,看着realdodo的演示,引得旁边预备队的师弟们也忍不住探过头来看看。介绍完毕之后,大家各自到电脑上安装 doxygen,并实际操作了一下,同时我们也就相关问题开展了讨论。
原创粉丝点击