1

There is need to create small scale winform applications for private use by my company for interaction with our database. Period. I know that .NET MVC has a very mature unit testing framework for the MVC pattern as I want to do TDD.

Thus, is it possible to use NUnit or some other easy/mature unit testing framework (EDIT: Based on my experience with ASP.NET) with the following tutorial given here? I have googled and checked my technical book library, and there is a distinct lack of documentation for how to do effective unit testing for winforms. Thus, I am turning to this forum hoping individuals can share their domain knowledge with me.

The most I have found has recommended the MVC pattern (which I agree with), but not how to address specific issues with the winform. For example, how do I test a button click and subsequent action by that button?

I plan on using C# VS13 .NET 4.5. I am excited to join this resource and will contribute rep to all who answer my inquiry. Thanks.

tereško
  • 58,060
  • 25
  • 98
  • 150
hlyates
  • 1,279
  • 3
  • 22
  • 44
  • 3
    ".NET MVC has a very mature unit testing framework"? - note clear what you mean. (Assuming MVC == ASP.Net MVC) .Net does not have any specific unit testing framework for ASP.Net MVC... There is generic testing framework as part of Visual Studio, but it has nothing specific to ASP.Net MVC or pretty much any of particular stack (WPF/WinForms/WebForms...). – Alexei Levenkov Sep 04 '14 at 15:59
  • 2
    Winforms go nicely with the MVP pattern. Decouple your presenters from dependencies and test the presenters. – Neil Smith Sep 04 '14 at 15:59
  • 1
    someone else seems to have had somewhat a similar question here: http://stackoverflow.com/questions/128086/how-can-i-write-a-unit-test-for-a-controller-class-that-uses-winforms-for-views?rq=1 – jbutler483 Sep 04 '14 at 16:07
  • @Smith.h.Neil: he knows that because this is what the tutorial from his link is all about. He just don't know how to "decouple [...] and test presenters". See my answer. – Wiktor Zychla Sep 04 '14 at 16:09
  • Use WPF instead with the MVVM pattern. You can test your ViewModels and Models and don't even need to test the View if you don't use any code behind – reggaeguitar Sep 04 '14 at 16:14
  • I edited my question @AlexeiLevenkov to address the ambiguity. I appreciate that link jbutler483, they asked in a different way, but it helps. Which leads us exactly to what WiktorZychla was saying as well. I think the answer is yes. Using interfaces to describe views. – hlyates Sep 04 '14 at 16:16

3 Answers3

3

As you have probably noticed, the idea there is to have your view described with an interface.

Thus, the controller doesn't really need a window, it needs a class implementing the interface.

And thus, you could have yet another, auto-mocked or manual implementation of the view interface that doesn't involve the WinForms subsystem but rather, exposes the data to write your assertios.

Having your stub view, you just write a script against it. You expose some methods from the class that allow you to automate the interaction:

public class ViewStub : IView
{
    // implement the view interface as it is but also
    // an extra stuff to let you automate this in your unit tests

    public void RaiseButtonClick()
    {
        this.controller.DoTheButtonClickStuff();
    }
}

Then your test becomes (I follow the convention from the tutorial)

ViewStub form = new ViewStub();
IModel mdl = new IncModel();
IController cnt = new IncController(view,mdl);

form.RaiseButtonClick();
Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • I think this would work with NUnit, given how you worded it. For example, let's say the buttonclick increments a counter. I could do the script above and then assert that the counter increased by 1, or whatever. Yes? If so, starting to get super excited. This could work. :) – hlyates Sep 04 '14 at 16:18
2

Unit Testing a GUI is something that is independent of the GUI library used. The answer to the general case answers your case as well: How can I unit test a GUI?

Unit testing a GUI is done by minimizing the footprint of classes that do depend on your GUI framework. Then the classes that still depend on the GUI framework are not unit tested (which is not at all the same as "are not tested"). Those classes are the "View" in patterns like MVP, MVC, MVVM.

Conclusion: Every good .Net Unit Testing framework is a good WinForms Unit Testing framework. One example of such a framework is NUnit, which you mentioned in your question.

Community
  • 1
  • 1
Peter
  • 5,608
  • 1
  • 24
  • 43
-3

Unit testing is not inteded for UI. Of course you can do it, but I don' recommend it for few reasons: You cannot unit test DPI changes, multiple screen, how your program acts in different window states or what happens if user moves with tabulator between your controls. Unit testing UI will only give you false safety.

Use UI automation tools to test UI automatically if you want to, but leave the unit testing out of it. You can keep the UI layer thin as possible and this is also a good design practice. You can use unit testing for other classes which are used in your winforms app.

Panu Oksala
  • 3,245
  • 1
  • 18
  • 28
  • Unit Testing is not supposed to give you a 100% feeling of safety, but to verify basic functionality and to rapidly find problems. There's nothing wrong with wanting to unit test a UI. The problem is that it's usually difficult to do so. – mason Sep 04 '14 at 16:12
  • 1
    @Mino: What you said is not true. MVC (or MVP as some call it) or MVVM are architecture patterns designed for unit testing ui applications. It is not that you test actual user interface but rather, how the application behaves when a user operates it. What you suggest, on the other hand, is also important and somewhat complementary. It's just like white/black-box testing. This is why I downvote, your answer sounds like you'd discourage him from doing something perfectly valid. – Wiktor Zychla Sep 04 '14 at 16:13
  • I know unit test wont cover anything.There is a link to Michael Feathers document in third comment of question and I think its also trying to say that you should not unit test UI layer. It wont hurt you much if you leave a thin UI layer without tests. If you are coding with TDD style and start tests from UI layer. I think it will guide you easily to write code directly into UI layer. Also wiring up UI can be pain in an ass. Doing something that is slow, just to test few method calls is waste of time in my opinion. Use tools which are designed for certain task,dont only use tools that you know. – Panu Oksala Sep 04 '14 at 16:27