How do I unit test a web forms site? It seems to me that as so much of it depends on state and user input it wouldn't be feasible.
If it's not feasible is there a valid automated alternative?
How do I unit test a web forms site? It seems to me that as so much of it depends on state and user input it wouldn't be feasible.
If it's not feasible is there a valid automated alternative?
Yes, you can. You just have to be careful to separate your concerns well. In short, you have to remove all your logic from the code-behind and put it into other classes.
There are two common ways to do this.
The simple way is to rethink all of your event handlers in terms of "What information does the system give me? What information do I need to populate on the page?" and then provide a service class which does that conversion.
In this case, the service layer should know very little about the nature of your presentation layer. You still have to take the data returned from the service and populate the correct components of the WebForm in your code-behind and this remains untested (at least by unit tests, you can still employ integration tests). But this is rarely where code goes wrong, it is much more likely to fail in the logic.
A more complicated, but more effective, way is to use the Model View Presenter pattern. When we tried that, we found that the Presenters quickly became very coupled to the framework and, the more we developed MVP, the more clear it was that MVP really wanted to be MVC but couldn't be.
That said, others have done this very successfully - there is even a webformsmvp framework available to remove the heavy lifting - so your mileage may vary.
Quite obviously, an entire web forms page is not a unit, and thus cannot be unit tested. However, there are some things you can do for automated tests:
I am sorry for missing the "unit" part of the question...
SeleniumHQ is your friend for tests from the front end. It is not a unit test, more like a black box testing. You still need to think of valid test cases...
Speaking from experience: Only if it's done right. By "right" I mean minimal code-behind and something like the above-mentioned Model-View-Presenter to make the Web Form "dumb". This usually proves to be very difficult with brownfield applications because they weren't designed with this in mind and it's a near-Herculean effort to refactor/rewrite pages to use it.
I find unit web tests are extremely useful, even if it's just to give a general idea of a regression bug or for new projects.
As far as state is concerned, you create your unit tests as you would with non-UI tests - they clear the database out at the start of the test and rebuild the database to contain nothing except the start state. Each unit test then encapsulates a single page, or usually a distinct task on a page.
http://watin.org/ is another web test tool but for C#/.NET. You write the tests as unit tests:
[Test]
public void SearchForWatiNOnGoogle()
{
using (var browser = new IE("http://www.google.com"))
{
browser.TextField(Find.ByName("q")).TypeText("WatiN");
browser.Button(Find.ByName("btnG")).Click();
Assert.IsTrue(browser.ContainsText("WatiN"));
}
}
It's currently IE based but has some experimental support for Firefox and Chrome. You can pretty much automate anything you would do in manual tests, including Javascript interaction.
You can't really unit test a web site, simply because web requests happen on a wire (or through a TCP stack). Thus, the tests do not fit the definition of "unit test", they would be, likely, end-to-end tests.
For those kinds of tests, you can use a suite like Selenium which runs a web browser behind the scenes. A word of warning though: usually this kind of testing is very difficult and unpredictable, as there are many moving parts!
More interestingly though, it worries me a bit why you would need to test web forms at all. Aren't you putting way too much logic in the code behind, and have an anemic business logic by any chance?
Over the past 5 years Jasmine has emerged as a key tool for front-end unit tests. It is often incorporated into automatic build testing with Node and npm
Per https://en.wikipedia.org/wiki/Jasmine_(JavaScript_testing_framework):
Jasmine is an open source testing framework for JavaScript.[2] It aims to run on any JavaScript-enabled platform, to not intrude on the application nor the IDE, and to have easy-to-read syntax. It is heavily influenced by other unit testing frameworks, such as ScrewUnit, JSSpec, JSpec, and RSpec.[3]
Despite all the mentions of javascript it can also be used for unit testing of a plain web form.
When developing an ASP.NET site we were able to run unit tests on:
It is possible to TDD all of this, depending on your architecture. The only thing you cannot unit test is the layout of the markup file.