www.xpj123123.com990.com怎么样,信得过吗?

后使用快捷导航没有帐号?
只需一步,快速开始
扫一扫,访问微社区
今日: 0|主题: 3658|排名: 5&
Powered by新葡京娱乐城-官方直营 |亚洲顶级线上投注平台|24小时任意提款3分钟到账|永久网址: 备用网址:1、 分享第一条经验:“学历代表过去、能力代表现在、学习力代表未来。”其实这是一个来自国外教育领域的一个研究结果。相信工作过几年、十几年的朋友对这个道理有些体会吧。但我相信这一点也很重要:“重要的道理明白太晚将抱憾终生!”所以放在每一条,让刚刚毕业的朋友们早点看到哈!
2、 一定要确定自己的发展方向,并为此目的制定可行的计划。不要说什么,“我刚毕业,还不知道将来可能做什么?”,“跟着感觉走,先做做看”。因为,这样的观点会通过你的潜意识去暗示你的行为无所事事、碌碌无为。一直做技术,将来成为专家级人物?向管理方向走,成为职业经理人?先熟悉行业和领域,将来自立门户?还是先在行业里面混混,过几年转行做点别的?这很重要,它将决定你近几年、十年内“做什么事情才是在做正确的事情!”。
3、 软件开发团队中,技术不是万能的,但没有技术是万万不能的!在技术型团队中,技术与人品同等重要,当然长相也比较重要哈,尤其在MM比较多的团队中。在软件项目团队中,技术水平是受人重视和尊重的重要砝码。无论你是做管理、系统分析、设计、编码,还是产品管理、测试、文档、实施、维护,多少你都要有技术基础。算我孤陋寡闻,我还真没有亲眼看到过一个外行带领一个软件开发团队成功地完成过软件开发项目,哪怕就一个,也没有看到。倒是曾经看到过一个“高学历的牛人”(非技术型)带一堆人做完过一个项目,项目交付的第二天,项目组成员扔下一句“再也受不了啦!”四分五裂、各奔东西。那个项目的“成功度”大家可想而知了。
4、 详细制定自己软件开发专业知识学习计划,并注意及时修正和调整(软件开发技术变化实在太快)。请牢记:“如果一个软件开发人员在1、2年内都没有更新过自己的知识,那么,其实他已经不再属于这个行业了。”不要告诉自己没有时间。来自时间管理领域的著名的“三八原则”告诫我们:另外的那8小时如何使用将决定你的人生成败!本人自毕业以来,平均每天实际学习时间超过2小时。
5、 书籍是人类进步的阶梯,对软件开发人员尤其如此。书籍是学习知识的最有效途径,不要过多地指望在工作中能遇到“世外高人”,并不厌其烦地教你。对于花钱买书,我个人经验是:千万别买国内那帮人出的书!我买的那些家伙出的书,!00%全部后悔了,无一本例外。更气愤的是,这些书在二手市场的地摊上都很难卖掉。“拥有书籍并不表示拥有知识;拥有知识并不表示拥有技能;拥有技能并不表示拥有文化;拥有文化并不表示拥有智慧。”只有将书本变成的自己智慧,才算是真正拥有了它。
6、 不要仅局限于对某项技术的表面使用上,哪怕你只是偶尔用一、二次。“对任何事物不究就里”是任何行业的工程师所不应该具备的素质。开发Windows应用程序,看看Windows程序的设计、加载、执行原理,分析一下PE文件格式,试试用SDK开发从头开发一个Windows应用程序;用VC++、Delphi、Java、.Net开发应用程序,花时间去研究一下MFC、VCL、J2EE、.Net它们框架设计或者源码;除了会用J2EE、JBoss、Spring、Hibernate等等优秀的开源产品或者框架,抽空看看大师们是如何抽象、分析、设计和实现那些类似问题的通用解决方案的。试着这样做做,你以后的工作将会少遇到一些让你不明就里、一头雾水的问题,因为,很多东西你“知其然且知其所以然”!
7、 在一种语言上编程,但别为其束缚了思想。“代码大全”中说:“深入一门语言编程,不要浮于表面”。深入一门语言开发还远远不足,任何编程语言的存在都有其自身的理由,所以也没有哪门语言是“包治百病”的“灵丹妙药”。编程语言对开发人员解决具体问题的思路和方式的影响与束缚的例子俯拾皆是。我的经验是:用面对对象工具开发某些关键模块时,为什么不可以借鉴C、C51、汇编的模块化封装方式?用传统的桌面开发工具(目前主要有VC++、Delphi)进行系统体统结构设计时,为什么不可以参考来自Java社区的IoC、AOP设计思想,甚至借鉴像Spring、Hibernate、JBoss等等优秀的开源框架?在进行类似于实时通信、数据采集等功能的设计、实现时,为什么不可以引用来自实时系统、嵌入式系统的优秀的体系框架与模式?为什么一切都必须以个人、团队在当然开发语言上的传统或者经验来解决问题???“他山之石、可以攻玉”。
8、 养成总结与反思的习惯,并有意识地提炼日常工作成果,形成自己的个人源码库、解决某类问题的通用系统体系结构、甚至进化为框架。众所周知,对软件开发人员而言,有、无经验的一个显著区别是:无经验者完成任何任务时都从头开始,而有经验者往往通过重组自己的可复用模块、类库来解决问题(其实这个结论不应该被局限在软件开发领域、可以延伸到很多方面)。这并不是说,所有可复用的东西都必须自己实现,别人成熟的通过测试的成果也可以收集、整理、集成到自己的知识库中。但是,最好还是自己实现,这样没有知识产权、版权等问题,关键是自己实现后能真正掌握这个知识点,拥有这个技能。
9、 理论与实践并重,内外双修。工程师的内涵是:以工程师的眼光观察、分析事物和世界。一个合格的软件工程师,是真正理解了软件产品的本质及软件产品研发的思想精髓的人(个人观点、欢迎探讨)。掌握软件开发语言、应用语言工具解决工作中的具体问题、完成目标任务是软件工程师的主要工作,但从软件工程师这个角度来看,这只是外在的东西,并非重要的、本质的工作。学习、掌握软件产品开发理论知识、软件开发方法论,并在实践中理解、应用软件产品的分析、设计、实现思想来解决具体的软件产品研发问题,才是真正的软件工程师的工作。站在成熟理论与可靠方法论的高度思考、分析、解决问题,并在具体实践中验证和修正这些思想与方式,最终形成自己的理论体系和实用方法论。
10、心态有多开放,视野就有多开阔。不要抱着自己的技术和成果,等到它们都已经过时变成垃圾了,才拿出来丢人现眼。请及时发布自己的研究成果:开发的产品、有创意的设计或代码,公布出来让大家交流或者使用,你的成果才有进化和升华的机会。想想自己2000年间开发的那些Windows系统工具,5、6年之后的今天,还是那个样子,今天流行的好多Windows系统工具都比自己的晚,但进化得很好,且有那么多用户在使用。并且,不要保守自己的技术和思想,尽可能地与人交流与分享,或者传授给开发团队的成员。“与人交换苹果之后,每个人还是只有一个苹果;但交换思想之后,每个人都拥有两种思想”,道理大家都懂,但有多少人真正能做到呢?
11、尽量参加开源项目的开发、或者与朋友共同研制一些自己的产品,千万不要因为没有钱赚而不做。网络早已不再只是“虚拟世界”,网上有很多的开源项目、合作开发项目、外包项目,这都是涉猎工作以外的知识的绝好机会,并且能够结识更广的人缘。不要因为工作是做ERP,就不去学习和了解嵌入式、实时、通信、网络等方面的技术,反过来也是一样。如果当他别人拿着合同找你合作,你却这也不会,那也不熟时,你将后悔莫及。
12、书到用时方恨少,不要将自己的知识面仅仅局限于技术方面。诺贝尔经济学奖得主西蒙教授的研究结果表明: “对于一个有一定基础的人来说,他只要真正肯下功夫,在6个月内就可以掌握任何一门学问。”教育心理学界为感谢西蒙教授的研究成果,故命名为西蒙学习法。可见,掌握一门陌生的学问远远没有想想的那么高难、深奥。多方吸取、广泛涉猎。极力夯实自己的影响圈、尽量扩大自己的关注圈。财务、经济、税务、管理等等知识,有空花时间看看,韬光养晦、未雨绸缪。
13、本文的总结与反思:
A:不要去做技术上的高手,除非你的目标如此。虽然本文是关于提高软件开发知识的建议,做技术的高手是我一向都不赞同的。你可以提高自己的专业知识,但能胜任工作即止。
B:提高软件知识和技术只是问题的表面,本质是要提高自己认识问题、分析问题、解决问题的思想高度。软件专业知识的很多方法和原理,可以很容易地延伸、应用到生活的其它方面。
C:在能胜任工作的基础上,立即去涉猎其它领域的专业知识,丰富自己的知识体系、提高自己的综合素质,尤其是那些目标不在技术方面的朋友。
 1、好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,最后你对哪个行业都没有摸透,永远是新手!
  2、可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!
  3、不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。
  很牛吗?人家能上去必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!
  4、多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,思维习惯,爱好,他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!
  5、知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务, 法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!
  6、抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!!
  7、逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果 ,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好--尽管你可能技术不错!
  8、的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,否则,有了机会也抓不住!
  9、要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会...
  10、该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功。
初/中/高级测试工程师测试题
一& 初级测试程师测试题
初级测试工程师职位要求:
岗位职责:1、依据需求文档及设计文档,编写测试用例;2、根据测试计划,搭建测试环境;3、依据测试用例执行手工测试,反馈跟踪产品BUG及用例缺陷;任职要求:1、本科及以上,计算机相关专业;具备1年以上测试工作经验;
2&熟悉windows操作系统,了解linux,可以搭建测试环境;2、掌握测试理论及技术;熟练运用各种黑盒测试用例设计方法;4、熟悉的Sql Server,可以使用基本的sql语句辅助测试;
5、具备互联网或证券类软件测试经验者优先考虑。
1 操作系统
&1.1 windows系统
1 如何在win2003中如何安装Internet信息服务(IIS)?
2 如何在Dos下面用命令将D盘下面test目录文件夹及子目录打印并保存?
3 进程和线程的区别?
1.2 Linux系统
(1) 局域网的网络地址192.168.1.0/24,局域网络连接其它网络的网关地址是192.168.1.1。主机192.168.1.20访问172.16.1.0/24网络时,其路由设置正确的是 。A route add –net 192.168.1.0 gw 192.168.1.1 netmask 255.255.255.0 metric 1B route add –net 172.16.1.0 gw 192.168.1.1 netmask 255.255.255.255 metric 1C route add –net 172.16.1.0 gw 172.16.1.1 netmask 255.255.255.0 metric 1D route add default 192.168.1.0 netmask 172.168.1.1 metric 1
(2) 下列信息是某系统用ps –ef命令列出的正在运行的进程, 进程是运行Internet超级服务器,它负责监听Internet sockets上的连接,并调用合适的服务器来处理接收的信息。A root 1 4.0 0.0 344 204? S 17:09 0:00 initB root 2 0.0 0.1 ? S 17:09 0:00 /sbin/gettyC root 3 0.0 0.2 ? S 17:09 0:00 /usr/sbin/syslogdD root 4 0.0 ? S 17:09 0:10 /usr/sbin/inetd
(3)对名为mayingbao的文件用chmod 551 mayingbao进行了修改,则它的许可权是 。A -rwxr-xr-x B -rwxr--r-- C -r--r--r-- D -r-xr-x—x
(4) 将home/stud1/mayingbao目录做归档压缩,压缩后生成mayingbao.tar.gz文件,并将此文件保存到/home目录下,实现此任务的tar命令格式 。
(1)对以下已知成绩关系如图1所示。执行SQL语句:  SELECT COUNT(DISTINCT学号)  FROM成绩  WHERE分数>60查询结果中包含的元组数目是( )
A 1&& B 2 &C 3&&&& D 4
(2) SQL语言中,删除一个表的命令是( ) A DELETE&&B DROP &&C CLEAR &D REMORE
(3) 请写出查询student_info_table表中姓名为“小马哥”的name字段和email字段。
(1) 写出以下程序输出的结果
#include&stdio.h&
int a,b,c,d;
printf("b,c,d:%d,%d,%d",b,c,d);
(2)do……while和while……do有什么区别?前一个循环一遍再判断,后一个判断以后再循环。
(3) 编写一个程序,用来计算1 到100 间所有整数的和是多少?
说明:编程语言可以使用c/vb/c++/c#/java等
(1)请描述下一个完整的Http通信过程?
(2)cookie和session的区别
(3) 以下关于TCP/IP传输层协议的描述中,错误的是A. TCP/IP传输层定义了TCP和UDP两种协议B. TCP协议是一种面向连接的协议C. UDP协议是一种面向无连接的协议D. UDP协议与TCP协议都能够支持可靠的字节流传输
五 数据结构
(1) 若在文件中查询年龄在20岁以上的帅哥及年龄在18岁以上的美女的所有记录,则查询条件为()
A &(性别=”男”) OR(年龄&20) OR (性别=”女”) OR (年龄&18)
B&(性别=”男”) OR(年龄&20) AND (性别=”女”) OR (年龄&18)
C&(性别=”男”) AND (年龄&20) OR (性别=”女”) AND (年龄&18)
D&(性别=”男”) AND (年龄&20) AND (性别=”女”) AND (年龄&18)
(2) 请写出冒泡排序算法?
说明:编程语言可以使用c/vb/c++/c#/java等
(1)下列关于alpha 测试的描述中正确的是A alpha 测试需要用户代表参加B alpha 测试不需要用户代表参加C alpha 测试是系统测试的一种D alpha 测试是验收测试的一种
(2) 软件质量的定义A 软件的功能性、可靠性、易用性、效率、可维护性、可移植性B 满足规定用户需求的能力C 最大限度达到用户满意D 软件特性的总和,以及满足规定和潜在用户需求的能力
(3) 软件测试的对象包括()A 目标程序和相关文档B 源程序、目标程序、数据及相关文档C 目标程序、操作系统和平台软件D 源程序和目标程序
(4) 软件测试类型按开发阶段划分是()A 需求测试、单元测试、集成测试、验证测试B 单元测试、集成测试、确认测试、系统测试、验收测试C 单元测试、集成测试、验证测试确认测试、验收测试D 调试、单元测试、集成测试、用户测试
(5) 根据下面给出的规格说明,利用等价类划分的方法,给出足够的测试用例。“一个程序读入三个整数。把此三个数值看成是一个三角形的三个边。这个程序要打印出信息,说明这个三角形是三边不等的、是等腰的、还是等边的。”
(6) 设要对一个自动饮料售货机软件进行黑盒测试。该软件的规格说明如下:“有一个处理单价为1元5角钱的盒装饮料的自动售货机软件。若投入1元5角硬币,按下“可乐”、“雪碧”或“红茶”按钮,相应的饮料就送出来。若投入的是2元硬币,在送出饮料的同时退还5角硬币。”(1) 试利用因果图法,建立该软件的因果图;(2) 设计测试该软件的全部测试用例。
(7)对一个长度为100,000条指令的程序进行测试,记录下来的数据如下:&测试开始,ú 发现错误个数为0;&经过160小时的测试, 累计改正100个错误, 此时, MTTF = 0.4小时;ú&又经过160小时的测试,ú 累计改正300个错误, 此时, MTTF = 2小时;(1) 估计程序中固有的错误总数;(2) 为使MTTF达到10小时, 必须测试和调试这个程序多长时间? (3) 给出MTTF与测试时间t之间的函数关系。
(8)请根据以下程序片段,设计最少的测试用例实现条件覆盖If((A&1)AND(B=0))Then X=X/AIf((A=2)OR(X&1))Then X=X+1Printf("X=%d",x)
(9)请画出你认为最合理的&缺陷处理流程图?
(10)c/s和b/s软件,你认为应从哪些方面去测试?
二 &中级测试程师试测试题
中级测试工程师
岗位职责: 1、&根据测试计划,制定产品的测试策略;
2、&评审功能需求及设计文档,编写测试用例;
3、&分析产品测试需求功能点,并准备测试数据,编写自动化测试脚本; 4、&执行测试,反馈问题,追踪Bug的生命周期;任职要求: 1、&本科及以上,计算机相关专业;2年以上测试工作经验,具备独立负责项目的测试工作经验;
2&& 熟悉Windows平台操作系统,可以搭建测试环境,了解Linux基本的命令;3、&掌握测试理论及技术;熟练运用各种黑盒测试用例设计方法;了解白盒测试方法; 4、&掌握一种以上自动化测试工具,具备一定的测试脚本的编写及维护能力,可以在高级测试工程师协调下完成性能测试或部分自动化测试工作; 5、&熟练掌握Sql&Server中企业管理器、查询分析器的使用,常用SQL语句的编写;理解存储过程、用户自定义函数、视图; 6、&具备互联网或证券类软件测试经验者优先考虑。
备注:以下题目应聘者应根据实际情况,建议选择性做答
1 操作系统
1.1&在Win2003下,在安装某个服务基于.net开发的程序如:AlertService.exe时,需要用什么命令才能实现正确安装?
1.2 &在Win2003下,如何从从dotnet1.1切换至dotnet2.0
1.3&&在性能测试过程中,监测系统有内存泄露,在Loadrunner下主要监控的性能指标是什么?
2.1&在SQL Server中,您如何从名为“Student”的表中选取列“mayingbao”的值以“a”开头的所有记录?
2.2 &利用sql语句,执行给student表插入10000条数据,主要数据表字段为(用户名:char(10); 密码 char(10);
3.1 找出下面程序的错误:
Void abc(){  char string[10];  char* str1="";strcpy(string, str1);}Void def(){  char string[10], str1[10];for(I=0; I&10;I++){    str1[i] ='a';}strcpy(string, str1);}Void ghl(char* str1){  char string[10];  if(strlen(str1)&=10){  strcpy(string, str1);}}
3.2 请写出以下程序的运行结果:
int sum(int a){    auto int c=0;    static int b=3;c+=1;b+=2;return(a+b+C);}  void main(){int I;int a=2;for(I=0;I&5;I++){  printf("%d,", sum(a));}}
4.1 什么是质量特性?质量特性有测试有什么关系?
4.2 以下是某公司手机炒股软件中的“东风汽车”的K线走趋图,你认为应从哪些方面去测试?
4.3以下是某公司门户网站中的股票栏目中的行情“搜索“功能,你认为应从哪些方面来测试?
4.4通常软件生命周期包括以下主要部分:项目问题定义、可行性分析、总体描述、系统设计、编码、调试和测试、验收与运行、维护升级到废弃等阶段,请你列举出测试与哪些阶段有联系?相应的阶段测试的主要活动是哪些?
4.5某银行,由于新上线的后台对帐项目突然出现崩溃,系统处于停用状态,最后查明系统可能存在性能瓶颈,你做为此项目主要的测试负责人员,面对这突如其来的事件,你如何处理?
4.6诺机亚手机中嵌入的“移动QQ”应用程序,试分析应从哪些方面去测试?
4.7Web测试中,经常会涉及到安全性测试,哪么什么是“sql注入”?,什么是“跨站脚本注入“?
5.1 运行Web浏览器的计算机与网页所在的计算机建立______连接,采用____协议传输文件;
5.2 系统响应时间和吞吐量是衡量计算机系统性能的重要指标,对于一个持续处理业务的系统而言,其___
&小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒, 小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。
请问:小明一家如何过桥?
本文出自的51Testing软件博客,请保留出处及链接:
  我知道的有关的情况:
  听一个在的朋友说,他们每天写完的代码,在晚上下班之前都要check到一起,执行一遍用例,当然都是自动执行的,那个地方出现了错误会红灯提示,所以这个用例一定是事先写好的。
  听一个在比较大的公司(1000多人)的朋友说,他们公司经常后补用例的。
  我一直在百十人的小公司工作,领导心绪来潮的时候要求写用例,可是多数情况是可写可不写的,而且对质量,形势也没有什么要求。
  对于写用例的认识,我经历了这样一个过程,一开始是很形式化的,质量也很一般,回想一下跟现在的新人写的一样,所以觉得毫无用途,所以后来就不怎么写了。可是面对新项目的时候,问题出现了,无论在测试之前你多么的了解需求,业务,在提交测试的时候,很是会有覆盖不全的情况,我们的大脑毕竟不是电脑,我们在测试一个新系统的时候,不可能在到脑中勾画出每一个小功能,甚至每一个表单的所有分支,所以我开始写用例了,对任何一个小功能都是以流程的方式,每一步有多少个分支都清晰的列出来,我觉得效果非常好,按照这个测试完成之后,晚上睡觉都安稳多了,这是自己给自己的保证。这个用例可以说是一个很详细的用例了,只适合新项目的新版本测试,回归的时候就没有这个必要了,这样不符合性价比。那时候,我们的回归都是凭着大脑测试的,没有感觉到任何问题,只是在牵涉到流程性比较强的项目时才写一些流程用例(包括正常流程和常见异常流程)。可是现在,我在新的公司工作一年多了,问题出现了,项目特别多,差不多有十几二十个,由于测试的人少,每个项目都要测试,所以在回归测试的时候经常会搞不清状况,记不清业务要求等(也许是我老了,记忆力不好了:()而且公司客户是比较强硬的那种,公司领导是认为测试过的东西就不应该有问题的那种,所以搞得自己经常提心吊胆,生怕给客户的东西出现问题。这时候,我发现了回归测试用例的重要性,以前没有写过,有个大概的概念就是写个简单的流程,回归的时候执行一下就行了,在一开始的实施过程中发现了问题,写的过于简单还是让我在回归的时候无从下手,在思考与实践中,我自认为自己找到了一种不错的编写方式:为了保证质量,回归在功能上要覆盖所有的功能按钮,这部分在写用例的时候要每个操作写一个用例(简单说excel的一行),操作结果中记录该操作应该返回的界面,一定要一个操作对应一个结果,这样才具有可操作性。在每条用例的后面设置“通过”和“不通过”的按钮,这样回归的时候就轻松了,过一个勾一个,在测试几乎没有改动的地方时,简直是休息,哈哈。当然也不要忽视业务流程,权限等方面的测试,可以另起文档,以自己比较喜欢的方式编辑就ok了!
这是一篇全面介绍单元测试的经典之作,对理解单元测试和Visual Unit很有帮助,作者老纳,收录时作了少量修改]一 单元测试概述  工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。  其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,老纳把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。  对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。  要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。老纳认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈老纳的看法。  一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以老纳的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。  有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。  什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。  由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。  关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。二 测试代码编写  多数讲述单元测试的文章都是以Java为例,本文以C++为例,后半部分所介绍的单元测试工具也只介绍C++单元测试工具。下面的示例代码的开发环境是VC6.0。产品类:class CMyClass {public:& & int Add(int i, int j);& & CMyClass();& & virtual ~CMyClass();private:& & int mA& && &//年龄& & CString mP //年龄阶段,如"少年","青年"};建立对应的测试类CMyClassTester,为了节约编幅,只列出源文件的代码:void CMyClassTester::CaseBegin(){& & //pObj是CMyClassTester类的成员变量,是被测试类的对象的指针,& & //为求简单,所有的测试类都可以用pObj命名被测试对象的指针。& & pObj = new CMyClass();}void CMyClassTester::CaseEnd(){& & delete pO}测试类的函数CaseBegin()和CaseEnd()建立和销毁被测试对象,每个测试用例的开头都要调用CaseBegin(),结尾都要调用CaseEnd()。接下来,我们建立示例的产品函数:int CMyClass::Add(int i, int j){& & return i+j;}和对应的测试函数:void CMyClassTester::Add_int_int(){}把参数表作为函数名的一部分,这样当出现重载的被测试函数时,测试函数不会产生命名冲突。下面添加测试用例:void CMyClassTester::Add_int_int(){& & //第一个测试用例& & CaseBegin();{& && && && &&&//1& & int i = 0;& && && && && & //2& & int j = 0;& && && && && & //3& & int ret = pObj-&Add(i, j); //4& & ASSERT(ret == 0);& && && & //5& & }CaseEnd();& && && && && & //6}第1和第6行建立和销毁被测试对象,所加的{}是为了让每个测试用例的代码有一个独立的域,以便多个测试用例使用相同的变量名。第2和第3行是定义输入数据,第4行是调用被测试函数,这些容易理解,不作进一步解释。第5行是预期输出,它的特点是当实际输出与预期输出不同时自动报错,ASSERT是VC的断言宏,也可以使用其他类似功能的宏,使用测试工具进行单元测试时,可以使用该工具定义的断言宏。  示例中的格式显得很不简洁,2、3、4、5行可以合写为一行:ASSERT(pObj-&Add(0, 0) == 0);但这种不简洁的格式却是老纳极力推荐的,因为它一目了然,易于建立多个测试用例,并且具有很好的适应性,同时,也是极佳的代码文档,总之,老纳建议:输入数据和预期输出要自成一块。  建立了第一个测试用例后,应编译并运行测试,以排除语法错误,然后,使用拷贝/修改的办法建立其他测试用例。由于各个测试用例之间的差别往往很小,通常只需修改一两个数据,拷贝/修改是建立多个测试用例的最快捷办法。三 测试用例  下面说说测试用例、输入数据及预期输出。输入数据是测试用例的核心,老纳对输入数据的定义是:被测试函数所读取的外部数据及这些数据的初始值。外部数据是对于被测试函数来说的,实际上就是除了局部变量以外的其他数据,老纳把这些数据分为几类:参数、成员变量、全局变量、IO媒体。IO媒体是指文件、数据库或其他储存或传输数据的媒体,例如,被测试函数要从文件或数据库读取数据,那么,文件或数据库中的原始数据也属于输入数据。一个函数无论多复杂,都无非是对这几类数据的读取、计算和写入。预期输出是指:返回值及被测试函数所写入的外部数据的结果值。返回值就不用说了,被测试函数进行了写操作的参数(输出参数)、成员变量、全局变量、IO媒体,它们的预期的结果值都是预期输出。一个测试用例,就是设定输入数据,运行被测试函数,然后判断实际输出是否符合预期。下面举一个与成员变量有关的例子:产品函数:void CMyClass::Grow(int years){& & mAge +=& & if(mAge & 10)& && &&&mPhase = "儿童";& & else if(mAge &20)& && &&&mPhase = "少年";& & else if(mAge &45)& && &&&mPhase = "青年";& & else if(mAge &60)& && &&&mPhase = "中年";& & else& && &&&mPhase = "老年";}测试函数中的一个测试用例:& & CaseBegin();{& & int years = 1;& & pObj-&mAge = 8;& & pObj-&Grow(years);& & ASSERT( pObj-&mAge == 9 );& & ASSERT( pObj-&mPhase == "儿童" );& & }CaseEnd();在输入数据中对被测试类的成员变量mAge进行赋值,在预期输出中断言成员变量的值。现在可以看到老纳所推荐的格式的好处了吧,这种格式可以适应很复杂的测试。在输入数据部分还可以调用其他成员函数,例如:执行被测试函数前可能需要读取文件中的数据保存到成员变量,或需要连接数据库,老纳把这些操作称为初始化操作。例如,上例中 ASSERT( ...)之前可以加pObj-&OpenFile();。为了访问私有成员,可以将测试类定义为产品类的友元类。例如,定义一个宏:#define UNIT_TEST(cls) friend class cls##T然后在产品类声明中加一行代码:UNIT_TEST(ClassName)。  下面谈谈测试用例设计。前面已经说了,测试用例的核心是输入数据。预期输出是依据输入数据和程序功能来确定的,也就是说,对于某一程序,输入数据确定了,预期输出也就可以确定了,至于生成/销毁被测试对象和运行测试的语句,是所有测试用例都大同小异的,因此,我们讨论测试用例时,只讨论输入数据。  前面说过,输入数据包括四类:参数、成员变量、全局变量、IO媒体,这四类数据中,只要所测试的程序需要执行读操作的,就要设定其初始值,其中,前两类比较常用,后两类较少用。显然,把输入数据的所有可能取值都进行测试,是不可能也是无意义的,我们应该用一定的规则选择有代表性的数据作为输入数据,主要有三种:正常输入,边界输入,非法输入,每种输入还可以分类,也就是平常说的等价类法,每类取一个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。下面举例说明:   正常输入  例如字符串的Trim函数,功能是将字符串前后的空格去除,那么正常的输入可以有四类:前面有空格;后面有空格;前后均有空格;前后均无空格。  边界输入  上例中空字符串可以看作是边界输入。  再如一个表示年龄的参数,它的有效范围是0-100,那么边界输入有两个:0和100。  非法输入  非法输入是正常取值范围以外的数据,或使代码不能完成正常功能的输入,如上例中表示年龄的参数,小于0或大于100都是非法输入,再如一个进行文件操作的函数,非法输入有这么几类:文件不存在;目录不存在;文件正在被其他程序打开;权限错误。  如果函数使用了外部数据,则正常输入是肯定会有的,而边界输入和非法输入不是所有函数都有。一般情况下,即使没有设计文档,考虑以上三种输入也可以找出函数的基本功能点。实际上,单元测试与代码编写是“一体两面”的关系,编码时对上述三种输入都是必须考虑的,否则代码的健壮性就会成问题。四 白盒覆盖  上面所说的测试数据都是针对程序的功能来设计的,就是所谓的黑盒测试。单元测试还需要从另一个角度来设计测试数据,即针对程序的逻辑结构来设计测试用例,就是所谓的白盒测试。在老纳看来,如果黑盒测试是足够充分的,那么白盒测试就没有必要,可惜“足够充分”只是一种理想状态,例如:真的是所有功能点都测试了吗?程序的功能点是人为的定义,常常是不全面的;各个输入数据之间,有些组合可能会产生问题,怎样保证这些组合都经过了测试?难于衡量测试的完整性是黑盒测试的主要缺陷,而白盒测试恰恰具有易于衡量测试完整性的优点,两者之间具有极好的互补性,例如:完成功能测试后统计语句覆盖率,如果语句覆盖未完成,很可能是未覆盖的语句所对应的功能点未测试。  白盒测试针对程序的逻辑结构设计测试用例,用逻辑覆盖率来衡量测试的完整性。逻辑单位主要有:语句、分支、条件、条件值、条件值组合,路径。语句覆盖就是覆盖所有的语句,其他类推。另外还有一种判定条件覆盖,其实是分支覆盖与条件覆盖的组合,在此不作讨论。跟条件有关的覆盖就有三种,解释一下:条件覆盖是指覆盖所有的条件表达式,即所有的条件表达式都至少计算一次,不考虑计算结果;条件值覆盖是指覆盖条件的所有可能取值,即每个条件的取真值和取假值都要至少计算一次;条件值组合覆盖是指覆盖所有条件取值的所有可能组合。老纳做过一些粗浅的研究,发现与条件直接有关的错误主要是逻辑操作符错误,例如:||写成&&,漏了写!什么的,采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,条件值覆盖与条件值组合覆盖往往需要大量的测试用例,因此,在老纳看来,条件值覆盖和条件值组合覆盖的效费比偏低。老纳认为效费比较高且完整性也足够的测试要求是这样的:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖。做过单元测试的朋友恐怕会对老纳提出的测试要求给予一个字的评价:晕!或者两个字的评价:狂晕!因为这似乎是不可能的要求,要达到这种测试完整性,其测试成本是不可想象的,不过,出家人不打逛语,老纳之所以提出这种测试要求,是因为利用一些工具,可以在较低的成本下达到这种测试要求,后面将会作进一步介绍。  关于白盒测试用例的设计,程序测试领域的书籍一般都有讲述,普通方法是画出程序的逻辑结构图如程序流程图或控制流图,根据逻辑结构图设计测试用例,这些是纯粹的白盒测试,不是老纳想推荐的方式。老纳所推荐的方法是:先完成黑盒测试,然后统计白盒覆盖率,针对未覆盖的逻辑单位设计测试用例覆盖它,例如,先检查是否有语句未覆盖,有的话设计测试用例覆盖它,然后用同样方法完成条件覆盖、分支覆盖和路径覆盖,这样的话,既检验了黑盒测试的完整性,又避免了重复的工作,用较少的时间成本达到非常高的测试完整性。不过,这些工作可不是手工能完成的,必须借助于工具,后面会介绍可以完成这些工作的测试工具。五 单元测试工具  现在开始介绍单元测试工具,老纳只介绍三种,都是用于C++语言的。  首先是CppUnit,这是C++单元测试工具的鼻祖,免费的开源的单元测试框架。由于已有一众高人写了不少关于CppUnit的很好的文章,老纳就不现丑了,想了解CppUnit的朋友,建议读一下Cpluser 所作的《CppUnit测试框架入门》,网址是:。该文也提供了CppUnit的下载地址。  然后介绍C++Test,这是Parasoft公司的产品。[C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%]。[]内的文字引自,这是华唐公司的网页。老纳想写些介绍C++Test的文字,但发现无法超越华唐公司的网页上的介绍,所以也就省点事了,想了解C++Test的朋友,建议访问该公司的网站。华唐公司代理C++Test,想要购买或索取报价、试用版都可以找他们。老纳帮华唐公司做广告,不知道会不会得点什么好处?  最后介绍Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术,不过老纳只关心是不是有用和好用。[自动生成测试代码 快速建立功能测试用例 程序行为一目了然 极高的测试完整性 高效完成白盒覆盖 快速排错 高效调试 详尽的测试报告]。[]内的文字是VU开发商的网页上摘录的,网址是:。前面所述测试要求:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖,用VU可以轻松实现,还有一点值得一提:使用VU还能提高编码的效率,总体来说,在完成单元测试的同时,编码调试的时间还能大幅度缩短。算了,不想再讲了,老纳显摆理论、介绍经验还是有兴趣的,因为可以满足老纳好为人师的虚荣心,但介绍工具就觉得索然无味了,毕竟工具好不好用,合不合用,要试过才知道,还是自己去开发商的网站看吧,可以下载演示版,还有演示课件。这是一篇全面介绍单元测试的经典之作,对理解单元测试和Visual Unit很有帮助,作者老纳,收录时作了少量修改]一 单元测试概述  工厂在组装一台电视机之前,会对每个元件都进行测试,这,就是单元测试。  其实我们每天都在做单元测试。你写了一个函数,除了极简单的外,总是要执行一下,看看功能是否正常,有时还要想办法输出些数据,如弹出信息窗口什么的,这,也是单元测试,老纳把这种单元测试称为临时单元测试。只进行了临时单元测试的软件,针对代码的测试很不完整,代码覆盖率要超过70%都很困难,未覆盖的代码可能遗留大量的细小的错误,这些错误还会互相影响,当BUG暴露出来的时候难于调试,大幅度提高后期测试和维护成本,也降低了开发商的竞争力。可以说,进行充分的单元测试,是提高软件质量,降低开发成本的必由之路。  对于程序员来说,如果养成了对自己写的代码进行单元测试的习惯,不但可以写出高质量的代码,而且还能提高编程水平。  要进行充分的单元测试,应专门编写测试代码,并与产品代码隔离。老纳认为,比较简单的办法是为产品工程建立对应的测试工程,为每个类建立对应的测试类,为每个函数(很简单的除外)建立测试函数。首先就几个概念谈谈老纳的看法。  一般认为,在结构化程序时代,单元测试所说的单元是指函数,在当今的面向对象时代,单元测试所说的单元是指类。以老纳的实践来看,以类作为测试单位,复杂度高,可操作性较差,因此仍然主张以函数作为单元测试的测试单位,但可以用一个测试类来组织某个类的所有测试函数。单元测试不应过分强调面向对象,因为局部代码依然是结构化的。单元测试的工作量较大,简单实用高效才是硬道理。  有一种看法是,只测试类的接口(公有函数),不测试其他函数,从面向对象角度来看,确实有其道理,但是,测试的目的是找错并最终排错,因此,只要是包含错误的可能性较大的函数都要测试,跟函数是否私有没有关系。对于C++来说,可以用一种简单的方法区隔需测试的函数:简单的函数如数据读写函数的实现在头文件中编写(inline函数),所有在源文件编写实现的函数都要进行测试(构造函数和析构函数除外)。  什么时候测试?单元测试越早越好,早到什么程度?XP开发理论讲究TDD,即测试驱动开发,先编写测试代码,再进行开发。在实际的工作中,可以不必过分强调先什么后什么,重要的是高效和感觉舒适。从老纳的经验来看,先编写产品函数的框架,然后编写测试函数,针对产品函数的功能编写测试用例,然后编写产品函数的代码,每写一个功能点都运行测试,随时补充测试用例。所谓先编写产品函数的框架,是指先编写函数空的实现,有返回值的随便返回一个值,编译通过后再编写测试代码,这时,函数名、参数表、返回类型都应该确定下来了,所编写的测试代码以后需修改的可能性比较小。  由谁测试?单元测试与其他测试不同,单元测试可看作是编码工作的一部分,应该由程序员完成,也就是说,经过了单元测试的代码才是已完成的代码,提交产品代码时也要同时提交测试代码。测试部门可以作一定程度的审核。  关于桩代码,老纳认为,单元测试应避免编写桩代码。桩代码就是用来代替某些代码的代码,例如,产品函数或测试函数调用了一个未编写的函数,可以编写桩函数来代替该被调用的函数,桩代码也用于实现测试隔离。采用由底向上的方式进行开发,底层的代码先开发并先测试,可以避免编写桩代码,这样做的好处有:减少了工作量;测试上层函数时,也是对下层函数的间接测试;当下层函数修改时,通过回归测试可以确认修改是否导致上层函数产生错误。二 测试代码编写  多数讲述单元测试的文章都是以Java为例,本文以C++为例,后半部分所介绍的单元测试工具也只介绍C++单元测试工具。下面的示例代码的开发环境是VC6.0。产品类:class CMyClass {public:& & int Add(int i, int j);& & CMyClass();& & virtual ~CMyClass();private:& & int mA& && &//年龄& & CString mP //年龄阶段,如"少年","青年"};建立对应的测试类CMyClassTester,为了节约编幅,只列出源文件的代码:void CMyClassTester::CaseBegin(){& & //pObj是CMyClassTester类的成员变量,是被测试类的对象的指针,& & //为求简单,所有的测试类都可以用pObj命名被测试对象的指针。& & pObj = new CMyClass();}void CMyClassTester::CaseEnd(){& & delete pO}测试类的函数CaseBegin()和CaseEnd()建立和销毁被测试对象,每个测试用例的开头都要调用CaseBegin(),结尾都要调用CaseEnd()。接下来,我们建立示例的产品函数:int CMyClass::Add(int i, int j){& & return i+j;}和对应的测试函数:void CMyClassTester::Add_int_int(){}把参数表作为函数名的一部分,这样当出现重载的被测试函数时,测试函数不会产生命名冲突。下面添加测试用例:void CMyClassTester::Add_int_int(){& & //第一个测试用例& & CaseBegin();{& && && && &&&//1& & int i = 0;& && && && && & //2& & int j = 0;& && && && && & //3& & int ret = pObj-&Add(i, j); //4& & ASSERT(ret == 0);& && && & //5& & }CaseEnd();& && && && && & //6}第1和第6行建立和销毁被测试对象,所加的{}是为了让每个测试用例的代码有一个独立的域,以便多个测试用例使用相同的变量名。第2和第3行是定义输入数据,第4行是调用被测试函数,这些容易理解,不作进一步解释。第5行是预期输出,它的特点是当实际输出与预期输出不同时自动报错,ASSERT是VC的断言宏,也可以使用其他类似功能的宏,使用测试工具进行单元测试时,可以使用该工具定义的断言宏。  示例中的格式显得很不简洁,2、3、4、5行可以合写为一行:ASSERT(pObj-&Add(0, 0) == 0);但这种不简洁的格式却是老纳极力推荐的,因为它一目了然,易于建立多个测试用例,并且具有很好的适应性,同时,也是极佳的代码文档,总之,老纳建议:输入数据和预期输出要自成一块。  建立了第一个测试用例后,应编译并运行测试,以排除语法错误,然后,使用拷贝/修改的办法建立其他测试用例。由于各个测试用例之间的差别往往很小,通常只需修改一两个数据,拷贝/修改是建立多个测试用例的最快捷办法。三 测试用例  下面说说测试用例、输入数据及预期输出。输入数据是测试用例的核心,老纳对输入数据的定义是:被测试函数所读取的外部数据及这些数据的初始值。外部数据是对于被测试函数来说的,实际上就是除了局部变量以外的其他数据,老纳把这些数据分为几类:参数、成员变量、全局变量、IO媒体。IO媒体是指文件、数据库或其他储存或传输数据的媒体,例如,被测试函数要从文件或数据库读取数据,那么,文件或数据库中的原始数据也属于输入数据。一个函数无论多复杂,都无非是对这几类数据的读取、计算和写入。预期输出是指:返回值及被测试函数所写入的外部数据的结果值。返回值就不用说了,被测试函数进行了写操作的参数(输出参数)、成员变量、全局变量、IO媒体,它们的预期的结果值都是预期输出。一个测试用例,就是设定输入数据,运行被测试函数,然后判断实际输出是否符合预期。下面举一个与成员变量有关的例子:产品函数:void CMyClass::Grow(int years){& & mAge +=& & if(mAge & 10)& && &&&mPhase = "儿童";& & else if(mAge &20)& && &&&mPhase = "少年";& & else if(mAge &45)& && &&&mPhase = "青年";& & else if(mAge &60)& && &&&mPhase = "中年";& & else& && &&&mPhase = "老年";}测试函数中的一个测试用例:& & CaseBegin();{& & int years = 1;& & pObj-&mAge = 8;& & pObj-&Grow(years);& & ASSERT( pObj-&mAge == 9 );& & ASSERT( pObj-&mPhase == "儿童" );& & }CaseEnd();在输入数据中对被测试类的成员变量mAge进行赋值,在预期输出中断言成员变量的值。现在可以看到老纳所推荐的格式的好处了吧,这种格式可以适应很复杂的测试。在输入数据部分还可以调用其他成员函数,例如:执行被测试函数前可能需要读取文件中的数据保存到成员变量,或需要连接数据库,老纳把这些操作称为初始化操作。例如,上例中 ASSERT( ...)之前可以加pObj-&OpenFile();。为了访问私有成员,可以将测试类定义为产品类的友元类。例如,定义一个宏:#define UNIT_TEST(cls) friend class cls##T然后在产品类声明中加一行代码:UNIT_TEST(ClassName)。  下面谈谈测试用例设计。前面已经说了,测试用例的核心是输入数据。预期输出是依据输入数据和程序功能来确定的,也就是说,对于某一程序,输入数据确定了,预期输出也就可以确定了,至于生成/销毁被测试对象和运行测试的语句,是所有测试用例都大同小异的,因此,我们讨论测试用例时,只讨论输入数据。  前面说过,输入数据包括四类:参数、成员变量、全局变量、IO媒体,这四类数据中,只要所测试的程序需要执行读操作的,就要设定其初始值,其中,前两类比较常用,后两类较少用。显然,把输入数据的所有可能取值都进行测试,是不可能也是无意义的,我们应该用一定的规则选择有代表性的数据作为输入数据,主要有三种:正常输入,边界输入,非法输入,每种输入还可以分类,也就是平常说的等价类法,每类取一个数据作为输入数据,如果测试通过,可以肯定同类的其他输入也是可以通过的。下面举例说明:   正常输入  例如字符串的Trim函数,功能是将字符串前后的空格去除,那么正常的输入可以有四类:前面有空格;后面有空格;前后均有空格;前后均无空格。  边界输入  上例中空字符串可以看作是边界输入。  再如一个表示年龄的参数,它的有效范围是0-100,那么边界输入有两个:0和100。  非法输入  非法输入是正常取值范围以外的数据,或使代码不能完成正常功能的输入,如上例中表示年龄的参数,小于0或大于100都是非法输入,再如一个进行文件操作的函数,非法输入有这么几类:文件不存在;目录不存在;文件正在被其他程序打开;权限错误。  如果函数使用了外部数据,则正常输入是肯定会有的,而边界输入和非法输入不是所有函数都有。一般情况下,即使没有设计文档,考虑以上三种输入也可以找出函数的基本功能点。实际上,单元测试与代码编写是“一体两面”的关系,编码时对上述三种输入都是必须考虑的,否则代码的健壮性就会成问题。四 白盒覆盖  上面所说的测试数据都是针对程序的功能来设计的,就是所谓的黑盒测试。单元测试还需要从另一个角度来设计测试数据,即针对程序的逻辑结构来设计测试用例,就是所谓的白盒测试。在老纳看来,如果黑盒测试是足够充分的,那么白盒测试就没有必要,可惜“足够充分”只是一种理想状态,例如:真的是所有功能点都测试了吗?程序的功能点是人为的定义,常常是不全面的;各个输入数据之间,有些组合可能会产生问题,怎样保证这些组合都经过了测试?难于衡量测试的完整性是黑盒测试的主要缺陷,而白盒测试恰恰具有易于衡量测试完整性的优点,两者之间具有极好的互补性,例如:完成功能测试后统计语句覆盖率,如果语句覆盖未完成,很可能是未覆盖的语句所对应的功能点未测试。  白盒测试针对程序的逻辑结构设计测试用例,用逻辑覆盖率来衡量测试的完整性。逻辑单位主要有:语句、分支、条件、条件值、条件值组合,路径。语句覆盖就是覆盖所有的语句,其他类推。另外还有一种判定条件覆盖,其实是分支覆盖与条件覆盖的组合,在此不作讨论。跟条件有关的覆盖就有三种,解释一下:条件覆盖是指覆盖所有的条件表达式,即所有的条件表达式都至少计算一次,不考虑计算结果;条件值覆盖是指覆盖条件的所有可能取值,即每个条件的取真值和取假值都要至少计算一次;条件值组合覆盖是指覆盖所有条件取值的所有可能组合。老纳做过一些粗浅的研究,发现与条件直接有关的错误主要是逻辑操作符错误,例如:||写成&&,漏了写!什么的,采用分支覆盖与条件覆盖的组合,基本上可以发现这些错误,另一方面,条件值覆盖与条件值组合覆盖往往需要大量的测试用例,因此,在老纳看来,条件值覆盖和条件值组合覆盖的效费比偏低。老纳认为效费比较高且完整性也足够的测试要求是这样的:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖。做过单元测试的朋友恐怕会对老纳提出的测试要求给予一个字的评价:晕!或者两个字的评价:狂晕!因为这似乎是不可能的要求,要达到这种测试完整性,其测试成本是不可想象的,不过,出家人不打逛语,老纳之所以提出这种测试要求,是因为利用一些工具,可以在较低的成本下达到这种测试要求,后面将会作进一步介绍。  关于白盒测试用例的设计,程序测试领域的书籍一般都有讲述,普通方法是画出程序的逻辑结构图如程序流程图或控制流图,根据逻辑结构图设计测试用例,这些是纯粹的白盒测试,不是老纳想推荐的方式。老纳所推荐的方法是:先完成黑盒测试,然后统计白盒覆盖率,针对未覆盖的逻辑单位设计测试用例覆盖它,例如,先检查是否有语句未覆盖,有的话设计测试用例覆盖它,然后用同样方法完成条件覆盖、分支覆盖和路径覆盖,这样的话,既检验了黑盒测试的完整性,又避免了重复的工作,用较少的时间成本达到非常高的测试完整性。不过,这些工作可不是手工能完成的,必须借助于工具,后面会介绍可以完成这些工作的测试工具。五 单元测试工具  现在开始介绍单元测试工具,老纳只介绍三种,都是用于C++语言的。  首先是CppUnit,这是C++单元测试工具的鼻祖,免费的开源的单元测试框架。由于已有一众高人写了不少关于CppUnit的很好的文章,老纳就不现丑了,想了解CppUnit的朋友,建议读一下Cpluser 所作的《CppUnit测试框架入门》,网址是:。该文也提供了CppUnit的下载地址。  然后介绍C++Test,这是Parasoft公司的产品。[C++Test是一个功能强大的自动化C/C++单元级测试工具,可以自动测试任何C/C++函数、类,自动生成测试用例、测试驱动函数或桩函数,在自动化的环境下极其容易快速的将单元级的测试覆盖率达到100%]。[]内的文字引自,这是华唐公司的网页。老纳想写些介绍C++Test的文字,但发现无法超越华唐公司的网页上的介绍,所以也就省点事了,想了解C++Test的朋友,建议访问该公司的网站。华唐公司代理C++Test,想要购买或索取报价、试用版都可以找他们。老纳帮华唐公司做广告,不知道会不会得点什么好处?  最后介绍Visual Unit,简称VU,这是国产的单元测试工具,据说申请了多项专利,拥有一批创新的技术,不过老纳只关心是不是有用和好用。[自动生成测试代码 快速建立功能测试用例 程序行为一目了然 极高的测试完整性 高效完成白盒覆盖 快速排错 高效调试 详尽的测试报告]。[]内的文字是VU开发商的网页上摘录的,网址是:。前面所述测试要求:完成功能测试,完成语句覆盖、条件覆盖、分支覆盖、路径覆盖,用VU可以轻松实现,还有一点值得一提:使用VU还能提高编码的效率,总体来说,在完成单元测试的同时,编码调试的时间还能大幅度缩短。算了,不想再讲了,老纳显摆理论、介绍经验还是有兴趣的,因为可以满足老纳好为人师的虚荣心,但介绍工具就觉得索然无味了,毕竟工具好不好用,合不合用,要试过才知道,还是自己去开发商的网站看吧,可以下载演示版,还有演示课件。
+++软件测试之中文网络资源总汇V2.0+++(更新日期:日)51Testing软件测试网&&测试时代&&CSDN——软件测试频道&&testing.csdn.net希赛网——软件测试频道&&中国软件测试联盟&&一起测试网&&北大测试&&中国软件测试基地 中国软件评测中心&&中国软件质量网&&更新说明:1.去除了不可用的链接和更新较慢的网站2.添加了几个网站的链接下列网站中,部分已经不可访问,但作为V1.0的内容仍保留了下来软件测试之中文网络资源总汇(顺序是我随意排的,不分先后)测试时代论坛&&中国软件测试社区 海松宝的小屋&&Alan工作室&&软件工程专家网&&51testing软件测试网(慧谷-博为峰软件测试工作室)&&中国软件测试在线&&杨柳清风论坛&&天极网的软件测试板块&&测试工程师&&自由龙(好像是珠海的)& &

我要回帖

更多关于 www.xpj6969.com 的文章

 

随机推荐