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.
Related
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.
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.
this post is meant to have a list of suggestions on MVVM approach... What tools do you use, what do you do to speed up development, how do you maintain your application, any special ways of finding defects in this design pattern......
here is what I do:
So first i create my model/db with EF.
Then I create Views (either user controls or windows) with their respective viewmodel. I usually place the viewmodel in the same location as my view. But while starting the name of my view with "UC-name", I call my viewmodel just "name-model".
In my viewmodel I implement InotifyPropertyChanged
in my xaml view I have a resource of my viewmodel, and bind my grids/controls via the itemsource to the staticresource.
I try to do a lot of front end logic with triggers and styles and also place some code in the xaml.cs file if it regards logic for behaviour of my controls.
I can reach my viewmodel from my view (xaml + xaml.cs).
for communiation between viewmodels I use MVVM lights.
that's pretty much it.
Things I'm thinking about
I'm thinking of using T4 templates for generating viewmodel/view. What do you guys think of this. is this worth it?
when using MVVM light Messenger, we get a subscription based communication, and sometimes I find it hard to track what has changed in my DataContext. Any suggestions on this?
any other improvements or suggestions are more than welcome !
Answering first question regarding View/ViewModel generation I think for CRUD cases it makes sense to use some tools, otherwise it won't be that beneficial.
Pretty nice basic scaffolding implementation example you can find here: WPF CRUD Generator. Also WPF solution by DevExpress looks really promising.
There are at least couple Codeplex projects addressing View/ViewModel generation:
WPF Scaffolder
ViewModel Tool by Clarius
But I am quite pessimistic about T4 for such scenarios. I think writing and polishing own T4's will take you much more time than adoption of existing tools.
Regarding MVVMLight messenger I can say that it will take you some time to get used to it. And as soon as you will understand difference between "regular" and message driven MVVM you'll be able to use it in most efficient way. Very nice article about messenger is Messenger and View Services in MVVM. And want to add a really important quote from there:
A Word of Caution About Messenger
Messenger is a powerful component that can greatly facilitate the task
of communication, but it also makes the code more difficult to debug
because it is not always clear at first sight which objects are
receiving a message. Use with care!
I'm very much a proponent of Domain-Driven Development (DDD). First I have the designer write specifications, roughly adhering to the methodologies in Behavior-Driven Development (BDD). This then forms the basis of unit tests for Test-Driven Development (TDD), for which I use NUnit. For the domain layer itself I start with an Anemic Domain Model i.e. entity classes containing mostly properties and virtually no methods; there are plenty of arguments both for and against this but personally I find it works well. Coupled with this is the Business Logic Layer (BLL) which knows only about the domain entities.
For the Data Access Layer (DAL) I prefer NHibernate, it supports all the usual things you would expect like lazy loading and repository management etc but particularly important is the Object Relational Mapping (ORM) i.e. the bit that translates between your domain entities and the underlying database representation.
One of the problems with NHibernate, in my opinion, is that it uses XML files to do the mapping for the ORM. This means two things: first is that any errors you introduce won't get picked up until run-time. Secondly it's not really a proper "solution" to ORM at all, instead of writing mapping classes you just wind up writing XML files. Both of these problems can be solved by using Fluent. Fluent solves the first problem by replacing XML files with C# files, so your mapping declarations are now done in code which will usually pick up errors at compile-time. It solves the second problem by providing an auto-mapper, which looks at your entities and generates the necessary mapping files automatically. This can be manually overridden if and where needed, although in practice I find I seldom need to. Since the auto-mapper uses reflection is does tend to be a bit slow but it can be run in an offline utility and then saved to a configuration file that is loaded at run-time for near-instant start-up; the same utility can also be used to create your database automatically. I've used this tech with MySql, MS Server and MS Server CE...they've all worked fine.
On the other side of the tier is your view model. I've seen a lot of projects create an almost 1:1 mapping of domain entities to view model classes, I may infuriate MVVM purists by saying this but I really don't see the point in doing all that extra work for something that isn't really needed. NHibernate allows you to provide proxies for the classes it creates, using Castle Dynamic Proxy you can set an intercepter to your NHibernate session factory that automatically injects INotifyPropertyChanged notification to all of your entity properties so that they work with the WPF binding mechanism. Another product, uNhAddIns, allows you to replace any lists with an ObservableCollection in order to get INotifyCollectionChanged support (for reasons I won't go into you can't just put an ObservableCollection into your entities without it seriously affecting performance).
If you're designing and building your application properly using technologies like these and fully unit-testing along the way then you're going to need some way of handling Inversion of Control (IoC) so that you aren't passing object references around all over the place, and for that you'll need a dependency injection framework. My personal preference is Ninject but Unity is pretty good too. Dependency injection is particularly important for good database session management (so that all relevant objects reference the same session), a good rule is one session per WPF form or one per web request.
There are lots of other little things I use to make life easier (MVVM Lite, log4net, Moq for mocking objects for unit testing etc) but this is my core architecture. It takes a while to set up but once you've got it all going you can build fully functional database applications in literally minutes without any of the headaches traditionally associated with layer management in tiered enterprise applications...you just create your domain entities and then start coding for them. Your schema is created automatically, your database is created automatically, you can use your entity classes to fill your database for immediate stress testing and you have full WPF support without having to pollute your entity classes with code or attributes not actually related to the domain. And since all development is driven by anemic domain entities your data is already in the perfect format for serialization into html/ajax/soap etc when you want to give your app web capablities.
You'll notice that I haven't discussed the presentation/XAML layer, mainly because that part is now straightforward. Using a decent architecture you can actually create a fully working and tested application that then only needs pure XAML added to turn it into a releasable product.
I'm trying to improve the automated testing in my application, but am unsure of the best way to proceed.
My app gathers data from multiple forms, recodes it and stores it in a database. I have created a pretty complex SQL view, which flattens the structure out, so it can be imported into a stats package (SPSS).
My concern is that the view is complex, and I want to automate some tests around it.
Currently I have some functional tests, which create a complete form objects model, and sends it into the application. I then retrieve the view from the database, and use reflection to test that the retrieved view fields match the original data.
The problem is that this is very manual and heavy, my fixtures are lengthy, and it is cumbersome to add new scenarios (i.e. various parts of the model incomplete).
Does anyone have any advice on how I could improve my test strategy? Tips tricks all welcome!
Thanks!
DbFit is perfect for this. DbFit is an extension of FitNesse which maybe you are already using since you spoke of using "fixtures". In any case, DbFit makes it really easy to set up a test where you can seed some data, run the View, compare the expected results, and then it will automatically rollback the data that you just seeded for the test. And it is very easy to update as you add more fields to the View. AND it requires no additional objects in your DB like some other SQL "unit" testing suites.
You can find more info on using DbFit at:
http://benilovj.github.com/dbfit
http://groups.google.com/group/dbfit
And here is a tutorial that I wrote for it that explains the basic options:
http://www.sqlservercentral.com/articles/Testing/64636/
This is a very difficult question to answer. It almost sounds to me like You want to make a single test that tests all in one go.
First, Your app should be constructed, so each functionality is isolated in its own class, thereby making it easy to test AND easy to replace by stubs when testing other things. Dependencies on other functions should be injected (Dependency Injection).
Second, you should use the same technique for external systems like database connections and SPSS file writers. This involves wrapping such functionality so these dependencies also can be injected, and thus replaced by stubs when testing other aspects of your app.
Third, be aware that if tests are hard to write, 99,99% of the time this indicates that your design is not as strong as it could be.
Regards,
Morten
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.