对ASP.NET MVC项目中的视图做单元测试

关于视图的单元测试

说到ASP.NET MVC,我们似乎始终都在关注对于Controller的测试——虽然Stephen Walther也写过如 何脱离Web Server对View进行单元测试,但是他的方法可看而不可用。复杂的构造和预备,以及对生成的 HTML字符串作判断——这真是在对视图做单元测试吗?仔细分析他的代码可以发现,这其实是在对 ViewEngine做单元测试。而且,如果真要对ViewEngine做单元测试,也不应该像他那样依赖外部文件。在 我看来,他的做法什么都不是……似乎美观,似乎能博得一些“掌声”,但是这个掌声是来自于他的解决 方案,还是大家一时的冲动呢?

如果要对视图做单元测试,还是要将内容呈现在浏览器中才行。在对网页做单元测试时,我们一般会 使用WatiN等工具操作浏览器,打开页面,再对其DOM元素结构及内容作断言。不过……这是单元测试吗? 可惜这只能算是一种回归测试或用户验收测试。因为,我们在打开一个页面的时候,从表现层到业务逻辑 再到数据访问,应用程序的每个部件都在忙碌着。而单元测试讲究的是“分离”,分离一切关注,分离一 切依赖。因为分离,我们才能准确定位错误;因为分离,我们才能在测试中使用我们准备好的数据。

既然要分离,我们就必须遵循一定的使用规范。在《ASP.NET MVC单元测试最佳实践》中我提到,在 View中只能使用ViewData中的数据,而不该依赖其他内容(包括HttpContext)。这样我们就可以自行构 造ViewData并注入一个视图对象中。事实上,这个约定在ASP.NET MVC自带的项目模板中就被破坏了。请 看Views\Shared\LogOnUserControl.ascx,其中通过this.User来查看当前用户的登陆状态。这是个定义 在传统Page对象上的属性,从当前HttpContext上直接获取。如果使用这种方式,我们在单元测试时就难 以“模拟”当前用户的登陆状态,进而难以使测试覆盖到测试的各种情况了。

Lightweight Test Automation Framework

在这里,老赵推荐使用ASP.NET Team提供的Lightweight Test Automation Framework(下文称之为 LTAF)作为测试工具,它目前已经在CodePlex上更新至Feb Update版本。这个框架的作用与WaitN和 Selenium类似,可操作浏览器对应用程序编写回归测试。虽然在某些方面(例如DOM元素的选取)不如“ 竞争对手”,但是LTAF自有其独到之处:

由于直接在浏览器中运行,它天生便支持现有的——以及未来可能出现的任意浏览器。

由于直接部署在被测试的网站中,因此测试代码和网站页面是在同一个进程中。

第一点优势自不必说,而第二点更是关键。试想WaitN和Selenium,都是通过编写代码在浏览器中打开 页面。这意味着我们的在测试代码和被测试的网页分别在不同的进程中。在这个前提下,如果我们要将测 试代码中定义的数据传递给被测试的网页(也就是视图对象),我们就必须进行跨进程的通信。而无论怎 么实现,都逃不过“序列化”一途,这无疑增加了复杂度。而使用LTAF之后,这个问题瞬间烟消云散了, 因为我们可以直接在内存中“传递”测试数据,一切都只是个引用而已。

不过任何事物都具有两面性,LTAF也有一些难以天生的,而且是永远无法弥补的缺点。例如:

由于LTAF将待测试的页面放置在Frame中,因此该页面上的window.top等基于浏览器frame结构的属性 会被改变。

由于LTAF的本质是使用JavaScript来操作DOM,这意味着任何会阻塞程序进行的操作(例如alert)都 不能使用,否则将阻塞整个测试过程。

不过幸运的是,这两点都不回成为严重的问题。对于第一种,我们只需要编写一个自定的getTop方法 来替换直接访问windows.top的做法即可。而第二种情况——老赵从来不喜欢alert或confirm这种“纯浏 览器功能”,因为它们会带来很差的用户体验,更何况现在的JavaScript类库/框架都能很轻松的做出这 种效果,您觉得呢?

LTAF的具体使用方式可参考其Release Note。令人奇怪的是,老赵发现直接在项目中使用LTAF会有一 些小问题(不过它的示例为什么就一切正常呢?),因此进行了一些细微的修改。请注意 ~\UnitView\DriverPage.aspx文件尾部的一些JavaScript代码。

时间: 2024-11-01 04:11:46

对ASP.NET MVC项目中的视图做单元测试的相关文章

asp.net MVC项目中 没有easyui插件的智能提示

问题描述 asp.net MVC项目中 没有easyui插件的智能提示 5C vs2015 中的mvc4项目,已经分别把jQuery.min.js jquery.easyui.min.jseasyui-lang-zh_CN.js依次拖入,写js代码的时候 智能提示只有jquery中的属性和方法 没有easyui的(例如$.messager就出不来智能提示),但是可以正常执行出来插件效果,尝试编辑cshtml.html格式的文件都不提示,尝试把 jquery.easyui.min.js的文件名改为

在ASP.NET MVC项目中使用RequireJS库的用法示例_javascript技巧

RequireJS 是一个前端模块化开发的流行工具,本身是一个Javascript的库文件,即require.js . RequireJs的主要功能: (1)实现js文件的异步加载,避免网页失去响应: (2)管理模块之间的依赖性,便于代码的编写和维护. 前端模块化开发现在有好多的工具,大体上分为两类,一类是像dojo之类的高大全,dojo v1.8之后已经内置了模块化开发组件:另一类是像require.js,sea.js 这种专心做模块化开发的工具. 从模块化划分的规则来区分,主要分为AMD.C

ASP.NET MVC 3中301永久重定向不带www域名到带www的域名

使用 ASP.NET 又喜欢跟进新技术的朋友可能已经知道,在 ASP.NET 4.0 中增加了 Response.RedirectPermanent() 方法来实现永久重定向,方法的作用在注释中解释的很清楚:执行从所请求 URL 到所指定 URL 的永久重定向,并提供用于完成响应的选项. 在 ASP.NET MVC 3 项目中,我们可以根据需要来使用以下写法实现永久重定向:  代码如下 复制代码 public ActionResult Index() {     return RedirectP

领先技术:在ASP.NET MVC 4中创建为移动设备优化的视图

如果深入探讨有关编写移动设备网站的常识性考虑因素,会发现其中有一种内在矛盾.一方面,客户在其 编写应用程序和网站的方法中强烈要求(或乐于要求)移动优先.另一方面,同一些人又经常称赞 CSS 媒体 查询和流体布局.我所发现的矛盾在于经常利用 CSS 媒体查询和流体布局并未在其他内容之前优先处理移动 方面,它不是一种移动优先的方法.在本文中,我将介绍如何使用服务器端逻辑为给定设备呈现最佳的显示效 果,并介绍 ASP.NET MVC 4 的一种新功能,称为显示模式. 问题不在于 CSS 媒体查询作为一

《精通 ASP.NET MVC 5》----2.2 创建新的ASP.NET MVC项目

2.2 创建新的ASP.NET MVC项目 本节打算从Visual Studio中创建新的MVC框架项目开始.在"File(文件)"菜单中选择"New(新建)"→"Project(项目)",打开"New Project(新项目)"对话框.如果在左侧"Visual C#"目录树中选择"Web"模板,会看到"ASP.NET Web Application(ASP.NET Web应用

【初学者指南】在ASP.NET MVC 5中创建GridView

介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些库能够提供所有必需的功能,如 Web 表格中的搜索.排序和分页等.是否包含这些功能,取决于应用的特殊需求,例如在客户端和服务器端提供搜索或其它功能的需求等. 可用的库 以下是一些可用的库和插件: Grid.Mvc MVCGrid.NET PagedList.MVC JQuery.Grid JQuer

百度Web富文本编辑器ueditor在ASP.NET MVC3项目中的使用说明

  ======================================================================   [百度Web富文本编辑器ueditor在ASP.NET MVC3项目中的使用说明]                                         ----by 夏春涛 2014-02-20   =====================================================================

浅谈ASP.NET MVC 3中如何使用Model

昨天博客发了新文章,讲一下我对如何使用MVC中的Model的看法,不是什么大技术,当是一个技术讨论^^ 原文地址:http://www.youguanbumen.net/Article.aspx?id=79 原文: 前两天写了个文章ASP.NET MVC 3 -- Model远程验证,主要记录了一下ASP.NET MVC 3中新增的RemoteAttribute类的使用,得益于这个类,我们可以在模型中为属性配置客户端远程校验的业务,文章中给了出一个简单的实体类MyUser_Add,举了一个最常见

asp.net mvc项目:做一个简单的购物网站,如何实现让多个用户同时在线购物?

问题描述 asp.net mvc项目:做一个简单的购物网站,如何实现让多个用户同时在线购物? 请知道的同行具体给晚辈吐槽点经验知识(asp.net mvc项目:做一个简单的购物网站,如何实现让多个用户同时在线购物?) 解决方案 每个用户的信息放在session里面,互不干扰的.在数据库中,通过用户id区分不同的用户,所以做网站天然就可以支持多个用户在线购物. 微软专门做了一个asp.net mvc的例子,叫mvcmusicstore,是一个音乐购物网站,你可以google下,有关于它全部的源代码