views:

2056

answers:

5

We're working on a project here in Visual Studio 2008. We're using the built-in testing suite provided with it (the Microsoft.VisualStudio.TestTools.UnitTesting namespace). It turns out, that much to our chagrin, a great deal of complexity (and therefore errors) have wound up coded into our UI layer. While our unit tests do a decent job of covering our business layer, our UI layer is a constant source of irritation. We'd ideally like to unit-test that, as well. Does anyone know of a good "Microsoft-compatible" way of doing that in visual studio? Will it introduce some sort of conflict to 'mix' unit testing frameworks like nUnitForms with the Microsoft stuff? Are there any obvious bear traps I should be aware of with unit-testing forms?

+4  A: 

You would need to refactor the UI so that UI does not need any unit testing. UI should contain minimum or no business logic. There are many patterns that deal with this issue. Martin Fowler has a very good article that explains a lot about these patterns: http://martinfowler.com/eaaDev/uiArchs.html

There is a small chapter in the Refactoring book by Martin Fowler that talks about refactoring the non testable UI. You could also read Working Effectively With Legacy Code.

Note: There are tool that could be used to automate the UI testing. SilkTest comes to my mind. But I would not use them if possible.

StackUnderflow
Completely agree. Spend the time getting your logic out of your UI and unit test your Business layer. That way you can plug your Business layer into a web app or a WPF app with no changes to your unit tests. UI testing should be done by humans testing for un-quantifiable things (i.e. looks better)
jcollum
The thing is that a lot of the UI logic is very much about the UI, not even the business. Its stuff like "Prompt the user to save when the record is dirty and they change screens." and "Make sure that the user has filled out all the required data entry fields when they press OK" and other controls
GWLlosa
check out HumbleDialog and PassiveView in the article I suggested.. it would take all the UI logic out in presenter and UI will be very dumb and easy to test by just viewing
StackUnderflow
Which comes first, the chicken or the egg? In order to refactor, you need to have a test so you can compare results before and after refactoring. Therefore, if you have a legacy UI that has domain/repository logic, the ONLY place to do the testing is in the UI.
awhite
A: 

I use the Passive View architecture as detailed here http://martinfowler.com/eaaDev/PassiveScreen.html

Basically move all your code in the forms to a separate class called the xxxUI. The form then implements a IxxxUI interface and expose anything that the xxxUI class needs. You can probably simplify things and aggregate dealing with several controls into one method.

The flow then goes The USER click on a button. The button calls a method on the corresponding UI class. Passing any needed parameters. The UI Class method modifies the model. Then using the interface updates the UI.

For unit testing you have test or dummy classes implement the interfaces and register themselves with the UI Classes. You can have these test classes fire any type of input and respond accordingly. Typically I have sequence lists that do thing in a precise order. (Tap A, click this, scroll that, then Type B, etc).

RS Conley
A: 

Check out Jeremy D. Miller's WIP Presentation Patterns wiki page for refactoring inspiration :)

Miller is writing a book, and it looks like it's going to be a must-have for this sort of thing.

Mark Simpson
+1  A: 

This is all well and good for regular application unit testing ... but if you are building user controls that need unit tests for the control behaviors and states, it needs a unit test framework too. NUnitForms might be the answer for you - personally I need to check it out myself.

Roger
A: 

I've used NUnitForms when it comes to testing my own UI controls with good results! I would agree with the others on refactoring if you are using standard (or well tested) UI controls.

If the focus is on testing the actual controls I would use NUnitForms as it can be extended to support your new controls. Anyhow if you're not to involve any manual testing you will need a lib that can do "image based" analysis of the displayed end result.

I've tried TestComplete for this but I though it to be a bit too pricey since I could code a similar lib for just the image comparison in c#. So my plan would be to test the controls separately and then refactor the UI as mentioned my the others.

Henrik