为什么不赞成测试MVC视图?


23

我目前正在为ASP.Net MVC应用程序奠定基础,并且正在研究应该准备编写哪种单元测试。我已经在多个地方看到人们在本质上说:“不要打扰测试您的观点,没有逻辑,这是微不足道的,将被集成测试所涵盖”。

我不明白这如何成为公认的智慧。集成测试的目的与单元测试的目的完全不同。如果我中断了某些事情,我不想在半小时后的集成测试中断时就知道,我想立即知道。

示例场景: 假设我们正在与一个Customer实体一起处理标准的CRUD应用。客户有名字和地址。在每个测试级别,我都想验证客户检索逻辑是否正确获取名称和地址。

为了对存储库进行单元测试,我编写了一个集成测试来访问数据库。为了对业务规则进行单元测试,我模拟了存储库,为业务规则提供适当的数据,并验证是否返回了预期的结果。

我想做的是: 为了对UI进行单元测试,我模拟了业务规则,设置了预期的客户实例,渲染了视图,并验证视图是否包含我指定的实例的适当值。

我要做的事情: 要对存储库进行单元测试,我编写了一个集成测试,设置了适当的登录名,在数据库中创建了所需的数据,打开浏览器,导航到客户,并验证结果页面是否包含适当的内容我指定的实例的值。

我意识到上面讨论的两种情况之间存在重叠,但是关键的区别在于设置和执行测试所需的时间和精力。

如果我(或另一个开发人员)从视图中删除了地址字段,则我不想等待集成测试发现这一点。我希望在每天多次获取的单元测试中被发现并标记出来。

我感到我只是没有掌握一些关键概念。有人可以解释为什么要对MVC视图的有效性立即进行测试反馈是一件坏事吗?(或者,如果还不错,则不是获得所说反馈的预期方式)


1
"To unit-test the repository, I write an integration test"等等...什么 这不是存储库的单元测试。您正在为其自动化测试,但是被测代码仍然包括DAL和数据库。要对存储库进行单元测试,您需要像对待业务规则一样对它进行隔离。
StuperUser 2011年

对按预期方式渲染的视图进行单元测试只是模板引擎正常工作的单元测试。就像对已编译的C进行单元测试时,包含某些机器代码块,对编译器进行单元测试而不是对代码进行单元测试。
雷诺斯2011年

2
@Raynos恭喜,我将不得不不同意。如果我(或其他开发人员)错误地连接了UI,以在UI字段中为另一个呈现一个数据属性(例如,“姓氏字段”中的“名字”,则与模板引擎无关),或者它是一个DAL或BR问题..它显然将仅在视图中暴露了一个问题。
彼得·伯尼尔

1
@PeterBernier您的观点很不错,但是我发现很难定义“测试编译器是否有效”和“测试我的代码是否有效”之间的界限。更不用说UI的测试与UI紧密相关。用户界面的任何更改都会导致测试失败。在不导致测试失败的情况下,您实际上无法对UI进行任何形式的重构。
雷诺斯2011年

Answers:


9

简单的UI测试在ASP.NET MVC中非常容易。本质上,您要做的只是断言返回的HTML包含您需要的元素。尽管这可以确保HTML页面按照您期望的方式进行结构化,但它不能完全测试UI。

正确的Web UI测试要求使用Selenium之类的工具,该工具将使用计算机上的浏览器并确保JavaScript和HTML在所有浏览器中均能正常工作。Selenium确实具有客户端/服务器模型,因此您可以拥有一组带有Unix,Mac和Windows客户端的虚拟机以及这些环境通用的浏览器。

现在,一个设计良好的MVC(模式,而不是框架)应用程序将重要逻辑放入模型和控制器中。简而言之,当您测试这两个方面时,即会测试应用程序的功能。视图往往仅具有显示逻辑,并且可以通过视觉检查轻松检查。由于视图中的精简处理和经过良好测试的应用程序的大部分,许多人并不认为测试视图层的痛苦大于其所获得的好处。

也就是说,MVC确实具有一些不错的功能来检查请求返回的DOM。这大大减轻了测试视图层的痛苦。


1
“基本上,您所需要做的就是断言返回的HTML包含所需的元素。” 这正是我正在尝试做的事情,事实证明这是不平凡的。您能否指向一个链接,该链接将与特定的控制器动作一起工作,而不是简单地呈现控件?(我已经完成了几篇文章,但是RenderPartial在没有大量开销的情况下无法完成我想做的事情。)
Peter Bernier

您将要查看mvccontrib.codeplex.com(MVC Contrib)。这提供了核心语言未内置的帮助,并且在“ Test-Drive ASP.NET MVC”(实用程序员)一书中建议使用此帮助。不过,我仍然认为Selenium更适合进行View测试。
Berin Loritsch 2011年

TestHelper(MVC的Contrib):mvccontrib.codeplex.com/...
帐户berin Loritsch

Selenium(在我的情况下为Selenium RC)是我将用于集成测试的东西。我想要的是在此之前发生故障。
Peter Bernier

2
@Peter:您对自己的工作“不平凡”的评论正是单元测试视图被皱眉的原因。因此,一种典型的策略是使视图尽可能地薄(即不包含业务逻辑),以便大多数单元测试可以在其他地方进行(通常在ViewModel中)。视图本身可以通过视觉检查或使用Selenium之类的UI测试工具进行验证。
罗伯特·哈维

7

我不会说这不满意。相反,这种感觉是由于对MVC视图(至少是aspx种类)进行单元测试非常困难的结果,因为aspx视图对WebForms的依赖过多,而WebForms本身却是不可测试的。因此,有观点认为,不值得付出努力,因为观点往往没有那么复杂。

当然,视图可能会变得非常复杂,因此由您选择。


3
据我所知,ASP.NET MVC视图与Webforms无关。不是Webforms的ASP.NET MVC的一大亮点不是吗?
亚当李尔

我的观点是,编写集成测试来覆盖UI比编写真正的“单元测试”来覆盖视图需要更多的人力。这就是为什么我试图理解似乎在为视图编写单元测试方面存在的一些阻力。
Peter Bernier

@Anna Aspx视图建立在WebForms之上。它们从System.Web.UI.WebControls.Page类派生,使用<asp:ContentPlaceholder>控件等。MVC执行它们的方式避免了通常与WebForms相关联的许多Page执行管道,但在幕后仍然使用了许多WebForms内容。
2011年

如果使用其他视图引擎(例如剃刀),则应该能够远离Webforms引擎。
松饼人

6

我不确定它是否会皱眉。可测试性是使用ASP.NET MVC的主要优势之一。请查看Steve Sanderson的博客,以获取有关此内容的更多信息。

他还在那里写下了最好的ASP.MVC书(IMO)。他不仅会教MVC,而且还会继续教授有关MVC的最佳实践,包括测试实践。

我认为我需要对单元测试视图进行澄清-您可以围绕从控制器返回的结果(ActionResult等)构建单元测试。您仍然需要对实际的UI和UI交互进行其他测试。


“您仍然需要对实际的UI和UI交互进行其他测试。” 这正是我的问题。为什么UI测试突然成为“其他测试”(即集成测试)的一部分。我看到了很多史蒂夫·桑德森的内容,这就是让我开始走这条路的原因,基本上是试图复制他在“ MvcFakes”项目中所做的工作,并遇到了为较旧的MVC版本编写代码的问题。 。
彼得·伯尼尔

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.