在代码签入之前运行测试

很久没有写文章,看着每天仅有的可怜的访问量,实在觉得对不起读者,决定再写点什么吧。

测试工程师应该做什么?如何体现测试工程师的价值?类似的问题如果放到一些测试会议或者沙龙上讨论,估计一定很热闹。每个人心中都有自己的认识和答案。我个人理解的较为简单,假如整个团队没有测试,会达得到什么样的一种成就?那假如把测试加进去这个团队,能否帮助大伙提高成就?如果测试是在做正功,那么就是有价值,至于价值多少不容易衡量,如果测试在做负功,那还是自求多福吧。

软件天生就有缺陷(Defect, Bug),缺陷从哪来?缺陷从不平白无故地出现,它总是伴随着功能(Feature)而来,谁创造了功能?随便啦,但是最后通常来是开发工程师动手的,所以大部分时间开发都会负责修bug。一般的流程都是:1. 写了一些功能; 2. 测试;3. 发现一些bug;4. 修bug。如果我们可以加速这个反馈的时间,那么也算是做了正功了。

在网上找到一张很好的图: http://www.jetbrains.com/teamcity/features/delayed_commit.html 很好的解释了怎么样在真正提交代码之前运行测试。至于如何做,基本上每个代码管理工具都有类似的支持,例如Git的Hook: http://git-scm.com/book/en/Customizing-Git-Git-Hooks, 又例如一个号称更加好的Hook:https://github.com/jish/pre-commit,SVN也行:http://svnbook.red-bean.com/en/1.7/svn.ref.reposhooks.pre-commit.html

我只分享一下我自己在使用上的一些经验:

  • 如果你的测试是Flaky的,不要放在pre-commit里面去。一切看起来很没好,但是如果当开发经常在写完一段代码正准备提交的时候,被一个fail的测试挡住了,然后花了半天时间发现不是他的代码有问题而是测试有问题,结果谁都不太爽
  • 不要把大量的end to end测试放在pre-commit里面跑,想一下让你跑10分钟测试才能提交代码,你能不抓狂吗?
  • 要让开发写测试,而不是测试工程师写测试。这样做的好处是开发自己了解测试代码,可以自己修改测试,更新测试,而不需要等测试来做修复。另一方面,产品质量真的不是测试工程师能保证的,大家测才是真的测
  • 不要在刚开始的时候就添加过多的测试,少量的测试总是比较容易跑过并且让大家接受
  • pre-commit测试不是万能,千万不要生搬硬套

Linq to Object在测试中的应用

.NET Framework 3.5中引入了一个新特性LINQ(集成语言查询),据说.NET Framework 3.5中很多特性都是为LINQ而服务的,例如Lambda表达式的支持,匿名类型,等等……这篇文章会讲述一个把Linq to Object应用于测试的例子。

前一阵子需要测试一个搜索在线会员的功能,如果一个用户是在线的,那么他所能够被搜索到的信息都会作为一条记录,保存在一个表中,主要的字段有5个,也就是根据这5个字段的信息可以查询出用户想要的在线会员。一个简单的方案就是写一个比较复杂的存储过程,然后根据5个输入来查询出不同的结果,不过DBA说在SQL SERVER中进行逻辑运算的性能不是很好,所以开发人员写了12条存储过程,分别对应不同的组合,那么对于我做集成测试来说,我起码要有12个测试方法对应这12条存储过程。同时我还要设计一定数量的测试数据,供我查询测试,而比较要命的是,这些测试数据随着我对这个功能的理解的深入,在不断地增加,结果就是如果我写第一个测试的时候,我准备的数据是30条,OK,测试通过;等我写到第五个测试的时候,测试数据可能有40条了,当我用这40条测试数据重新指向第一个测试的时候,FAILED!!!这让人非常郁闷。所以我想到了能不能用round trip的方法来进行测试。做一个比喻,假如说我想证明WIN7的计算器程序是正确的,那么可以把相同的计算在WIN XP的计算器中跑一遍,如果两者结果一样,那么我可以认为WIN7的计算器程序也是正确的(如果XP的计算器有错怎么办?先别较真,有风险,但很小)。

我的做法就是,准备一些数据,首先用SUT进行查询,然后用LINQ进行查询,如果两者查询结果一致,那么可以认为程序是正确的,否则就是两者之一存在问题。

首先准备一些测试数据,保存为XML文件,第一方便对测试数据进行CRUD,第二可以用XmlSerializer把这些数据转换为对象,方便用LINQ查询。
Continue reading “Linq to Object在测试中的应用”

单元测试中的异常处理

最近项目不是十分多,所以大部分的学习来自于书本还有同行的博客,淘宝的QA Team博客就是一个很好博客,里面N多淘宝的工程师写,而且更新的非常频繁,质量也很好。翠翠同学以后就要加入淘宝了,以后就能看到他写的博客了。

早上来看到一篇文章,大概讲的是在单元测试中容易用到了Try…Catch语句而容易出现的一个错误,这里想说一下我对单元测试中异常处理的。记得一个牛人曾经说过(实在想不起来谁也搜不到),大概的意思就是“处理一个问题的最好的办法就是不去处理它”。我不知道当时他讲这句话的具体场景是什么,不过我觉得这句话用在单元测试的异常处理中还是比较合适的。

首先来看看两条关于异常处理的原则

  • 如果无法处理某个异常,那么就不要捕获它
  • 如果捕获到一个异常,那么不要胡乱处理它

单元测试的代码和开发的生产代码,虽然同是程序代码,但是他们存在的意义是不一样的。前者是验证程序的正确性,属于为程序服务的;后者是实现某种功能,属于为客户服务的。然后在看上面的两条异常处理的原则。
Continue reading “单元测试中的异常处理”

自动化单元测试要点

用单元测试的框架MSTEST,做单元测试,集成测试快1年了,总结一下工作中学到都东西。

单元测试,集成测试有什么用?

1. 改进产品质量

软件测试,很多时候围绕着两个问题:

Verification和Validation,常说的双V。前面的Verification就是Is the software built correctly?。后面的Validation就是Have we built the right software?

单元测试,更多的是Verification。所以有时候经过我单元测试和集成测试以后的功能模块,在交给其他同事做功能测试的时候,依然会有一些BUG,这时候开发可能会埋怨我测试得不够完全,诸如此类。但是其实很多时候,我的关注点是单个方法的功能、行为,没有站到更高的位置来测试这个模块。对于这样的问题,开发和测试应该互相体谅,我本人也会提高自身的水平。希望在单元测试和集成测试中也加入更多关于Validation的思考。
Continue reading “自动化单元测试要点”