新项目,WebTest

最近为了给Jumony for ASP.NET进行单元测试有点伤神,ASP.NET由于环境特殊,一直是单元测试的禁地,传统的单元测试工具因为运行在非ASP.NET环境,可谓是举步维艰。固然,微软在搞ASP.NET MVC的时候已经注意到了这一点,雇了不少个临时工把HttpContext以及全部的相关类型所有写了个Base和Wrapper类型,用来Mock一个HttpContext伪装在ASP.NET环境。有了这些对象,测试个MVC的Controller和Action也够用了(只是我还没找到自动Mock这一大坨对象的方法)。可是ASP.NET环境显然不止这些,譬如说你们不多用到的VirutalPathUtility就在其列。因为Jumony for ASP.NET是个框架性质的项目,因此一些框架底层不经常使用的东西随处可见。固然,也有人不堪其扰,对这个东西也改造了一番: git

还有这个: github

但这些都是internal的,我不能直接用之,再说,指不定哪天就成了public的,个人还与其冲突。最后,我也没有微软那么多临时工去一个个方法Mock出来。想来想去,个人要求再简单不过,只要有个HttpRuntime就行了,不妨直接用真的ASP.NET环境。 app

 

用真的ASP.NET环境有几个方案,VS自带的测试工具支持ASP.NET的测试,可是摸索了半天,发现局限大的很,还只能测试aspx文件,用起来也很是的不方便,彻底不能知足个人要求,遂放弃。 框架

而后又想,干脆本身用控制台搭一个ASP.NET运行环境出来,这样的话就能够本身发个请求进去,让里面的代码执行个结果扔出来。虽然说微软提供了本身搭建ASP.NET环境的类型和工具,可是因为宿主和ASP.NET环境是在两个AppDomain,通讯不便不说,调试起来也特别麻烦,网站编译什么都是事儿。 工具

最后,终于想到,TMD干脆本身在ASP.NET环境搭一个单元测试框架算了。话说其实一个单元测试框架就是找到测试方法而后所有跑一次,再看看有没有什么AsertException之类的东西,显示出来就完了。我直接在ASP.NET环境搭一个,整个单元测试都在网站跑,就什么问题都解决了。 单元测试

 

而后,就有了WebTest这个开源项目: 测试

https://github.com/Ivony/WebTest 网站

 

既然是从新搞,那新的技术神马的全都给用上,之前的Assert是个静态类,一大堆的静态方法,有些断言没有就只好转换成真假再去判断。新的框架索性把Assert弄成个对象,全部的断言方法都给整成扩展方法,大家爱有多少断言就有多少,不够再来补充包。之前的测试得本身写个静态类,而后每一个方法都要加个[TestMethod]告诉框架这个方法是个测试用的,而我以为这纯属多余。只须要写一个类型,里面全部的无参public方法所有都被认为是测试方法,反正框架都会一个个来跑。 设计

肯定好思路后,作起来仍是很快的。首先我想到要有一个类型负责运行测试。 调试

而后来设计这个类型:

  1. 首先咱们能够获得一个测试类型,把测试类型丢给TestManager,就能够进行测试(RunTest)。
  2. TestManager获得测试类型后,应当建立一个实例来测试,由于全部的测试方法都是实例方法(RunTest)。
  3. 对实例进行测试(RunTest)时,应当找出哪些方法是用来测试的方法(FindTestMethods)。
  4. 找到测试方法后,要给测试方法建立调用器(CreateInvoker),便于快速调用测试。
  5. 运行完测试方法后,要建立测试结果(TestResult),测试结果有三种,成功(Success)、失败(Failure)、异常(Exception)。
  6. 建立测试结果前,要获取当前测试方法的信息(GetTestInfo),放在测试结果中。

设计后的结果就是以下图:

再加上一个找到全部测试类的静态方法,TestManager就差很少了。

而后是设计TestResult类型,呈现结果的时候,最关键的只有两个元素,消息和是否成功,而后针对三种测试结果,设计三个派生类:

 

再而后定义一个测试基类,继承于这个类型的全部类型都是测试类:

Initialize和Cleanup如今均可以定义为这个基类的虚方法,若是须要的话就重写好了,事实上查找测试类型的时候,查找基类比查找Attribute要快,我想不通如今的测试框架为啥都要弄个特性来标识。

测试基类提供了一个Assert对象,这个对象能够用来进行断言:

由于全部的断言方法都作成扩展方法,因此断言失败的时候须要调用Failure方法来描述断言失败了。

 

至此,OOD就基本完成了,而后是一些细节的实现。

查找全部测试类型:

找全部测试方法:

建立Invoker:

事实上,若是熟悉ASP.NET MVC的代码,这些看似高深的东西并不费神。

 

最后,写一个IHttpHandler做为总控,运行测试,并显示测试结果,而后,就能够直接写单元测试用例了。

固然,做为一个单元测试框架,目前还有诸多欠缺的地方,例如伪造指定URL的请求,分析代码覆盖率等,若是我有时间的话,会继续完善这个框架的。

 

事实上,单元测试并不难,即便是搭建一个测试框架,也就是几百行代码的事情,咱们有什么理由不去作呢?

相关文章
相关标签/搜索