[转载]打造第二代测试框架TestDriven 2.0(七)

[转载]打造第二代测试框架TestDriven 2.0(七)—— 让测试驱动更加的自动吧! – 美丽人生 – 博客园.

——————–

前 言 Preface

——————–

本 文介绍了一种新颖的测试思路,并制作了原型系统展示其效果。

此技术将作为测试驱动框架2.0的一个部分(Testdriven 2.0) 。

而 测试驱动2.0的目的是:让代码之间沟通,让变化更加容易。

——————–

测 试分类 与 本文的讨论对象 Catalog 

——————–

测试包含了很多种, 每一种需要特定的技术去解决,例如:

1. Winform类的界面测试:通常使用钩子等Win32接口去捕捉用户的操作,然后模拟回放进行测试(此技术不在讨论范围)

2. Web界面测试:一般使用JS嵌入测试页面,同样模拟用户操作;或者使用IE内核等调用内部函数实现用户操作(此技术不讨论)

3. Web的Http模拟测试:在.net 2.0比较难实现,到了3.0之后的版本,微软对HttpContext这个庞然大物体做了重构,因此让测试变得稍微简单了。(此技术不讨论)

4. 类库、代码测试:这个是我需要讨论的终点,包含了各种框架、逻辑应用等。现有的技术主要是UNit / Testdriven.net / Mock等。他们也貌似很好的解决了一些问题。但是。。。

所以,本文接下来将针对第4种测试 (类库、代码测试),也是最常见的测试进行讨论。

———————

现有的问题 Problem

———————

现在的测试,很大一 部份是在回归。开发者梦想编写好自动测试代码,日后如果有变动,通过做回归,就知道是否破坏了之前的功能、是否产生了bug。朝着这个目标,诞生了很多测 试工具。可是在我看来,他们只是从一个小坑跳到了另外一个大坑。(也就是我之前说的,掉入自己挖的坑里了)

首先,测试的结 果是否准确,完全取决于测试数据是否全面准确。 那么编写测试数据本身就存在了人为的bug。

其次,测试代码和业务代码紧 密联系,一旦业务代码修改,测试代码往往是全盘否定的。这就出现一个矛盾:如果测试代码写的马虎,日后基本上不能用;如果测试代码写的精细,一旦修改起 来,之前的工作都白费了。

所以,我们真正期望的是:能够自动分析业务代码,自动编写测试代码, 而不是人去写。这个目标现在还很难实现(微软在VS2010里面已经大量引入了Code Gen等技术,可是。。)

可 是难,不等于不行,下面我将尝试迈出一小步。

———————

原理分析 Analysis

———————

要 让测试变得自动,首先需要抽象出测试过程,然后逐一攻破。经过我分析,一段测试代码主要包含了三个方面:

1. 测试数据生成。

直 接决定了测试代码是否有效;因此要求全面、准确、也业务逻辑精密绑定。 这部分工作目前是没有更好的思路。

2. 调用对应方法。

这个很简单,就是调用一个方法,传入测试数据。没有优化的必要。

3. 查看测试结果是否符合预期。

这部分以往是写这非常无聊的Assert.IsEqual等。既无聊,又浪费时间。而恰恰这部分我发现了提升的 空间。

测试结果无非就是字符串、对象等。就是C#的ValueType / class。 而如果是对象,也一定是对象的某些属性(Property) 。而这些数据都是可以被序列化、反序列化的!

因 此 这个过程完全可以被机器代替,从而让测试代码变得更加灵活,立马减少50%的工作量!现在我就展示一下目前的原型系统效果。

———————

原 型系统效果  ProtoType

———————

首先是一段测试代 码。

public void test00001()
{
object pojo = CreatePojo();

Assert.SaveOrVerify(test000 create pojo, pojo);
}

这 段代码的目的是 测试生成的pojo对象是否符合预期。 而一个Pojo对象可能是下面一个接口的实例:

代码

interface IinterfaceWithAllCollection
{
byte[] Image { get;set;}
string Name { get;set;}
double Fee { get;set;}
int Age { get;set;}
IinterfaceWithAllCollection[] pojos {
get;set;}
List
<IinterfaceWithAllCollection> pojos2 { get;set;}
ObjectWithValue objPojo {
get;set;}
ObjectWithValue[] objPojos {
get;set;}
List
<ObjectWithValue> objPojos2 { get;set;}
}

按照以往的做法,一定是要展开这个对象,获 取每一个属性,然后做Assert。现在我仅仅需要一句话就完成了测试 结果验证
Assert.SaveOrVerify(test000 create pojo, pojo);

不 知道您感受到了其中的魅力和惊喜没有?

调用了这句话, 框架首先会搜索保存在磁盘的结果数据,一般是xml文件;这些数据本质上就是预期结果的序列化值。然后逐一和这些值做对比。

那 么您一定好奇,这些期望的值从哪里来?答案就是,代码本身生成。当第一次执行的时候,是没有预期值的,那么框架会给出警告,然后将当前数据持久到磁盘。例 如:

代码

—— Test started: Assembly: Pixysoft.Framework.Configurations.dll ——

WARNING: expected value do not existed. create new one for test000 create pojo
Verifying IinterfaceWithAllCollection.Image.
TRUE: expected
=%01, actual=%01

Verifying IinterfaceWithAllCollection.Name.
TRUE: expected=hello, actual=hello

Verifying IinterfaceWithAllCollection.Fee.

。。。。。 省 略

这个时候,我调用一个配置界面,就可以查看第一次生成的 值,然后修改成为预期值:

这 样一个序列化结构就可以通过 树形结构 展示出来。 现在我们只要查看第一次运行的结果是否正确,调整ExpectedValue。 这样这段测试代码就可以永远被重复调用了。

———————-

小 结 Summary

———————-

因为是原型系统,目前还不能发出第 一个release,不过很快就可以完成了。主要是我写的代码和屎一样烂,需要进行优化才好意思拿出来。

等release 出来时候,所有代码都会采取开源的策略。不过是一种新的开源策略。

如果各位有急着需要的,咱们可以相互讨论交流下。希望大 家多提供些思路,多提供您期望的需求。谢谢!


我们的最新动态 (Bamboo@pixysoft.net)

  • 1.DynamicProxy开发完成.和微软的Realproxy比较.性能提高1.5倍… [2010-6-5]
  • 2.对象反序列化的emit框架完成.性能测试提高了15倍.[2010-6-4]
  • 3. 对象序列化操作使用最新的emit框架.动态编译.性能提高了10倍…[2010-6-3]
  • 我们每天都在努力着!

作者:美丽人生
出处:http://zc22.cnblogs.com/
技术支持:reborn_zhang@hotmail.com
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏