Reputation: 24433
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?
Upvotes: 12
Views: 15531
Reputation: 124
For Windows 10, Microsoft now recommends Appium with WinAppDriver. VS 2019 will be the last version containing Microsoft Coded UI.
https://learn.microsoft.com/en-us/visualstudio/test/use-ui-automation-to-test-your-code?view=vs-2019
Upvotes: 1
Reputation: 3911
You should use Microsoft Coded UI to test the UI layer. This involves writing (or recording) tests that mimic actions that a user would perform and writing assert statements to ensure that the correct output is achieved.
Of course, this is arguable not unit testing, because it is difficult to create actions from the front end that test a single unit of work and is not a replacement for other unit testing. I agree also that the front end business logic should be a thin as possible. However, this will fill any gaps where your unit tests do not cover. Hopefully only small units of work will be not covered by your unit tests, so that the coded UI tests will catch the remaining untested units.
Coded UI comes built in with the latest versions of Visual Studio Premium. I suggest that you do not just use the record functionality, but instead learn how to write the tests yourself as this gives you greater flexibility.
Upvotes: 0
Reputation: 2351
It's quite easy to test Winforms with ApprovalTests (www.approvaltests.com or nuget approval tests) and they are compatible with MsTest as well as Nunit.
There's a video here of how to do it: https://www.youtube.com/watch?v=hKeKBjoSfJ8
But the process is simple. 1) create the form you want to test in the state you want it verified. 2) call WinFormApprovals.Verify(form)
ApprovalTests uses the golden master paradigm to screen capture the result. if you like it simply rename the file to .approved and the test will pass.
The great thing about this for refactoring existing code is you don't even have to worry about what the result is, since you are only concerned that you are not changing it.
Upvotes: 1
Reputation: 97
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.
Upvotes: 0
Reputation:
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.
Upvotes: 3
Reputation: 23365
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.
Upvotes: 0
Reputation: 7196
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).
Upvotes: 2
Reputation: 25408
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.
Upvotes: 5