解决真实世界的单元测试问题
作者:网络转载 发布时间:[ 2012/11/2 9:39:12 ] 推荐标签:
过去几年的经验告诉我:单元测试已然是“被解决的问题”了。所有的信息、图书、工具都摆在面前,你只要把NUnit拣起来可以上路了,不是么?
不是。
即便是在下决心要开始写单元测试之前,我们也得从别人那里吸取经验,从那些好的坏的故事里,那些令人绝望或是见证奇迹(一个测试省了我一周时间!)的时刻中,取其精华弃其糟粕。即便这样,等我们勇敢上路之后还会意识到,要学的东西还多着呢!
我想跟你讲讲我在单元测试这片大陆上一段奇妙的旅程。我们Typemock的团队已经在这块大陆上游历了数年,这些经历也改变了我们的产品开发过程。Isolator是我们的主打产品,它开始是作为mock框架出现的,但是当我们对在真实世界中单元测试的问题了解的越来越多,我们开始开发一些特性帮人们解决这些问题。直到现在,还有很多事情没搞定。
不过我们还是从头讲起吧。Typemock有一个简单的信念:让单元测试变得很容易。
够简单吧,可是容易么?
呵呵……
写单元测试可不是件容易的事情。单元测试的好处数不胜数,这大家都明白。但你得好好加把劲,才能享受到这些好处。
咱们都有个代码库。有些幸运的家伙会面对一块未开垦的处女地,但更多的人却会遇到大量“遗留代码”,这才是常态。我们写测试的时候,测的是那些遗留代码。这真的很棘手啊。
Typemock刚刚起步的时候,不修改代码给遗留代码写测试还是件不可能的事情。但这正是Isolator的主要目标:在不修改代码的情况下编写单元测试。当Isolator能够mock每一种.NET对象类型,给遗留代码写单元测试已成为可能。
演化中的API
随着时间推移,我们明白了要好好控制API。开始的一版API是基于string的,比如要伪造DateTime.Now的时候,你需要这样写:
Mock mockDateTime = MockManager.MockAll<DateTime>();
mockDateTime.ExpectGetAlways("Now", new DateTime(2000, 1, 1));
看上去不太漂亮,但是管用。然而这些代码稍一重构会废掉。所以我们换成了录制-重放(record-replay)模型,对重构的支持友好一些了,虽然看上去有些怪异:
using (RecordExpectations recorder = RecorderManager.StartRecording())
{
DateTime.Now = new DateTime(2000, 1, 1);
}
这一版API算得上是一次革命性的飞跃,但是录制-重放模型已经过时了,而且这个版本还有些技术问题需要解决。所以当lambda表达式出现以后,我们的API又为了保证可读性和支持重构来了个华丽的转身:
Isolate.WhenCalled(() => DateTime.Now).WillReturn(new DateTime(2000, 1, 1));
在当前这个版本中,我们还做了另一个简化,用“fake”换掉了“mock”这个词汇,“mock”和“stub”被用的太多了,而且总是被滥用,被误解。为了避免麻烦,我们决定回避这个问题,省得还要把mock和stub之间所有的细微差别给新手一一讲述。
贴心的邻居
Isolator不只是Visual Studio的插件而已──我们得让它跟其他工具和供应商集成。代码覆盖率,性能分析器,构建引擎等等,不管是啥,只要你能想得到。Isolator需要良好的兼容性,这样大家能在不同的配置下用不同的工具跑测试。
说到跑测试,脱离Visual Studio跑怎么样?当你开始做自动化构建的工作以后,你会学到很多MS家族中琳琅满目的工具,当然也包括全能的TFS大神。Isolator在分析器上做了大量的集成工作,让测试能被纳入持续集成流程中运行。因为不同的团队会用不同的工具集和CI服务器,为了保证在不同环境下的适用性,我们是花了不少力气的。
健壮的API
随便找个考虑过写单元测试的人来问问,她都会忧郁地跟你说:我的代码要改,可我不想每次都要改测试。你能帮帮我么?
能力越大责任越大,这句话放到Mock框架上也一点没错(蜘蛛侠也是一样)。改变行为的能力来源于了解对象内部的行为。而这种如同X射线一般的功能,也正是它的阿喀琉斯之踵──改变内部代码同样也会影响测试。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11