浅论C++在Windows下的GUI自动测试(Unit Test)

昨天,公司开发组与测试组开会总结上一个release的经验教训,期间就提到一个问题,如何更好的更自动化的测试程序。

公司正在研究的是IBM的RFT,这个东西不用说,一定是功能强大、极难使用,IBM的软件做的如此有特色,也是不易。问题是作为一个开发人员,我只想能够快速的、可重复、可添加用例的测试自己的代码,难道只能用屏幕定位、鼠标模拟、控件按钮定位这样的“高深”技术?

最近在开发的主要是一些接口,给另外一个产品使用,没有界面上的任何东西。美国的同事开发了一个测试程序,跑在命令行下,每次我添加一个新的功能或者修改了一些代码,他那边只要跑一遍,就知道对以前的功能有没有影响。

这个东西不新鲜,就是unit test,几乎每个新兴的开源代码(以java、python、ruby为代表)都会有一个unittest字样的目录,里面就是一些主要的功能测试代码。可是为何我们一直没有很好的利用这个工具呢?

我想原因也很简单,unit test需要开发人员更好的对代码进行抽象化、模块化。有人一定会反驳说,对于GUI紧密相关的,没法做Unit Test。这是一个问题,但是不是绝对的,也不能成为不进行unit test的理由。关键还是要很好的做到MVC各个模块分离,降低他们之间的耦合度。

通常对于一个Windows程序员来说,一个GUI界面,会包含几个功能,一是按钮或者控件的响应,比如按下一个按钮,它要变成灰色,直到运行功能完成再恢复原状,或者是一个控件,点击一下会让用户输入,输入完成以后校验,根据校验的结果保存或者提醒用户出现问题。这些都是比较common sense的流程。

但是这些流程显然不是原子的(atom),它们涉及到了M(model)、V(View)、C(control)的各个方面,对于Windows程序员,这三个方面往往都被放入到CXXXDialog这样的类里面实现,自己还感觉封装的非常好。

我们就拿用户校验来说明一下如何分解这个MVC过程。

“一个控件,点击一下让用户输入”,这一部分显然是V和C的,个人感觉,这部分的测试可以由test方面做更深入的检查,开发人员需要保证功能实现完整,简单运行正确。

“接受用户输入、检查输入数据”,这一部分,显然是比较复杂的逻辑,涉及到Model和Control,View在这一部分可以被忽略掉,输入部分就是数据,输出部分就是检查的结果。很显然,这一部分可以被包装、抽象起来,自己单独做Unit Test。

“如果出错,反馈用户出错的结果”,这一部分基本上也是以View为主,是需要tester发现问题的部分。

“如果正确,保存用户的输入”,这块很显然也是可以分离出来单独进行自动测试的。

从上面分析可以看出来,GUI的测试不是不能进行,而是需要开发人员做更多的工作,需要很好的抽象逻辑计算部分的代码,如果可能,界面展示规则代码也可以抽象处理单独测试。

这不容易实现,但是值得去做。

另外,在研究C++的GUI测试,发现了一个很好的帖子:http://bytes.com/forum/thread606579.html

摘选一些比较精华的部分,中文部分是我的简单翻译:
Do a google for ‘TFUI’ – its a good technique for your problem.搜索一下“TFUI”,这是一个很好的技术,可以用来解决你的问题。(我找的结果是这里http://c2.c2.com/cgi/wiki?TestFirstUserInterfacesPrinciples)

Aside from that, the main approach is to treat the GUI library like any other 3rd party library – mainly, don’t try and unit test it, unit test your code that uses it.另外,主要的一点是应该把GUI库当作其他的第三方库来看待,不要试图对他们做单元测试,要测试使用这些库的代码。(简单说,就是不要测View界面部分,而是测试逻辑或者数据部分)

By this, I mean: ensure all of your logic (business rules, gui presentation rules, data retrival and updates, etc) are completed separated from the gui code. In your gui’s event handlers, don’t do anything except delegate to a plain old C++ Class.我是说:确保所有你的逻辑(商业逻辑,gui展示规则,数据存取更新等等)是完全的与界面代码分离,在GUI事件处理里面,不要做任何事情,除了代理到一个简单的C++类里。

By separating your code from the gui code, you can easily test your code, without having to even link to the gui library.通过分离代码(功能部分、规则部分)和GUI,就可以很容易测试代码而不需要连接到GUI库。

In software, abstract is usually the way to solve a problem.在软件中,抽象通常都是解决一个问题的办法。

Andrew

另一篇回复,

————————-

Its a great book for working with un tested code, and for seeing how
to create ‘seams’ between areas like GUI libraries and our code.(这本书应该是《修改代码的艺术》)

For those interested in unit testing, a good guide that M Features,
myself and plenty of others use is:

A unit test does NOT :
* Use any file IO
* Connect to a db
* Present anything on screen
* communicate across a network.

单元测试不应该:

1,使用任何文件输入输出。

2,连接到数据库。

3,展示任何东西到屏幕。

4,通过网络连接通讯。
The rational for this, is many, but boils down to forcing us to create
a design that is decoupled from these areas, which nearly always
results in a good, clean & highly cohesive design. For example, how
many times have we in the past put logic directly into a dialog
class? Where as with this style of testing, we force ourselves to
separate out the UI aspect from the logic part, resulting in us using
the MVC or MVP or Humble Dialog design patterns, as they allow us to
unit test the logic without going anywhere near the GUI.

The second major win is speed of test runs.

I can run 1200 unit tests in 42.7 seconds currently (and these are
Java unit tests!) because of following these guidelines. And because
they run soo fast the Team runs ALL tests ALL of the time.
Slow tests mean we run them fewer times, the less we run them, the
longer it is before we find out we broken something. The longer time
before finding out we broke something, the more costly it is to
fix…..

Andrew

奥运感想

在写这篇文字的时候,闭幕式只有半小时,cctv里提到少林弟子要来,我倒,不知道释永信CEO会不会亲身上阵。

大连这地儿,还是没添多少可以运动的场所,考研时经常去打打篮球的中学,早就变成了全封闭。奥运,除了看看几个比赛,聊聊花絮,跟我,没有任何关系。

这大半个月,还是有很多传奇。最值得花絮的,就是艾蒙斯,他打中了多少环并不重要,大家看到的,是他妻子捧住他的脸,那时的温柔。不知道大家是不是跟我一样感慨,有爱,真好。

奥运,鸟巢里有多少人是它的建筑者,重新回到那里?有多少人,建造了鸟巢之后,被劝回家乡看奥运?我不知道。

2008年8月以后,大多数少年会选择篮球作为他们的主要运动,中国男足,就是一堆狗屎。

回到家乡的运动员、教练,为另一个国家效力,当他们与中国队员交手,那震耳欲聋的“中国加油”会让他们有什么感触,很值得联想。

刘翔,当时为何退赛,是不是有阴谋?足可以拍个电影了。我还是支持刘翔,无论如何,他已经做到他的本分。

这届奥运会,如果有遗憾,那就是假,唱歌的假唱,体操的年龄让人怀疑。为何不能真实一点,哪怕不够好。

张斌、胡紫微又出来了,真是春风吹又生啊。

2008年这个多事之年,会不会因为奥运“冲喜”变得好一点?我也不知道,我只是在一边看着罢了。

走出阴影

从刘翔放弃比赛那天开始,心情就跟着飞速滑落,原本以为刘飞人会再度点燃激情,激发国人斗志呢,结果却大出所料,那么平静地退出比赛,离开赛场,甚至最后连个鞠躬致意都没有,到底为什么啊?他欠我们所有关注他,关注奥运比赛的人们一个解释!

赛后的新闻发布会只看了个结尾,看到刘翔的孙指导坐在摄像机前拼命“挤眼泪”实在难受得很,真是想不通,何苦来这一下,要么事先就跟大家坦白,身体状态不好,压根别去参加报名参赛;要么就利利索索跑完全程。整这一出是何苦,咱不知道真是他的伤病导致这样的结果,还是心理压力太大,担心跑不过萝卜丝儿,总之,是临阵脱逃了。刘翔的退赛不禁让人联想起战场上的类似状况:指挥官说冲,手下的士兵却掉头往回跑……该砍头还是枪毙呢?当然,奥运会毕竟不是战争,咱不更至于要砍头枪毙,但奥运会除了比赛成绩,最重要的是奥林匹克精神吧,挑战极限,挑战自我,虽然不用拼命去完成比赛,非得取得什么名次,但起码要尽全力去争取用最好的比赛状态,创造最好的比赛成绩吧,就算不跟别人比也得尽量去超越自我吧。你刘翔凭什么选择放弃,伤病真的到了那个地步,还是面对强大的对手胆怯了?该不是担心辜负中国人民的期望吧?这种临阵脱逃,恐怕比跑了倒数第一名更让人心里难过。实在百思不得其解啊,刘翔,你到底为什么要放弃,原来的张扬个性哪里去了,是不是雅典以后得瑟大了,啊?!

那天上午,我早早地就把家里一切收拾停当,准备好观看赛事直播,然而,等来的却是那样的结果,实在让人难过,什么心情都没有了。也可能是赶上状态不佳吧,接连几天都觉得没有力气跑去图书馆夺位置看书,就在家里做做模拟题,说到做题那阵子一直不错的,想不到那日判卷后正确率只有51.几几%,简直创了历史新低。面对一片片的错误题目我简直欲哭无泪,就这样子的成绩放弃算了,还学什么学:(

一个网友见我学习状态不佳就发了新青年上的五年四班佳作给我看,简直笑死个人,那仁兄建议我状态极度不佳的时候就适当放松一下,别逼着自己学,自己找点儿乐子,比如看看搞笑视频。放松两天以后心情渐渐好了起来,回过头一一总结了问题所在。心想,千万不能放弃,别跟刘翔那样让人瞧不起,切。

这两日状态渐渐好起来,今天上午的一套题目150道,对了100整,正确率66.666%!!!哈哈,太顺了,如果真能保持这样的状态,肯定没问题了,终于走出前两日的阴影,重新获得自信,简直开心死了,为了庆祝一下,特写此文作为自勉,加油哦,咱不跟刘翔学,哼!

被迫病休一天

理论考试迫在眉睫,再不磨枪恐怕来不及了,因此最近都是从早到晚地泡在图书馆里。

想努力学习也不是那么容易的事情,八月初,全市的中学生相继放假,去自习的人一下子多得可怕,有一次,我死活找不到座位只得跑到分馆,周二早晨八点多自习票就卖完了,等我赶到鲁迅路,分馆也满员,晃荡着跑到妖妖那里借口送系统盘呆了一会儿,下午回家恶狠狠地做了两套模拟题,累得眼睛都直了,于是下狠心,决定以后八点刚开馆就到。

然而,事情并没有想象中的简单,等我周三真的八点赶到时,排队的人能有百八十个个了,心想二三百座位应该没问题吧,结果买完票各个厅都走遍了,居然找不到座位,因为那帮小孩伢子有相当一部分没买票就去占了好几个座,让他们倒地方就跟我装可怜,说好话,你说拿他们有什么办法呢?最后只得气哼哼地跑到前台退票。要说怪只能怪图书馆管理太差,市内可以自习的地方太少,当然孩子们素质也有点儿低!话说回来,大清早的已经来了,总不能就回家吧,看架势去分馆也是类似情况,只得跑到楼上多媒体阅览室上网,做模拟题了,于是又足足在电脑前呆了一整天,晚上回家照样累得头昏眼花,跟帅哥诉苦,他说要怪只能怪我去得太晚。无奈,决定第二天八点之前死活赶到,而且跟他们学,先去占座,哼!

星期四,七点五十我就跑到图书馆了,一看还没开始买票,排队的人却比前一天多一倍,我赶紧一溜烟跑到西侧二楼的自习厅,居然没开门,而且门口有个老头把守,正跟两个中学生交涉,说是必须凭票进入,我心想,今天情况有变?改变路线!从转门刚探头进西大厅,“尹叔叔”就笑眯眯地说没到点呢。咦?奇怪了,什么状况呢,等我再去排队发现队伍居然从前台沿着一楼大厅顺时针绕了一整圈,是前两天的两三倍多,天啊,这要是能有座位不就怪了?来把死猪不怕开水烫得了,硬着头皮耐心跟着排队,果然主楼一楼二楼都没座位,到了西侧小楼发现先前的老爷爷还在门口,他严格按照凭票入场的做法,只开一扇门。等到我进去,惊喜地发现还有一些空位呢。就连排在我后边的那些人也基本都找到了位置,最后那老爷爷居然关了所有的们,领着几个持票者挨个排雷(打击占座的),这下子几乎就座无虚席了。自习厅静得让人欣喜,一早无话。

唉,早该加强管理了,那天我学得特别开心。眼见着身边那些小孩儿走马灯一样换来换去,进进出出,有些还真不是来学习的,聊天,睡觉,谈恋爱,还有些捞到座位,九点多钟就走了,半天不见回来,你说他们何苦呢,就算一块钱的费用太过低廉也不必穷折腾一气吧,又不学习,占地方干嘛,切。

因为连日来的湿热天气都没睡好,前天晚上突然特别凉爽,睡得舒服极了,可能也实在是累了,最近都睡得很早。早睡早起,空气凉爽,心情极佳,昨天七点四十就赶去排队了,人没有前两天多了似的,有几个小男生叨咕着说前一天前台如何过分,只按人头买票;门口的老爷爷如果过分,之能凭票入场,呵呵,打击的就是他们。因为人不多,居然一楼就有位置,坐下之后心里美得不行了,一上午愉快度过,可惜发现厅里冷气太足,吹得我胳膊腿冰凉,胃肠也有点儿不舒服,跑趟厕所才好一点儿,近中午,实在觉得难受就试着去小楼看有没有地方,那里虽然人多,但基本上是自然风的,没想到大片大片的空座任我去挑,最后找了个靠窗的坐下来。又美美地学了一下午,只是后来又跑了两次卫生间,胃肠实在不舒服,不知是头天晚上没关窗着凉了还是上午空调太猛。

三点来钟,有点儿坐不住啦,跑去主楼边上网边做题,还是不舒服,接个电话,四点多就跑去沃尔玛逛荡。帅哥说要找地方过周末,我实在懒得动弹,索性就在沃尔玛下面的味千拉面等他。没想到那家伙也肚子不舒服,一碗拉面进去觉得好一些,去超市转了转七八点钟回家还是不行,简单吃了点药,八点多就上床休息,下半夜三点又爬起来蹲厕所,今早实在没精神了。起来做了点混汤面没吃几口就跑回床上休息,书看了两眼便去会周公了,实在没囊劲儿啊,有数的嘛,好汉架不住三泡屎。幸好帅哥他没什么大碍。中午我迷迷糊糊起来,吃了药觉得舒服些,敷好绿茶祛痘面膜,把剩下的面条吃掉,下午渐渐来了精神,开始对着电脑做模拟题。

做题时帅哥还嘱咐我休息,那家伙居然知道心疼我?做题结果差强人意,又是60%的 正确率!被迫休息的一天也不敢放弃学习,逼上梁山了啊。要说真是惭愧,以前浪费了大把的时间,现在却把自己折磨成这样子,何苦?

帅哥说晚上想去吃圣道,我晕,明知我胃肠这么弱,那烤肉他吃着我看着啊 ,最可笑的是那家伙在我看书做题的当会儿睡了好几觉,刚才居然迷迷糊糊跑过来,没头没脑问我,你昨晚在哪里睡的啊。我的天,太阳刚下山,还没黑天呢,今天还没过完,他睡糊涂了,哈哈。这不又睡去了!

因为被迫休息,没有把宝宝接回来,现在时间不早了,估计沟里的三个人应该吃罢晚饭,打个电话去吧,跟孩子说声对不起……

你看你看,windows好傻好天真

微软这么多年,总在IT人心中扮演一个小丑的角色,甚至比尔盖茨这样的大商人基本上是被刻画成一个宅男或者是美国校园青春电影中的高智商低情商自闭症小伙,有人认为他是程序员,可是个人感觉,他作为商人要比程序员牛逼多了,二十一世纪最不缺的就是搞编程的,但是缺乏比尔盖茨这样的商业领袖。从能力、情商、家世、学历、钱财各个方面,他都比夹不斯(steve jobs)牛多了,可是两人站在一起,比尔一定是被取笑的那个,你说这是为啥泥?

奥运会了,2008年8月8日或者是8月9日,当李宁同志如飞天一般划过鸟巢雄伟的边际线,一个意外发生了。

一块屏幕蓝屏了。这真是好大好明显的一块Windows广告啊。

另外一件事,最近发现更新windows经常问我要一个setup(2).msi程序,后来看提示,像是windows active sync的毛病,于是乎进入控制面板,试图删除active sync,可是windows这个二竟然提示我,需要setup(2).msi,真真正正的够傻够天真。拜托,我是要删除,不是要安装。

没办法,到微软网站下载了active sync的安装程序,名字叫setup. msi,没有二。可是卸载程序坚持提醒我,它要的是setup(2).msi,真是二啊。改名重新卸载,万事大吉。

微软,你让我怎么爱你呢,这么简单的事,搞得这么麻烦。

超级模仿秀

大礼拜萌萌宝贝回来玩得很开心,星期天晚上又不想走了,可能孩子跟爸爸妈妈在一起的确是最幸福的吧,当然, 我们有她在家也增加不少乐趣,虽然幸苦些,还是值得的,因为是应该的啊。    毕竟是小孩子难免有时调皮,出现状况一般都是爸爸批评教育,我只是象征性说说她罢了,有一回不知是什么原因小丫头惹我不高兴了,跟她说一二三,要她改正,后来一个打岔就忘了跟她较劲,结果人家却不依不饶地,说了两次一二三,然后用很特别的腔调跟我喊:“我跟你说多少便了,啊?”最后那个啊语气特别重,明显就是在质问呢,末了还配合一个大大的白眼儿。我的天,这口气活脱脱小学老师训学生啊。后来,看我们对她那表现极为好奇,人家就又表演了几遍,每每都弄得我们哈哈大笑。

    在我们一再追问下,小丫头终于摊牌了,说幼儿园里的贝贝老师经常这样说她们,她本人因为总是鼓捣身边的小朋友也没少被老师这样子教训。再问她其他老师怎么对付她们的吵闹时,她就煞有介事地说,安静!闭嘴!当然不光说消极的,还表演了老师们夸奖孩子的情景,比如说很棒,竖大拇指,打立正之类的。

    说到高兴处,小丫头主动开始做操,背诵古诗,洋洋得意地说她已经会背诵《江雪》了,然后不等我们反应过来就高声背诵:“千山鸟飞绝……”当然还有《草》和《回乡偶书》,都是朗朗上口的,小丫头真是长能耐了啊,其实还有一首诗我俩都不会呢,惭愧,实在惭愧。

    期待下个周末到来,期待小丫头再来点模仿秀之类的绝活吧。

奥运杂记

1,开幕式好不好,得看跟谁比?如果国际奥委会有个最高花钱上限,那结果肯定不同。至于那上万上万的群众演员,中国肯定会用“志愿者”来称呼他们。据说伦敦的市长看完了开幕式就哭了,他们国家不是没钱,是没这能力,资本主义国家的缺点决定了他们没法无限制花钱和无限制的投入人力资源。

2,为何“外国友人”都是赞扬开幕式好?OK,想象一下你自己,如果请客吃饭,这客人还挑三拣四说菜不好吃,你还会再请他们么?不花钱就能吃能玩,漂亮小姑娘接待着,需要的只是动动嘴皮子赞扬两句,这他妈的好事谁不想轮上一次??

3,没人关心中国男足吧?他们爱死不死的,一帮彪子能踢好球?到了什么时候态度、素质都是很重要的。(update:果然屁了)

4,忘了主题歌了,什么玩意?汪峰加上张靓颖都强过他们两个百倍。当然问题不在萨拉和刘欢身上,他们只能算是戏子罢了,什么时候都轮不上他们说话。如果我能选,就是《飞的更高》加上《天下无双》,不挺好么?

5,有人说,运动会开幕式不重要,也不想想,如果这个开幕式花了几十个亿(我只能假设花这些),怎么不重要?更何况,花了多少钱根本没人知道。最简单的算法是,奥运会怎么也顶得上十个《英雄》或者《无极》的投资吧,那就是几十个亿了。

6,搞了半天,大脚印烟花还是假的,糊弄谁呢?

7,到现在为止,海外那些爱国人士,比如“萨苏”什么的,都对开幕式赞扬有加,我虽然喜欢这个写手,不过还是觉得此事不能苟同。如果要爱国要赞扬,能不能先把税交给中国政府?(而不是什么日本、美国等其它政府)爱国,你要站在这片土地上爱,说空话扯大旗谁不会?

真扯。