-
2007-09-17
闲聊C++单元测试框架
今天下午,和Darwin聊了一下C++单元测试框架,主要参考对象是CppUnit和CxxTest。
表现形式
因为C++不支持reflection,所以,必须要做一些额外的工作,让框架知道相关内容的存在。CppUnit的做法是用宏进行注册。这种做法要求我们每添加一个测试,就要考虑用相应的宏进行注册,这种做法很繁琐,最大的问题在于由于疏忽而遗漏,这种靠人工保证的东西不可靠。在这点上,CxxTest做得要好一些,有一个专门的脚本做这件事。通过这个脚本扫描这个自己编写的文件,生成一些新的文件,完成这个工作。从代码的表现力和可靠度来说,要好得多。唯一的问题是引入了一个脚本,而且这个脚本一般是由某些动态语言写成的(目前的CxxTest有Perl和Python的脚本),从而引入了对这种语言的依赖。不过,由于C++语言本身的限制,从接口的角度来看,这种做法已经很不错了。
语法
有一种C++的单元测试框架叫TUT,Template Unit Test的缩写。顾名思义,它是用模板完成的(其实,CppUnit和CxxTest都有模板的部分)。随着C++编译器的进步,在大多数情况下,模板都是可以顺利通过编译的。但是,不要忘了,还有一种环境叫嵌入式,那里的编译器基本上还是很原始的,模板并不见得能够顺利的通过编译。
此外,模板还会带来另外一个问题,编译时间的增长,相信有过模板编程经验的人都会对此深有体会。编译时间增长意味着什么?我们接下来讨论。
编译时间
有一种敏捷实践叫做测试驱动开发(Test Driven Development)。测试驱动开发的基础是单元测试。测试驱动开发希望达成的一个目标是快速反馈,所以,站在C++语言的角度,如果执行时间受限于代码本身无法缩短,那么我们希望编译时间尽可能短,这样,才不会把生命都浪费在等待代码编译上。
除了刚才提到的模板问题之外,CppUnit会把所有测试编译生成一个可执行文件,这意味着什么?几乎修改任何一个文件都会造成这个文件的重新生成。随着目标文件的增加,这个过程时间就会增长。相对于修改范围(可能只是某一个文件),还是显得有些长了。为什么Java语言不会存在这种现象?因为Java是动态连接的,所以,Java生成.class就结束了。对应到C++上,这只是完成了目标文件的生成,而在C++我们不得不再进一步生成可执行文件。从道理上,CxxTest可以为不同的测试文件生成不同的可执行文件,不过这么做又少了总体的过程,统计起来又显得心有余力不足了,而且通常不会这么做。
个人而言,对这几个单元测试框架都不是非常了解,如果前面的讨论存在谬误,欢迎有识之士指出。 -
2007-09-10
XRuby一岁了!
一年前,yawl将自己用业余时间做了一年的项目开源了,这就是XRuby。
XRuby project is now hosted on Google Code
有人愿意做Ruby Compiler么?
我就是那时加入XRuby的,依然记得最初见到这个项目时的兴奋,转眼,一年过去了。从2007年1月29日0.1.0发布至今,我们一共发布了7个版本。XRuby正逐渐变得越来越有样子:代码越来越干净,功能越来越强大。
XRuby是我第一次真正全身心投入参与的一个开源项目:常常为自己漂亮的解决了一个问题而自豪,也时常为解决方案不够优雅而寝食难安。依然记得有几次,为了实现一个功能而熬夜;也有本来已经躺在床上,却难以抑制兴奋爬起来继续编码。这一年里,XRuby在成长,我也随着这个项目在成长,对Ruby语言的实现理解越来越深,从最开始的照搬C实现,到现在逐渐有了一些自己的想法在里面。在与大家合作的过程中,从其它人身上学到了许多足以让我受用终身的东西,尤其是yawl。相信其他深入参与XRuby的人与我有着类似的经历和感受吧!
其实,在这一年里,我也并非始终如一的对XRuby付出着。从项目最初开源到发布0.1.0之间有大约4个多月时间,完成了那个新runtime之后,很长一段时间,我并没有写太多代码。那段时间,应该是我参与XRuby过程,感觉最为黑暗的一段时间,因为确实看不到这个项目的方向,没有版本发布,漫无边际的代码等待着编写,而我写的新runtime又很难集成到XRuby里面。这个状态一直持续到0.1.0的发布,我似乎一下子看到了光明,尽管XRuby看起来那么不成熟,但我们的努力终于得到了一丝回报,于是,我兴奋的写下了《XRuby发布了!》 。
在我找回动力之后,XRuby也逐渐开始得到了越来越多的关注,项目成员也逐渐增多,XRuby也逐渐步入开发的正轨。每隔一个多月,我们就会发布新版本,每次新版本的发布,都增强着我们对XRuby的信心。XRuby的成员也通过各种途径向大家介绍着XRuby,也有人开始讨论XRuby。
做开源,最艰难的是什么?技术吗?似乎是,尤其像XRuby,仅仅一个“编译器”的名头,就足以让许多人望而却步了。其实不然,技术这东西,只有不愿意学的,少有难以学会的。参与XRuby并不需要一开始就掌握复杂的编译器技术,因为XRuby包括了许多部分,编译器只是其中的一个部分。时至今日,XRuby中的某些部分对我来说,依然是陌生的,但这并不影响我为XRuby编写代码。从个人的经历来看,builtin是一个很好的入手点,而那里并不多数情况下并不需要了解编译器,甚至几乎不需要了解Ruby内部实现。
在我看来,最难的是坚持。用业余时间,无偿为一个项目付出着。回报?除了知识和技能上的提升,其他都是不可预期的。在这种情况下,坚持着实是一件困难的事情。其实大家可以很清楚的看出来,这个世界上,开源项目不计其数,但真正能让人知道的少之又少,许多开源项目在开始后没多长时间便死去了。在国内论坛中,很多开源项目的发起者都在抱怨,开源环境很差,没有人参与他们的项目。当然,这其中也有项目本身吸引力的因素。其实,做开源是需要一些理想主义的,这样,才能在一条未知的路上前行。XRuby中也存在类似的问题,许多参与者一开始总是兴致勃勃的要求加入,好一些的,贡献了一些代码之后,便很长时间没有声音,有的则在加入之后,一行代码都没有写,便无声无息了。从加入开始一直比较稳定的贡献代码的人,屈指可数。不过,从另一个角度,这也说明了,当一个开源项目具备了一定的生命力之后,并不会因为某个人的不作为而死去。不管一路上有多少阳光和风雨,XRuby走过了它的第一个生日,步入了第二个年头,大家已经开始尝试着进行Rails的支持,我们会努力让它走得更好。在班加罗尔讲XRuby时,有人问过我,现在XRuby面临的主要问题是什么,我说,我们没有足够的资源。其实,现在可以看到的很多问题对我们来说,并不是非常困难,但却需要投入大量时间来完成。这也是我们始终如一的欢迎有兴趣的人加入我们的原因。如果你愿意和XRuby一起成长,欢迎加入我们!
-
2007-08-31
班加罗尔的Geek Night
做了一件让自己觉得不可思议的事情,在班加罗尔的Geek Night用英文讲XRuby。
这周早些时候,在办公室遇到了Sidu——我在西安办公室见过他。周五有个班加罗尔Ruby User Group的活动,叫Geek Night,Sidu是活动的组织者。之前,他知道Ola会来,于是安排Ola介绍JRuby。当他看到我的时候,才知道我也来了班加罗尔,于是邀请我也一起参加活动。我问他,我是否需要准备什么,他建议我做一个XRuby的介绍。Ola会有一个45分钟左右JRuby方面的介绍,所以,我需要做的只是一个简单的XRuby介绍。很合我意,因为要用英文讲,所以,如果讲多了,我恐怕自己不成。我很快就准备好了一个很短的介绍。
ThoughtWorks做事总是要敏捷的。今天,我发现Ola没来,后来才知道Ola病了。所以,Ola的部分就取消了。Sidu问我怎么办,我只好硬着头皮答应由我讲一个长一点的,一个比较完整的XRuby介绍。晚上六点的活动,商量好这些的时候,已经是四点多了。所幸之前讲过XRuby的介绍,我把讲稿翻出来修改了一番,更新了一些状态,准备用在活动中。XRuby介绍这个稿子居然得到了反复应用,第一次在北京Java User Group,第二次在敏捷西安,据说,XRuby的其他成员也用过。无论如何,我没想到,我个人的第三次居然是在班加罗尔,而且是英文。
其实,最让我头疼的绝对不是介绍XRuby,而是用英文。这周在班加罗尔上课,对我来说,简直就是一周的英文课。所有课程所有讨论都是英文,我的英文水平让我经常就不知道大家在说什么。不过,自我感觉,经过一些锻炼之后,还是略有提高的。
活动开始,我开始了第一次用英文在比较公开的场合讲东西。我的开场白是,这是我第一次用英文讲。起初,活动在一个小会议室进行,在我讲的过程中,进来的人越来越多,所以,我们又换到了一个比较大的会议室。因为用英文,我只能说,我尽量把我要表达的意思说出来,至于是否大家听懂了,我不好说。好在有讲稿,即便我讲得不够清楚,讲稿也会帮助大家多一些理解的。当翻到讲稿最后一页的时候,我长出了一口气。如果是用中文的话,我可以说得更多,至少我可以胡扯一些东西。对我来说,更大的挑战是Q&A。我的听力本来就不是太好,印度口音更是经常让我犯晕。开始之前,我找了几个同事,如果我听不懂的话,他们可以为我解释一下。在提问者的宽容和几位同事的帮助之下,我成功的度过了Q&A。问题倒不算太难,唯一让我不敢确认的是,我说的是否真的是我要表达的意思,希望没有大错。
不管怎样,我用英文讲了一次XRuby,一次很有趣的经历。 -
2007-08-28
交流技巧
在ThoughtWorks里,交流是工作中非常重要的一个部分,在这里工作时间越长,这一点感觉得越加明显。今天,和我们团队中的一个人聊天,他教了我一些交流上的技巧,这里做一个简单的备忘。事实上,他教给我的远不止这些。
交流中,最大的障碍就是双方是否真的理解了对方的意思。造成误解的原因可能有很多:
* 双方都认为自己理解了问题,但这种理解可能并不一致。
* 因为背景不同,所以,双方对达成一致所基于的假设是不同的。
* 语言之间的障碍,这点我最近颇有体会
* 双方对问题理解的深度不一致
同事交给我的解决方案就是不断问问题,不断解释自己对问题的理解,对方接收到反馈就会判断与他的理解是否一致,然后再给出他的看法,这样几个来回下来,双方基本上就可以达成一致。有些人可能认为反复的问问题,反复澄清自己的理解似乎会让自己的看上去很傻,所以,听得差不多就不愿意问了。我们的根本目的是完成工作,如果因为前面不愿意看上去丢人,后面可能就要真正的丢人了。其实,没有人会认为把问题搞清楚是丢人的。
再有一点,交流之后要尝试总结,通过总结:
* 确定真正理解问题所在
* 确定双方对问题有一个共同的接收标准
* 确定双方能够在进度上达成一致
学到了,争取用起来! -
2007-08-24
写在迪拜机场
写下这篇blog时,我在迪拜机场。没错,阿联酋迪拜。
起因是要到印度参加培训。ThoughtWorks通常会对入司的新员工进行一些培训,使其更加了解公司的文化和做事的风格,其中很著名的是TWU。不过,TWU是给毕业生预备的,所以,我没有机会参加。我去参加的是另外一个课程。不同于TWU固定在印度,这个课程的培训地点是变化的,这次刚好在印度的班加罗尔。
要去印度,我却出现在阿联酋,是的,我是来转机的。只要有些地理常识都会发现这条路线极其诡异。据Jessie的blog记载,她是这条诡异路线的始作俑者。早几天去TWU的几位同事是通过新加坡转机,至少从常识和心理上来说,更容易接受一些。
这次坐飞机让我见识了一些新鲜的东西。我乘坐的是A340-300,很大的飞机,一排有八个人。每个面前都有一个小电视,配有一个遥控器,居然这个遥控器还是个游戏手柄,所以,在路上,我还自行娱乐了一下。一上飞机,就可以发现,每个人的座位上,都预备好了一些东西,比如小枕头,毯子和一些小东西。我以为大夏天的可以不用毯子,结果充足的空调还是让我决定把自己盖上,以免感冒。这次旅行是我第一次在飞机上过夜,因为起飞的时间就是23:55。个人而言,我不是特别喜欢长途旅行,尤其需要过夜的,身体会很疲劳。飞机会比火车舒服一些,但要在飞机上过夜,还真的不如火车的卧铺,无论我怎样调整姿势,总是不如躺着的感觉舒服。当然,比火车硬座要好得多。同机的有一群要到塞浦路斯去表演的小朋友,有他们在,飞机上热闹了许多。人家航空公司想得还真周全,每个人送了一个小玩具,孩子们很高兴的给周围的人展示着自己的玩具。
到迪拜的时候是当地时间早上五点多,一下飞机却让我感到了桑拿天气,长期生活在这里的人真的要有很好的耐热能力才成。从我下飞机到再次上飞机,之间的间隔有六个小时。所以,我和同行的同事在机场可以活动的区间里转了一大圈,了解周边的环境。在一个免税的店里,他拿起一个Sony的耳机,我居然看到了中文,仔细一看,Made in China。在这里,中国人(至少是中国人面孔的)很多,让人误以为只是在国内的机场,经常可以听见有人在用中文聊天。当我们在一个地方喝水聊天的时候,竟然还有人用中文来向我们问路。就在写这篇blog的时候,后边过去的两个人在议论大连如何如何。迪拜的机场地上铺有地毯,这让我想起了我们公司的办公室。在办公室时,我时不时的就会坐在地上办公。在这里,可以看到很多人席地而卧,悠然入梦。
就在刚刚,同事奇迹般的发现,居然有无线网可用,于是,赶紧打开机器,在迪拜机场发一篇blog,作为纪念。
还有一段时间我才能再度起飞,若干小时之后,我会出现在印度。







