Unit Testing for Winforms using MVC pattern? - c#

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.

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();

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.

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.

Related

MVVM Unit Testing

I have developed an application in WPF using MVVM because of the added benefits of seperation and test ability. However I am trying to write some unit tests as part of this but am confused about what to test. I know how to write the unit tests, hovever am unsure of what should I be testing in the view model, which is made up of my properties for data bindings and methods for some logic.
Furthermore most of my view model methods are private because they only need to be accessed from inside of the view model so they cannot be simply tested via unit tests like a public method would be. This results in being able to test very little of the view model which opposes the supposed value of MVVM in concerns to testing and from a quality POV is disadvantageous as I have to rely on manual tests to prove the functionality of my code.
I might be wrong and am new to using MVVM but any help would be appreciated on how to go about this.
When I write WPF applications I focus my testing on the models.
I test view-models by calling commands and setting properties like the user would do by using the user interface. For trivial view models that just wrap a model one-to-one or call a service with 4 lines of code I don't write any initial tests.
As soon as I find something that doesn't work as expected when running the application I go back and write a test for that particular use case. That initial "bug" usually shows what was tricky to implement in that particular view model and is a good starting point to write more tests and continue development in a more test driven fashion.
You can test the same things that the user can do on your UI.
By definition those things will be public, since the view will binding to them.
eg. Say you have a Widgets collection, and an AddWidgetCommand. You can test that executing the command will add a widget to the collection.

Retrofit unit tests to large solution, IOC, Moq

I am in the process of retrofitting unit tests for a asp.net solution written in VB.Net and c#.
The unit tests need to verify the current functionality and act as a check for future breaking changes.
The solution comprises of:
1 MVC web project
written in vb.net (don't ask, it's a legacy thing)
10 other supporting projects each containing logically grouped functionality
written in C#, each project contains repositories and DAL
All the classes are tightly coupled as there is no inversion of control (IOC) implemented anywhere, yet.
currently to test a controller there is the following stack:
controller
repository
dal
logging
First question, to unit test this correctly would I setup 1 test project and run all tests from it, or should I setup 1 test project for each project to test the functionality of that DLL only?
Second question, do I need to implement IOC to be able to use MOQ?
Third question, is it even possible to refactor IOC into a huge solution like this?
Forth question, what other options are available to get this done asap?
I am in the process of retrofitting unit tests for a asp.net solution written in VB.Net and c#. The unit tests need to verify the current functionality and act as a check for future breaking changes.
When working with a large code base that doesn't have unit tests and hasn't been written with testing in mind, there is a good chance that in order to write a useful set of unit tests you will have to modify the code, hence you're going to be triggering the event that you're planning on writing the unit tests to support. This is obviously risky, but may not be any riskier than what you're already doing on a day to day basis.
There are a number of approaches that you could take (and there's a good chance that this question will be closed as too broad). One approach is to create a good set of integration tests ensure that the core functionality is working. These tests won't be as fast to run as unit tests, but they will be further decoupled from the legacy code base. This will give you a good safety net for any changes that you need to make as part of introducing unit testing.
If you have an appropriate version of visual studio, then you may also be able to use shims (or if you have funds, typemock may be an option) to isolate elements of your application when writing your initial tests. So, you could for example create shims of your dal to isolate the rest of your code from the db.
First question, to unit test this correctly would i setup 1 test project and run all tests from it, or should i setup 1 test project for each project to test the functionality of that dll only?
Personally, I prefer think of each assembly as a testable unit, so I tend to create at least one test project for each assembly containing production code. Whether or not that makes sense though, depends a bit on what's contained in each of the assemblies... I'd also tend to have at least one test project for integration tests of the top level project.
Second question, do i need to implement IOC to be able to use MOQ?
The short answer is no, but it depends what your classes do. If you want to test using Moq, then it's certainly easier to do so if your classes support dependency injection, although you don't need to use an IOC container to achieve this. Hand rolled injection either through constructors like below, or through properties can form a bridge to allow testing stubs to be injected.
public SomeConstructor(ISomeDependency someDependency = null) {
if(null == someDependency) {
someDependency = new SomeDependency();
}
_someDependency = someDependency;
}
Third question, is it even possible refactor IOC into a huge solution like this?
Yes it's possible. The bigger question is it worth it? You appear to be suggesting a big bang approach to the migration. If you have a team of developers that don't have much experience in this area, this seems awfully risky. A safer approach might be to target a specific area of the application and migrate that section. If your assemblies are discrete then they should form fairly easy split points in your application. Learn what works and what doesn't, along with what benefits and unexpected pain you're feeling. Use that to inform your decision about how and when to migrate the rest of the code.
Forth question, what other options are available to get this done asap?
As I've said above, I'm not sure that ASAP is really the right approach to take. Working towards unit-testing can be done as a slow migration, adding tests as you actually change the code due to business requirements. This helps to ensure that testers are also allocated to catch any errors that you introduce as part of the refactoring that might need to take place to support the testing.

How to do BDD in a winforms app

I have a scenerio where I have to get some data from the DB and display it in a Grid View in a Win forms app. I have written a unit test for Presenter mocking my repository and view. The test checks that the presenter calls the GetData() method of the repository and then calls the Bind(data) method of the view.
I have also another Integration test for the repository that verifies that if there is some data in the DB it is returned by the repository.
Now comes the part of testing my view. I can think of no way to test my form and check if it indeed binds data to the Grid view but that is a separate question.
My question is that if I wanted to test the above scenario in BDD style then in Win forms there is no way for me to test that when I call a method of the presenter is the Grid View filled with the correct data. Does that mean that I can not do BDD on Win forms as I cannot verify the complete behaviour without mocking the view. If we mock the view then the entire concept of BDD is lost because one key player that is involved in the completion of the scenario is mocked and not real.
It is really confusing for me and don't know if anyone else out there has had similar question in their mind ever.
Yes it is possible to use BDD when creating a winform application.
TestStack have a framework called White. Quoting their website:
White is a framework for automating rich client applications based on
Win32, WinForms, WPF, Silverlight and SWT (Java) platforms. It is .NET
based and does not require the use of any proprietary scripting
languages.
As you are using C# I also strongly recommend you use SpecFlow for your behaviour-driven development; it allows you to define feature and scenarios for your application in a technology agnostic format and creates boilerplate code to aid you in your BDD process.
Here is a good article which works through an example using Specflow for BDD and White for winform automation.

c# webforms testing strategy

I wondered if anyone had links or comments on strategy as regards to testing a webforms application, I am referring specifically to automated testing practices, and unit testing.
My current strategy has been to separate business logic into a separate DLL that can be Unit tested on a class by class basis. However when it comes to testing the web Forms themselves using code UI tests, it appears I should be running two instances of visual studio 2010, one for the application and the other in order to run the created UI tests.
I found this link:
Testing ASP.NET webforms applications
However while this link was interesting it does not answer my question with regard to a strategy on a green fields project.
Although MVC3 would solve some of this, part of my reason for sticking with webforms is that I am slowly migrating aspects of a legacy system and to start from scratch on everything, when I can migrate strategic parts does not make sense.
Any links comments or observations would be welcome. Thanks.
1 You can try with Selenium if you want just test your interfaces
http://seleniumhq.org/
2 On functionnal subject (Code behind) It's very difficult to test because you must mock your pipeline, when i compare to MVC.
So for example you can mock HttpContextBase
var mock = new Mock<HttpContextBase>();

Firing UI control events from a Unit Test

As a beginner to TDD I am trying to write a test that assumes a property has had its value changed on a PropertyGrid (C#, WinForms, .NET 3.5).
Changing a property on an object in a property grid does not fire the event (fair enough, as it's a UI raised event, so I can see why changing the owned object may be invisible to it).
I also had the same issue with getting an AfterSelect on a TreeView to fire when changing the SelectedNode property.
I could have a function that my unit test can call that simulates the code a UI event would fire, but that would be cluttering up my code, and unless I make it public, I would have to write all my tests in the same project, or even class, of the objects I am testing (again, I see this as clutter). This seems ugly to me, and would suffer from maintainability problems.
Is there a convention to do this sort of UI based unit-testing
To unit test your code you will need to mock up an object of the UI interface element. There are many tools you can use to do this, and I can't recommend one over another. There's a good comparison between MoQ and Rhino Mocks here at Phil Haack's blog that I've found useful and might be useful to you.
Anothing thing to consider if you're using TDD is creating an interface to your views will assist in the TDD process. There is a design model for this (probably more than one, but this is one I use) called Model View Presenter (now split into Passive View and Supervisor Controller). Following one of these will make your code behind far more testable in the future.
Also, bear in mind that testing the UI itself cannot be done through unit testing. A test automation tool as already suggested in another answer will be appropriate for this, but not for unit testing your code.
Microsoft has UI Automation built into the .Net Framework. You may be able to use this to simulate a user utilising your software in the normal way.
There is an MSDN article "Using UI Automation for Automated Testing which is a good starting point.
One option I would recommend for its simplicty is to have your UI just call a helper class or method on the firing of the event and unit test that. Make sure it (your event handler in the UI) has as little logic as possible and then from there I'm sure you'll know what to do.
It can be pretty difficult to reach 100% coverage in your unit tests. By difficult I mean of course inefficient. Even once you get good at something like that it will, in my opinion, probably add more complexity to your code base than your unit test would merit. If you're not sure how to get your logic segmented into a separate class or method, that's another question I would love to help with.
I'll be interested to see what other techniques people have to work with this kind of issue.

Categories