Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm currently setting the groundwork for an ASP.Net MVC application and I'm looking into what sort of unit-tests I should be prepared to write. I've seen in multiple places people essentially saying 'don't bother testing your views, there's no logic and it's trivial and will be covered by an integration test'.

I don't understand how this has become the accepted wisdom. Integration tests serve an entirely different purpose than unit tests. If I break something, I don't want to know a half-hour later when my integration tests break, I want to know immediately.

Sample Scenario : Lets say we're dealing with a standard CRUD app with a Customer entity. The customer has a name and an address. At each level of testing, I want to verify that the Customer retrieval logic gets both the name and the address properly.

To unit-test the repository, I write an integration test to hit the database. To unit-test the business rules, I mock out the repository, feed the business rules appropriate data, and verify my expected results are returned.

What I'd like to do : To unit-test the UI, I mock out the business rules, setup my expected customer instance, render the view, and verify that the view contains the appropriate values for the instance I specified.

What I'm stuck doing : To unit-test the repository, I write an integration test, setup an appropriate login, create the required data in the database, open a browser, navigate to the customer, and verify the resulting page contains the appropriate values for the instance I specified.

I realize that there is overlap between the two scenarios discussed above, but the key difference it time and effort required to setup and execute the tests.

If I (or another dev) removes the address field from the view, I don't want to wait for the integration test to discover this. I want is discovered and flagged in a unit-test that gets multiple times daily.

I get the feeling that I'm just not grasping some key concept. Can someone explain why wanting immediate test feedback on the validity of an MVC view is a bad thing? (or if not bad, then not the expected way to get said feedback)

share|improve this question
1  
"To unit-test the repository, I write an integration test" Wait... what? That's not a unit test of the repository. You are automating the test for it, but code under test still includes the DAL and the database. To unit test the repository you have you isolate it like you have for your business rules. –  StuperUser Oct 12 '11 at 12:22
    
Unit testing the view rendered as expected is just unit testing that your templating engine works. That's like unit testing your compiled C contains certain chunks of machine code, your unit testing the compiler not your code. –  Raynos Oct 12 '11 at 13:06
2  
@Raynos Respectfully, I'm going to have to disagree. If I (or another developer) mistakenly wires up the UI to render one data attribute in the UI field for another (For example, 'First Name' in the 'Last Name Field', that has nothing to do with the templating engine, nor is it a DAL or BR issue.. it's clearly a problem that would only be exposed on the view. –  Peter Bernier Oct 12 '11 at 14:51
    
@PeterBernier you have a good point, but I find it difficult to define the line between "testing whether the compiler works" and "testing whether my code works". Not to mention that tests for the UI are tightly coupled to the UI. Any changes to the UI cause the tests to fail. You can't really do any kind of refactoring of the UI without causing a test to fail. –  Raynos Oct 12 '11 at 15:49

4 Answers 4

Simple UI testing is easy enough in ASP.NET MVC. Essentially all you have to do is assert that the returned HTML contains the elements you need. While this ensures that the HTML page is structured the way you expect, it doesn't fully test the UI.

Proper web UI testing requires a tool like Selenium that will use browsers on your machine and ensure that the JavaScript and HTML are working properly in all browsers. Selenium does have a client/server model so that you can have a set of virtual machines with Unix, Mac, and Windows clients and the set of browsers common to those environements.

Now, a well designed MVC (pattern, not framework) application puts the important logic in the models and controllers. In short, the functionality of the application is tested when you test those two aspects. Views tend to only have display logic and are easily checked with visual inspection. Due to the thin processing in the view and the bulk of the application being well tested, many people don't think that the pain of testing the view layer outweighs the benefit gained by it.

That said, MVC does have some nice facilities to check the DOM returned by the request. That reduces the pain quite a bit for testing the view layer.

share|improve this answer
    
"Essentially all you have to do is assert that the returned HTML contains the elements you need." This is exactly what I'm trying to do and it's turning out to be non-trivial. Can you point to a link where that'll work with a specific controller action as opposed to simply rendering a control? (I've worked through a couple of write-ups, but RenderPartial isn't accomplishing what I want to do without significant overhead..) –  Peter Bernier Jan 5 '11 at 15:59
    
You'll want to check out mvccontrib.codeplex.com (MVC Contrib). This provides help that wasn't built in to the core language, and was recommended in the book "Test-Drive ASP.NET MVC" (pragmatic programmers). I still think Selenium is a better match for View testing, though. –  Berin Loritsch Jan 5 '11 at 16:06
    
TestHelper (MVC Contrib): mvccontrib.codeplex.com/… –  Berin Loritsch Jan 5 '11 at 16:08
    
Selenium (in my case Selenium RC) is what I'll be using for my integration tests. What I want is for a failure to happen before that point. –  Peter Bernier Jan 5 '11 at 18:05
1  
@Peter: Your comment about your efforts being "non-trivial" is exactly the reason that unit testing views is frowned upon. Consequently, a typical strategy is to make the views as thin as possible (i.e. containing no business logic), so that most of the unit testing can take place somewhere else (generally in the ViewModel). The views themselves can be verified by visual inspection, or with a UI testing tool like Selenium. –  Robert Harvey Jan 12 '11 at 17:29

I wouldn't say it's frowned upon. Rather, that sentiment is the result of the fact that unit-testing MVC views (at least of the aspx variety) is quite hard because aspx views have too much dependency on WebForms, which are themselves quite untestable. So the argument goes that it's not worth the effort because the views tend to be not that complicated.

Of course views can get quite complicated so it's your choice.

share|improve this answer
3  
ASP.NET MVC views aren't tied to Webforms, far as I'm aware. Isn't one of the big points going for ASP.NET MVC that it's not Webforms? –  Anna Lear Jan 5 '11 at 15:28
    
My point of view is that it takes more human effort to write the integration tests to cover the UI, than it would to write real 'unit-tests' to covers the views. That's why I'm trying to understand some of the resistance that seems to be out there towards writing unit-tests for the views. –  Peter Bernier Jan 5 '11 at 15:36
    
@Anna Aspx views are built on top of WebForms. They derive from the System.Web.UI.WebControls.Page class, use <asp:ContentPlaceholder> controls etc. The way MVC executes them avoids a lot of the Page execution pipeline typically associated with WebForms but it still uses a lot of WebForms stuff under the covers. –  marcind Jan 5 '11 at 16:18
    
If you use a different view engine (such as razor) you should be able to move farther away from the Webforms engine. –  The Muffin Man Dec 9 '11 at 19:29

I'm not sure that it is frowned upon. Testability is one of the key benefits of using ASP.NET MVC. Check out Steve Sanderson's blog for more info on this.

He also wrote the hands-down, best ASP.MVC book (IMO) out there. Not only does he teach MVC, but he goes above and beyond to teach best practices around it, including testing practices.

I'm thinking I need to clarify a bit on unit testing views -- you can build unit tests around the result returned from the controller (ActionResult, etc.). You'll still need to do other testing for the actual UI and UI interaction.

share|improve this answer
    
"You'll still need to do other testing for the actual UI and UI interaction." That's exactly my point of the question.. why do the UI tests suddenly become part of 'other testing' (ie, integration testing). I'd seen alot of the Steve Sanderson content and that's sort of what got me started down this path, basically trying to replicate what he's doing with his 'MvcFakes' project and running into into issues with his code being written for older MVC releases.. –  Peter Bernier Jan 5 '11 at 15:32

You can learn how to test the View returned by a controller action, how to test the View Data returned by a controller action, and how to test whether or not one controller action redirects you to a second controller action by check out the following URL, describe in this brief article about Testing View Data in MVC.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.