Unit Testing rich Views for ASP.NET MVC - asp.net-mvc

If I have a rich AJAX-driven GUI in ASP.NET MVC, how would I unit test that effectively using a framework like NUnit?

If you're looking to test the functionality of the UI, use browser automation tools like Selenium.

jQuery has a unit testing project called QUnit which you could use to test your ajax code from a client. It isn't going to integrate with NUnit, but it is another option.

With NUnit, you would primarily be testing your controller actions -- i.e., given a set of parameters and a configuration, does the method return the correct result and view model. If you need to test your client-side javascript, you should look at either a javascript unit testing framework or a UI testing tool, such as Selenium or WatiN.

You can use Selenium IDE to record tests and the generate NUnit testcases to verify behaviour and output of your views.
Steve Sanderson also blogged earlier on today about HtmlUnit on .NET as 'headless browser'. (Testing using the Selenium server can be slow, because it requires creating an instance of FireFox, IE etc);

You would have to unit test your ajax calls and not your UI per se., For example if you are getting some json data through a ajax call, this would translate to a controller method which can be unit tested.
I you want to unit test something which happens after the data reaches the browser then its a whole different ball game and not related to MVC.

Related

Does Geb support multi browser testing?

I would like to ask if Geb supports multi browser testing. i.e. testing same scenario at a time in two different browser on one execution?
geb is built on top of Selenium WebDriver which supports most browsers. See here for geb config for various browsers
I just posted and example app for this. you can create a gradel task to spin through and execute the tests for each browser in the gebconfig. Firefox is a bit of a mess at the moment. link why is provided in the sample gebconfig
https://github.com/basejump/grails3-geb-example

Can I test an ASP.NET MVC web project using Selenium from a unit test project in the same solution?

I have an ASP.NET MVC 5 web project, and I have an MsTest-based unit test project that uses Selenium to do some automated "browser" tests.
Currently, I have to run the web project (in my local IIS Express) and then run the tests against that, but that has all kinds of restrictions. For example, I can only "run" the tests, I can't "debug" them. And clearly this doesn't play well with my continuous integration pipeline.
Is there no way to have the tests spin up an instance of the website? (I know that ASP.NET MVC 6 can be self-hosted, so that might open up some possibilities, but this project will be stuck on MVC 5).
OK, here's a way to do it:
Spin up a web server in a method decorated with the [AssemblyInitialize] attribute (this method must be in a class in your test project decorated with the [TestClass] attribute).
[AssemblyInitialize]
public Initialize()
{
...
}
Stop the web server in a method decorated with the [AssemblyCleanup] attribute.
[AssemblyCleanup]
public Cleanup()
{
...
}
To start IIS Express you can just use Process.Start on IISExpress.exe, passing in the path and port arguments. (To stop it, you can simply kill the process you started). See the link in Fran's answer for an example.
The path argument should point to the folder containing your website project (the project folder, not the bin folder).
The port argument needs to be the same local port number used when you run the website locally (so if the URL in the browser window is http://localhost:57941 then the port number you need is 57941).
I'm not sure how you'd do this with just Selenium. Selenium is just automating browser processes. you might be able to write a script or you could use a testing framework like SpecFlow to start up a webserver before your test run.
http://www.radicalgeek.co.uk/Post/12/starting-up-iis-express-for-a-specflow-and-selenium-webdriver-test-run
Archived link in case the first one does not work: https://web.archive.org/web/20160927003518/http://www.radicalgeek.co.uk/Post/12/starting-up-iis-express-for-a-specflow-and-selenium-webdriver-test-run

Property injection on attributes not working from a unit test

During execution as an Asp.Net Mvc application, property injection by autofac works successfully, as documented here:
http://code.google.com/p/autofac/wiki/Mvc3Integration#Filter_Attribute_Property_Injection
If I carry this same logic through to a (nunit) unit test, the properties are not being injected on my custom attribute. Is there something specific in the mvc extensions that would cause this not to work from a unit test?
Thanks
Filter attribute property injection works as part of the MVC/ASP.NET pipeline, not as something available as a standalone feature.
You'll probably notice that the filters on an MVC controller don't actually execute during unit tests either. For example, put the HandleErrorAttribute on your controller action and throw an exception from that action in a unit test. Notice how the HandleErrorAttribute didn't get invoked to try to send you to the error view?
This is because in a unit test scenario, you're not in the MVC pipeline - you're testing controllers/actions as POCO (Plain Old CLR Objects). You won't get model binding, filters, HttpModules, or anything else that you'd normally see as part of real integration/execution.
That's not an error, that's by design. It's similar to the way you can unit test WCF service implementations and if you attach behaviors to them via your web.config you won't see those behaviors in the unit test. Your unit test isn't executing in the pipeline, it's executing only against the one class as a standalone entity.
If you need to test how the whole thing works together with filters and all - an integration test - you'll need to look into retrieving the content from a running version of your web application using browser automation or some other programmatic web client mechanism. For the pipeline to be in place, you have to actually be running in a real, full runtime, not in a standard/standalone unit test environment.
As far as whether it's OK to use DI in unit tests or not... that's more a personal preference. I use it in some of my tests, but when I do, I wire up mocks/stubs as the dependencies so I can control the interaction between my system under test and its dependencies. You don't need DI to do that. You could just construct all the fake dependencies manually and poke them in without any DI/IoC container at all. That said, in a unit test environment, you shouldn't be wiring up The Real Dependencies because then you're not testing your class as a unit - that's an integration test.
You should avoid using DI for unit testing. Unit testing is all about testing the functionalities of the a particular piece of code and not others. In your case if you are testing the custom attribute then you should set the dependencies directly without relying on any IoC container to do that.
Most of the cases the dependencies would be replaced by mock objects instead of the real ones.

Can we unit test View ('V') of MVC?

Duplicate: Unit Testing the Views?
Is there any way to unit test View?
I am sure that we can test Model & Controller but don't know how to unit test View?
Is that worth testing View?
You can enable compilation of MVC views. That helps a lot. Otherwise, I don't think it is worth it. After all, the there are only two things that you are interested in. Does view compile and do you get any exceptions (null, out of bounds exceptions, or similar)?
There are some folks who claim that you should not include any logic in view. Write helpers for anything. In that case, compilation is pretty much everything you'll want.
We decided to invest into WatiN testing. It tests views and it tests the whole app at the same time. Has some nice helpers, but requires constant maintainance.
Haven't views abandoned code behind now? So what are you going to test? If you are testing the controller, then you just need a succesful view result to show that the view works. Rather than going to the trouble of pre compiling views or whatever, this will start to drag any sizeable project down in terms of continuous integration, and build.
From what I have read (in Pro ASP.NET MVC Framework by Steven Sanderson), views are not considered worth testing. ASP.NET MVC viewes can be generated using various engines, e.g. the default lightweight ASPX, or for example http://www.stringtemplate.org/. For ASPX output you might run some HTML syntax checker tool, and for other view engines the fact that the views compile successfully should be a good enough test ;)
I do not see the point of unit testing the views, since they don't contain much logic. You can however to some integration testing/UI testing using a tool like WatiN.
Example of a test written in WatiN:
[Test]
public void SearchForWatiNOnGoogle()
{
using (IE ie = new IE("http://www.google.com"))
{
ie.TextField(Find.ByName("q")).TypeText("WatiN");
ie.Button(Find.ByName("btnG")).Click();
Assert.IsTrue(ie.ContainsText("WatiN"));
}
}
You should not try to test everything using tool like this. Select some key functionality of the application, and write test for them.
For those who do not see the value in testing views.... How can you be sure that the view has the right attributes on elements, or that it is bound correctly?
Many answer "at a higher level" (such as running the site and using tools such as selenium or equivalent).
However these techniques make it virtually impossible to prove that the source of the error is in the view itself and also require massive changes to the server side code so that the views can be rendered in a targeted manner.

Asp.net MVC View Testing?

With more and more code pushed to the Views in Asp.Net MVC (i.e. AJAX, JQuery, etc...), how do you maintain the 'testability'?
How do you test your Views?
How do you test your views with client-side jscript code?
How do you test your Views with Async behavior?
It seems that most examples on the testability of MVC deal with controllers. What about Views?
Selenium is a great tool for testing the front end of any web app. It is written in the browser's native language, JavaScript. Having the browser run the test framework code gives your tests the ability to expose browser incompatibility issues. It is free and open source.
Also see other free browser automation tools like ArtOfTest and WatiN. The Selenium stack can be a little complicated to set up.

Resources