进化的测试

关注软件测试,白盒测试,自动化测试,性能测试

Entries for 三月, 2009

单元测试中的异常处理

最近项目不是十分多,所以大部分的学习来自于书本还有同行的博客,淘宝的QA Team博客就是一个很好博客,里面N多淘宝的工程师写,而且更新的非常频繁,质量也很好。翠翠同学以后就要加入淘宝了,以后就能看到他写的博客了。 早上来看到一篇文章,大概讲的是在单元测试中容易用到了Try…Catch语句而容易出现的一个错误,这里想说一下我对单元测试中异常处理的。记得一个牛人曾经说过(实在想不起来谁也搜不到),大概的意思就是“处理一个问题的最好的办法就是不去处理它”。我不知道当时他讲这句话的具体场景是什么,不过我觉得这句话用在单元测试的异常处理中还是比较合适的。 首先来看看两条关于异常处理的原则 如果无法处理某个异常,那么就不要捕获它 如果捕获到一个异常,那么不要胡乱处理它 单元测试的代码和开发的生产代码,虽然同是程序代码,但是他们存在的意义是不一样的。前者是验证程序的正确性,属于为程序服务的;后者是实现某种功能,属于为客户服务的。然后在看上面的两条异常处理的原则。

测试工程师可以修复BUG吗?

昨天Check in了几行代码,部署到了生产环境,一切正常,这个是我第一次把代码提交到生产环境。今天早上看到一篇文章“Who fixes the bugs?”。这篇文章是讲述了一个测试工程师是否应该去深入到代码,然后自己把发现的BUG修复,这样的一个事情。很有趣,我刚做完这样的事情,就看到一篇文章讲述同样的问题。 读完那篇文章以后会发现,软件测试真的是一件跟上下文(Context)联系的特别紧密的事情。所以在做某一件事,或者讨论某一件事情的时候,最好先把上下文先弄清楚,然后再下判断。下面阐述一下文章的观点。 作为一个团队里面的成员,每个人都有义务和责任去提高产品的质量。 测试工程师来修复BUG这样的行为虽然不会京城在传统的软件行业里面发生,但是也不能以这个为理由去打击它。 你不必要去创造一个敏捷的过程来规定测试工程师可以修复BUG。 上面这三点非常模棱两可的观点,在我看来就是作者让读者知道,我们在充分了解上下文的前提下来进行判断。对于我现在所处的公司的环境下,昨天我做的事情是没啥问题的。 公司没有严格的流程或者指引,规定了Tester不能往生产的代码库中check-in代码 现在公司的Developer不是很多,有时候能帮的地方尽量帮助,自己也能学到东西 对于我测试过的代码,熟悉起来还是会比较快 我也需要对代码的质量负责 那么这样做会有什么问题呢? 变相地成了自己测试自己的代码,不推荐 对于测试小组来说,比较难留住人才(那篇文章的观点,也是一个现实) 在多数情况下,测试工程师的工作就是不断地折磨那个被测软件,不断地向被测系统提问题;然后等待被测系统的答案,从这些答案里面获得尽可能多的信息,软件测试在开发生命周期活动里面扮演一个服务者的作用,给开发经理,开发工程师,各个stakeholder们提供信息,所以软件工程师甚少去修BUG。而且在大多数非常正规的企业中,测试工程师设置没机会看到代码,所以也没有办法能修复BUG。软件工程师可以修复BUG吗?可以,不过不常见。

利用序列化和反序列化实现深拷贝

假如说有一个简单的类,只有2个属性,那么可以用比较简单的方法实现深拷贝。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [Serializable] public class Person { public int Height { get; set; } public string FirstName { get; set; } }   class Program { static void Main(string[] args) { //实例化一个对象 Person PersonOne = new Person(); [...]

测试代码重构实例

Martin Fowler的《重构》这本书基本上每个程序员都会看,对于做单元测试的测试工程师来说,测试的代码本身也是程序,也需要重构。最近在看《XUnit Test Patterns》,把以前的做的东西重新梳理了一下,并且落实到新的项目中。 首先来看看一个最原始的单元测试代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 [TestMethod] public void GetPaymentAccountByOwnerID() { int ownerId = 1300100000; //Delete the account TestHelper.DeletePaymentAccountByOwnerId(ownerId);   //Here should be create an account PaymentAccount paymentAccount = PaymentGateway.PaymentProvider.GetPaymentAccountByOwnerID(ownerId, AccountOwnerType.NormalUser);   //Verify the payment account instance Assert.IsTrue(paymentAccount.AccountID [...]

避免用户用一个邮箱在网站上注册多个帐号(马甲)

SNS的风已经刮过了,国内不少SNS网站正在刮第二阵风:游戏!像聚友网,开心网,山寨开心网,校内等社交网站都添加了大量的游戏,在这些游戏中都有一个共同之处–邀请朋友注册送积分(金币,道具等等……)。很多人就会多申请几个邮箱,然后再多注册几个马甲来获利。 我比较懒,一直想着有什么样的办法可以不申请更多的邮箱,而又能多注册几个马甲。可能大家都比较熟悉Google的Gmail邮箱,这个邮箱有一个特点就是它那神奇的“+”加号。例如现在我有这样一个邮箱abc@gmail.com那么我只需要在@符号和abc中间添加一个“+”,还有若干文字,就能“生成”一个新的邮箱,无需申请。例如abc+haha@gmail.com, abc+hi@gmail.com,这2个邮箱的邮件都发送到abc@gmail.com中,这就方便了我们注册马甲啦!

单元测试中三种准备Test Fixture的方法比较

首先说一下Test Fixture,我不知道怎么样翻译这个Test Fixture,没能搜到一个翻译的比较合适的。最让我气愤的是某人翻译的一本书中,直接把Test Fixture翻译成为测试夹具,这明显就是什么词霸词典硬翻译出来的,我强烈鄙视这样不负责任的翻译行为。 The test fixture is everything we need to have in place to exercise the SUT 我觉得这是一个对Test Fixture的一个很清晰明了的定义,就是运行被测软件所需要的一切东西,这个“东西”不单只是数据,同时还包括对被测软件的准备,例如实例化某个被测方法所在的类,准备数据库的ConnectionString等。通常来说,有三种方法来准备Test Fixture。 1. 内联方式:这种方式就是直接在测试方法中编写准备Test Fixture的代码。用这种方法的缺点是很容易造成代码的重复,出现很多复制粘贴的代码。同时,如果这个SETUP的过程比较复杂,也会降低测试代码的可读性,可维护性。另外的一个问题就是,这种方法很容易会带来测试数据Hard code的隐患。既然有那么多缺点,这种方法还有什么生命力呢?首先,可能对于初学者来说,这种方法是最简单的;其次,在一些只需要准备简单的Test Fixture的场合中,这种方法还是给编写测试的人提供了便利。

控制反转有助于提高程序的可测试性

控制反转,英文是Inversion of Control,简称IoC。这个概念在JAVA的Spring框架中比较常见,在.NET的开发中,Ioc或者其的变种依赖注入DI(Dependency Injection)是不太常见的。一般来说,类A要使用类B,类A会在其内部对类B进行控制,比较典型的做法就是在类A中创建一个类B的实例;而控制反转,就是把一个已经创建好的类B实例交给类A去控制。 例子:

.NET平台上的Memcached客户端介绍

早上接到一个任务,需要对Linux服务器的Memcached的update操作进行性能测试,我发现我是一个典型的“手里拿着锤子,就把所有问题都当成钉子”的人。我第一个念头就是,上Memcached的官网找.NET的客户端。最后在Codeplex上找到了一个叫Memcached Providers的客户端程序,很小,218K,里面就3个DLL,一个是Memcached Providers本身的DLL,还有一个是Enyim.Caching,Enyim.Caching也是一个.NET平台上的Memcached客户端,最后就是著名的log4net。 Memcached Providers的配置很方便,首先就是在.NET项目中引用上述提到的3个DLL文件,然后就需要修改项目的配置文件,如果是桌面程序,就修改APP.CONFIG,如果是WEB程序,就修改WEB.CONFIG。

自动化单元测试要点

用单元测试的框架MSTEST,做单元测试,集成测试快1年了,总结一下工作中学到都东西。 单元测试,集成测试有什么用? 1. 改进产品质量 软件测试,很多时候围绕着两个问题: Verification和Validation,常说的双V。前面的Verification就是Is the software built correctly?。后面的Validation就是Have we built the right software? 单元测试,更多的是Verification。所以有时候经过我单元测试和集成测试以后的功能模块,在交给其他同事做功能测试的时候,依然会有一些BUG,这时候开发可能会埋怨我测试得不够完全,诸如此类。但是其实很多时候,我的关注点是单个方法的功能、行为,没有站到更高的位置来测试这个模块。对于这样的问题,开发和测试应该互相体谅,我本人也会提高自身的水平。希望在单元测试和集成测试中也加入更多关于Validation的思考。

单元测试的坏味道

Martin Fowler有一本很出名的书《重构》,里面有个很出名的概念,Code Smell。前阵子我也刚发现一本很好的书,《XUnit Test Patterns》。这本书主要讲的是如何重构测试代码,这里的测试代码指的就是自动化测试的代码,再进一步细化就是单元测试为主的自动化测试代码的重构。由于此书已经让清华大学翻译烂了……所以建议大家下载英文版。 所谓的测试的坏味道,有三种: 项目(Project) 行为(Behavior) 代码(Code) 按照《重构》书中提出的坏味道的概念来看,如果说是有坏味道(Smell),那么大多数都是指代码级别的。什么的坏味道?就是程序有可能会有大问题的一种征兆(symptom)。个人理解就是不能被直接观察到的现象,可以称之为坏味道。 对于自动化测试代码来说,如果有了项目级的坏味道,通常变现就是生产环境出现了BUG。如果出现这样的情况,那么自动化测试代码就不是有味道那么简单了,而是有问题了,自动化测试的安全网没有能够抓住这个BUG。