【MVC拾遗】MVC的单元测试简单学习总结

关于测试的必要性什么的已经在 重构与测试 里扯过了。倒也不必说,写的代码多了天然就明白这个东西重要性。html

当时说了坐等被推进去学习单元测试来着,然而等着被人推进的结果就是根本就没人来推你。o(∩_∩)o编程

因此仍是本身主动来学,主动来总结了。框架

可测试性设计基础理论知识函数

可测试性设计(Design for Testability, DFT)是一种集成电路技术,它将一些特殊结构在设计阶段植入电路,以便设计完成后进行测试。单元测试

后来这种玩法被应用到了软件之中。它关注的是在正确的、错误的、丢失的和不完整的输入下的输出是否符合预期。学习

具备可测试性的软件通常是采起松散设计,目的是为了方便测试软件去调用,那么低耦合就是它的原则了。(话说回来,就算不为了可测试性,低耦合也很重要啊)测试

好比基于接口来编程,就是众所周知的降耦合的方法之一,减小测试时的依赖性。编码

编写可测试性代码的时候,也是对代码结构的一个评审,由于一个在测试中没法轻松实例化的类,那么就一定会存在耦合问题。spa

测试的代码也应该保证效率,而低耦合也能够减小一些无用的测试环境的配置,那么测试代码的运行速度就会提高,这在大的项目中尤其重要。.net

若是不能使代码的结构低耦合,那么就不是单元测试了,而变为了集成测试。

虽然集成测试一样有必要,可是不管是运行速度上仍是对于问题发生后定位问题的速度上而言,都不如单元测试方便。

关于单元测试

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。

上面是单元测试的百度百科定义。

单元测试包括编写和运行一个小的程序,以自动的方法实例化测试类以及调用测试方法。

若是咱们要手动去写代码去测试一个程序,虽然是可行的,可是毕竟耗时耗力,因此执行单元测试的最有效和最多见的方式是使用自动化的测试框架。

这个框架一般包括一个运行时引擎和一个类的框架,用于简化测试程序的建立。

经常使用的自动化测试框架有:MSTest、NUnit以及xUnit.net。

MSTest看这名字就直到来自微软,也就自动集成在VS中了,而为了懒得下别的资源的缘由o(︶︿︶)o ,这里就用MSTest了。

单元测试中有测试固件这么个概念,实际上就是一个用于测试的类,这个类建立和结束的时候可能还会去设置测试环境和消除测试环境什么的。(因此咱们后面仍是就叫测试类吧)

测试方法的典型设计能够总结为:设置、做用和断言。(简单来说,第一步设置测试环境,第二步将测试代码做用于须要测试的代码上,第三步将输出结果与预期的断言进行验证)

单元测试是由数据驱动的测试,用不一样的数据(好比临界值,错误值什么的)去测试代码的可靠性。

虽然单元测试也是写代码,可是与日常的写代码仍是有些区别的:

  • 测试范围尽量小。就像单一职责原则同样,目的明确。这样作不只有助于快速定位问题,有助于测试代码的可读性。
  • 隔离测试。即在测试一个方法时,摆脱该方法全部的依赖性,而专一于测试该方法自己。
  • 伪造和模拟。实际上这个东西就是为了配合隔离测试来的,当一个类确确实实只能依赖于另外一个类时,那么就用伪造和模拟一个对象去替代被依赖的类的对象。
    • 伪造对象就是对一个对象的简单克隆,提供与原始对象相同的接口,可是返回硬编码的值。
    • 模拟对象比伪造对象更复杂,它涉及到要去模拟原始对象的一些交互
  • 一个断言。这个是一个争议点,就是为了保证测试范围尽量小。然而在实际操做中,可能会存在不少类似的测试,因此也能够去在一个测试中运用多个断言。
  • 测试非公共成员。方法就是给所测试的类添加一个新类,而后这个新类有一些受保护的方法去调用那些要测试的非公共成员。
  • 代码覆盖率。用来计算被测试的系统中的代码有多少被测试代码测到了,以此来评估测试的可靠性。然而盲目地去提升代码覆盖率并不能说明测试的相关性和有效性,测试的关联性才是重要的。

MVC的单元测试实战

来吧,到了上点干货的时候了,实战永远比枯燥的理论有趣多了。

MVC的实现了控制器、视图、模型的分离,而且不像WebForm那样对Request和Session这些内部组件过于依赖,使得它成为了一个便于单元测试的框架。

首先建立单元测试项目。

被测试的代码就是VS2015下,不带账号系统的MVC项目。如下为VS自动建立的单元测试项目。

能够看到默认的有一个Controller文件夹,下面为控制台测试文件。能够联想到,也能够加一个service或business文件夹去测试代码的业务逻辑。(一般而言更多的测试其实都是针对业务层,由于控制器的代码逻辑通常都比较简单)

那么看看默认的测试类HomeControllerTest中具体的代码:

用TestClass特性去标注测试类,TestMethod特性去标注测试方法。

而观察Index中的代码:

首先声明要测试的控制器类,也就是准备好测试环境,

而后用控制器实例去调用要测试的函数,

最后用断言去判断返回的结果是否符合预期。

 让咱们再加三个特性的用法

而后启动测试什么的也很简单:

测试的结果会显示在测试资源管理器中:

很明显看到被Ignore特性标注的被跳过了测试。还能够选择测试资源管理器中的测试而后进行单个测试,而不是像以前那样测试全部。

其实说穿了单元测试这个东西玩法很简单,须要去掌握的反而是以前的那些理论知识,保证测试的质量和高效。

提及来单元测试麻烦的地方可能也就是去解除依赖性了吧,主要是模拟交互,这个扯起来就麻烦了,百度了一下还有模拟交互的各类框架什么的,并且一些模拟Http上下文的要用到。

不过我想总会有简单的解决办法的,本质上模仿也只是伪造的交互版本而已,那么将伪造的返回结果丰富多样化,那么不就是模仿了吗?

一点拙见啦~

OK,虽然单元测试是个能够简单入门的东西,可是难度仍是有的。

除了上面写到的解除依赖性,最重要的仍是实施和坚持。

从明天开始慢慢来把它归入项目中吧!

相关文章
相关标签/搜索