How to unit test WinForms with Visual Studio 2013 Ultimate? - c#

I added from Tools | Extensions and Updates: NUnit Test Adapter, NUnit Test Generator, xUnit.net runner for Visual Studio 2012 and 2013, Unit Test Generator.
Only Unit Test Generator seems to give me a context menu item that allows me to right-click a form's class constructor and "Generate Unit Test". However, that context menu item does not appear when I right-click a method of a plain old class in the same project. That context method also does not appear if I try to generate unit tests for a button click or textbox selection, including if I try it from anywhere inside the code of the Form Designer code (e.g. this.button1.Click += new System.EventHandler(this.button1_Click);). Why is that?
Also, while "Generate Unit Test" gives me a choice of MSTest, NUnit and XUnit, only MSTest works. The other two choices create the new test project but not the test class and generate a long error messagebox:
No exports were found that match the constraint:
ContractName
NuGet.VisualStudio.IVsPackageInstallerServices
RequiredTypeIdentity
NuGet.VisualStudio.IVsPackageInstallerServices
Finally, the skeleton MSTest method generated shows no obvious way to access the form and its controls. The author of this article http://www.steveandrews.me/blog/2008/02/05/testing-the-winforms-ui, obviously using a different Visual Studio back in 2008, writes that the generated method includes code that helpfully provides access to the form:
`[TestMethod()]
[DeploymentItem("WindowsFormsApplication1.exe")]
public void InitializeComponentTest()
{
Form1_Accessor target = new Form1_Accessor(); // TODO: Initialize to an appropriate value
target.InitializeComponent();
Assert.Inconclusive("A method that does not return a value cannot be verified.");
}`
Now, with Visual Studio 2013 Ultimate and MSTest, all I get is:
[TestMethod()]
public void Form1Test()
{
throw new NotImplementedException();
}
I read elsewhere that one should use the MVVM pattern instead if one wants to test things like textbox selections and button clicks, etc but I want to know if there is a "proper" way to unit test classic WinForms from inside Visual Studio. (I'm obviously new to all this!)
Thank you

Unit testing private methods is a bad practice, as is making the classes internal and using the InternalsVisibleTo attribute so that you can test it.
Basically, if you have a private method, that method represents an implementation detail of your class -- what that method does is irrelevant to your testing efforts. What you should be testing is the public API of your class.
"Well, I want to test some logic that's buried deep in a private method, but it's really hard to pass data in to my public API that hits all of the logic in my private methods!", you might be saying. That is a common response to the advice I just gave, and there's an answer:
Logic that's hard to test via the public API is generally an indicator that your class is poorly designed. You'll want to start to decompose the class into multiple, smaller classes and test each of those classes through their public API.
Now, one last thing: You're trying to test Windows Forms. WinForms is ancient and does not make even a cursory attempt to guide you down the path of using modern patterns and practices, like separation of concerns. That means you generally have a lot of view logic mixed in with your business logic, which makes it harder to unit test. You can look into starting to implement the MVP pattern.

The Accessors that are used in there were deprecated and are not included in VS2012 onwards.
You cannot access privates any more.
What you can do is make your classes internal and use the InternalsVisibleTo Attribute to enable your unit test assembly to access them.

Related

How to do TDD in Visual Studio that separates production code from test code

In a typical Java IDE (say Intellij), working Test Driven Development (TDD) style mean a very efficient workflow and virtually no modifications or alternations are needed after you finish the code through the test.
Java projects, just as C# solutions, have various styles of separating production code from test code, but usually there are two directory structures in parallel
src
test
or the tests are separated by namespace in the src tree. And then endless variations on that theme.
Using something like Intellij I can create my "test class/method", start coding, generate objects on the fly, as I go, and they generally end up in the correct place, that is, where the production code is supposed to be. When I'm done, I'm done done. Tools and IDE's in the Java world support this 110%.
Now the experience Visual Studio (or actually the R# experience). Currently my (simplified) workflow for doing TDD in C# is something like this (using R#):
Create a test class in a test project
Create test method
Start coding.. generate classes, interfaces, etc as I go. I generate the code in the same file as the test-class as per R# default.
...
When I'm done I go to each class/interface/whatever and move the files into separate files matching their name (ctrl+enter action).
Go to solution explorer and drag-drop the classes from the test-project over to the production project.
I want to get rid of everything 4 & 5. And I would also like my classes to generate directly in the production project in step 3.
I've searched high and low for an extension to Visual Studio that can help me with this.
Question 1: How can I get more productive with TDD the way I do it today?
Question 2: Should I adopt another TDD workflow/structure that would ultimately provide me with a better TDD experience in Visual Studio? (this is an alternative question)
Remain unanswered
But please take the time to vote for this feature in Resharper https://youtrack.jetbrains.com/issue/RSRP-424370
You can remove steps 4 & 5 with Visual Studio using Generate Method Stub feature, the Resharper bit distracted me.
Create two projects:
Solution
| Project1
_ Quiz.cs
| UnitTestProject
_ UnitTestClassQuiz.cs
1. Create an empty class called Quiz in Project1.
2. Create a unit test in UnitTestClassQuiz.cs , eg:
using Project1;
private class UnitTestClassQuiz
{
[TestMethod]
public void ShouldReturnDivisibles()
{
//Arrange
Quiz q = new Quiz();
//Act
var actual = q.ReturnDivisibles(60)
At this point VS will have a squiggle red line under the 'ReturnDivisibles' function because its undeclared! Hover the mouse over this undeclared 'ReturnDivisibles' function and you will see a little blue underline/underscore, click on it and it will give you a context menu with the option to "Generate Method Stub".
When you generate the method stub a function will be created in the Quiz class in Project1, eg:
public object ReturnDivisibles(int p)
{
throw new NotImplementedException();
}

How to write unit tests around private methods

I am trying to unit test a class that has public and private methods and I want to unit test a particular method that has been set as private (protected abstract on the base). I cannot make the method public and I do not want to go through the full process to get this method tested, I am only concerned that the input argument to this method and the return meet an expectation.
I do not want to make the method public as this question highlights:
Making a private method public to unit test it...good idea?
My question would be, what are the various ways of testing private methods and which technique should I favour and why?
I have read this question (How do you unit test private methods?) but would like to know if the accepted answer is still the best answer or after years there is a better way.
If this question is considered a duplicate of How do you unit test private methods? I will add my comment there and ask for an update, please advise.
If you can't meaningfully test the private methods of a class via the public methods then that would suggest something is wrong with the design of the class. If it is hard to test the class so that you wish to break down the tests to test a subset of its functionality then I would suggest breaking the class into its logical pieces and testing those individually.
Perhaps you have an opportunity to refactor the code so that the private methods become the public methods of some other class(es). A good example is a class that schedules some work on a timer to be processed at a later time. The work method would likely be implemented as private method making it difficult to test in a simple way without scheduling a timer and waiting around for it to execute the work method. Not ideal in a test where execution times should be very quick. A simple way around this is to split the scheduling work code into two seperate classes. The private work method then becomes the public method of the Worker class making it very easy to test. Whilst splitting the scheduling and worker code means you will struggle to achieve 100% coverage, you will at least cover the work code. A way around the problem is to use something like Quartz.net for implementing the scheduler class so that you can unit test the scheduler quite easily and the worker code as well.
I have read this question (How do you unit test private methods?) but
would like to know if the accepted answer is still the best answer or
after years there is a better way.
I would avoid the accepted answer.
I can jump into a tirade about testing the public interface and not worrying about the internals, but that might not be realistic.
There are two immediate options I can see:
Reflection to see the method, sort of a hack, but at least you can get some sort of test going. This is also likely the easiest to get working quickly.
Abstract the private method behaviour using something like the Strategy pattern and inject the behaviour into the object itself (or have the object internally new up the relevant strategy manually). This separate strategy item can then be tested independently.
That said, you shouldn't find yourself in this situation very often. If you do, you need to take a step back and review how you are designing your classes and possibly review them with a view to making them more open and testable.
In VS 2005, 2008 and 2010, you may have private accessor. You right click on a private function, and select "Create private accessor" ...
In VS 2012, this feature had somehow gone. The only handy way is to use PrivateObject. You may check MSDN for examples of using PrivateObject.
Do you want to be able to call your private method in test and see how it works?
You can derive from your class and add public method that will call method you want to test. Very simple. Although I wouldn't advice testing private methods. I can't think of single reason to do it. I would love to see example that will change my mind.
Edit: Since this answer still gets some traffic I share this link. This blog post was created around 4 years after I posted my answer:
https://enterprisecraftsmanship.com/posts/unit-testing-private-methods/
Use reflection. If you don't want to mess with reflection yourself, then you can use Microsoft's PrivateObject class located in Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll. But there are problems in cooperating MSTest and NUnit - Using both MSTest and NUnit?
If you are using VS 2005 or above, use following steps
Open a source code file that contains a private method.
Right-click the private method, and select Create Unit Tests.
This displays the Create Unit Tests dialog box. In the visible tree structure, only check box for the private method is selected.
(Optional) In the Create Unit Tests dialog box, you can change the Output project. You can also click Settings to reconfigure the way unit tests are generated.
Click OK.
This creates a new file named VSCodeGenAccessors, which contains special accessor methods that retrieve values of private entities in the class being tested. You can see the new file displayed in Solution Explorer in the test project folder.
If your test project had no unit tests before this point, a source code file to house unit tests is also created. As with the file that contains private accessors, the file that contains unit tests is also visible in your test project in Solution Explorer.
Open the file that contains your unit tests and scroll to the test for the private method. Find the statements that are marked with // TODO: comments and complete them by following the directions in the comments. This helps the test produce more accurate results
For more information refer this
It looks that internally it uses reflection to call private method. But it works.
I actually came here for an answer to this question until I realized that I shouldn't be unit testing private methods. The reason for this, is because private methods are a piece in a process that is part of some larger logic.
Unit tests are intended to test against the interface of a class. The idea is that I am supposed to ensure quality control when using my class in the way that it is intended to. As a result, it's not useful to unit test a private method, simply because it will never be exposed to the consumer (whoever is implementing). You need to unit test against cases which the consumer can use your class.
If you find yourself with the absolute need to unit test something that is private, you might need to rethink the location of that method, or how your code is broken down. I've come to the conclusion that if I need to unit test a private method, 9/10 times it's a method that can be wrapped into a static utility class.

How to organize unit tests and do not make refactoring a nightmare?

My current way of organizing unit tests boils down to the following:
Each project has its own dedicated project with unit tests. For a project BusinessLayer, there is a BusinessLayer.UnitTests test project.
For each class I want to test, there is a separate test class in the test project placed within exactly the same folder structure and in exactly the same namespace as the class under test. For a class CustomerRepository from a namespace BusinessLayer.Repositories, there is a test class CustomerRepositoryTests in a namespace BusinessLayerUnitTests.Repositories.
Methods within each test class follow simple naming convention MethodName_Condition_ExpectedOutcome. So the class CustomerRepositoryTests that contains tests for a class CustomerRepository with a Get method defined looks like the following:
[TestFixture]
public class CustomerRepositoryTests
{
[Test]
public void Get_WhenX_ThenRecordIsReturned()
{
// ...
}
[Test]
public void Get_WhenY_ThenExceptionIsThrown()
{
// ...
}
}
This approach has served me quite well, because it makes locating tests for some piece of code really simple. On the opposite site, it makes code refactoring really more difficult then it should be:
When I decide to split one project into multiple smaller ones, I also need to split my test project.
When I want to change namespace of a class, I have to remember to change a namespace (and folder structure) of a test class as well.
When I change name of a method, I have to go through all tests and change the name there, as well. Sure, I can use Search & Replace, but that is not very reliable. In the end, I still need to check the changes manually.
Is there some clever way of organizing unit tests that would still allow me to locate tests for a specific code quickly and at the same time lend itself more towards refactoring?
Alternatively, is there some, uh, perhaps Visual Studio extension, that would allow me to somehow say that "hey, these tests are for that method, so when name of the method changes, please be so kind and change the tests as well"? To be honest, I am seriously considering to write something like that myself :)
After working a lot with tests, I've come to realize that (at least for me) having all those restrictions bring a lot of problems in the long run, rather than good things. So instead of using "Names" and conventions to determine that, we've started using code. Each project and each class can have any number of test projects and test classes. All the test code is organized based on what is being tested from a functionality perspective (or which requirement it implements, or which bug it reproduced, etc...). Then for finding the tests for a piece of code we do this:
[TestFixture]
public class MyFunctionalityTests
{
public IEnumerable<Type> TestedClasses()
{
// We can find the tests for a class, because the test cases references in some special method.
return new []{typeof(SomeTestedType), typeof(OtherTestedType)};
}
[Test]
public void TestRequirement23423432()
{
// ... test code.
this.TestingMethod(someObject.methodBeingTested); //We do something similar for methods if we want to track which methods are being tested (we usually don't)
// ...
}
}
We can use tools like resharper "usages" to find the test cases, etc... And when that's not enough, we do some magic by reflection and LINQ by loading all the test classes, and running something like allTestClasses.where(testClass => testClass.TestedClasses().FindSomeTestClasses());
You can also use the TearDown to gather information about which methods are tested by each method/class and do the same.
One way to keep class and test locations in sync when moving the code:
Move the code to a uniquely named temporary namespace
Search for references to that namespace in your tests to identify the tests that need to be moved
Move the tests to the proper new location
Once all references to the temporary namespace from tests are in the right place, then move the original code to its intended target
One strength of end-to-end or behavioral tests is the tests are grouped by requirement and not code, so you avoid the problem of keeping test locations in sync with the corresponding code.
Regarding VS extensions that associate code to tests, take a look at Visual Studio's Test Impact. It runs the tests under a profiler and creates a compact database that maps IL sequence points to unit tests. So in other words, when you change the code Visual Studio knows which tests need to be run.
One unit test project per project is the way to go. We have tried with a mega unit test project but this increased the compile time.
To help you refactor use a product like resharper or code rush.
Is there some clever way of organizing unit tests that would still
allow me to locate tests for a specific code quickly
Resharper have some good short cuts that allows you to search file or code
As you said for class CustomerRepository their is a test CustomerRepositoryTests
R# shortcut shows inpput box for what you find in you case you can just input CRT and it will show you all the files starting with name have first as Capital C then R and then T
It also allow you do search by wild cards such as CR* will show you the list of file CustomerRepository and CustomerRepositoryTests

C# : add Main methods in classes to quicktest

I am more of a Java guy, and usually the convenient thing with Java is that you can just add a Main method on the fly in various classes to then execute them individually with a raw right-click -> run.
Right now, I have an ASP.NET application, and I am writing a package inside of it that I need to test individually. A little Main function, added on the fly to print things in the console, as described above, is what I would like to have. I tried simply adding one but of course Visual Studio doesn't notice it. At the moment I develop the package in anoher console application to bypass the trouble..
What would you suggest if you see what I mean ?
The common way I do single class tests is by using a unit test framework like nUnit.
This allows me to instantiate and test a class in isolation.
If the class has dependencies, I may also use a mocking framework to mock those out.
A good suite of Unit Tests would probably go a long way to doing what you need.

Getting Started with Unit Testing in C# with Visual Studio

I know Visual Studio offers some Unit Testing goodies. How do I use them, how do you use them? What should I know about unit testing (assume I know nothing).
This question is similar but it does not address what Visual Studio can do, please do not mark this as a duplicate because of that. Posted as Community Wiki because I'm not trying to be a rep whore.
Easily the most significant difference is that the MSTest support is built in to Visual Studio and provides unit testing, code coverage and mocking support directly. In order to do the same types of things in the external (third-party) unit test frameworks generally requires multiple frameworks (a unit testing framework and a mocking framework) and other tools to do code coverage analysis.
The easist way to use the MSTest unit testing tools is to open the file you want to create unit tests for, right click in the editor window and choose the "Create Unit Tests..." menu from the context menu. I prefer putting my unit tests in a separate project, but that's just personal perference. Doing this will create a sort of "template" test class, which will contain test methods to allow you to test each of the functions and properties of your class. At that point, you need to determine what it means for the test to pass or fail (in other words, determine what should happen given a certain set of inputs).
Generally, you end up writing tests that look similar to this:
string stringVal = "This";
Assert.IsTrue(stringVal.Length == 4);
This says that for the varaible named stringVal, the Length property should be equal to 4 after the assignment.
The resources listed in the other thread should provide a good starting point to understandng what unit testing is in general.
The unit testing structure in VS is similar to NUnit in it's usage. One interesting (and useful) feature of it does differ from NUnit significantly. VS unit testing can be used with code that was not written with unit testing in mind.
You can build a unit testing framework after an application is written because the test structure allows you to externally reference method calls and use ramp-up and tear-down code to prep the test invironment. For example: If you have a method within a class that uses resources that are external to the method, you can create them in the ramp-up class (which VS creates for you) and then test it in the unit test class (also created for you by VS). When the test finishes, the tear-down class (yet again...provided for you by VS) will release resources and clean up. This entire process exists outside of your application thus does not interfere with the code base.
The VS unit testing framework is actually a very well implemented and easy to use. Best of all, you can use it with an application that was not designed with unit testing in mind (something that is not easy with NUnit).
First thing I would do is download a copy of TestDriven.Net to use as a test runner. This will add a right-click menu that will let you run individual tests by right-clicking in the test method and selecting Run Test(s). This also works for all tests in a class (right-click in class, but outside a method), a namespace (right click on project or in namespace outside a class), or a entire solution (right-click on solution). It also adds the ability to run tests with coverage (built-in or nCover) or the debugger from the same right-click menu.
As far as setting up tests, generally I stick with the one test project per project and one test class per class under test. Sometimes I will create test classes for aspects that run across a lot of classes, but not usually. The typical way I create them is to first create the skeleton of the class -- no properties, no constructor, but with the first method that I want to test. This method simply throws an NotImplementedException.
Once the class skeleton is created, I use the right-click Create Unit Tests in the method under test. This brins up a dialog that lets you create a new test project or select an existing one. I create, and name appropriately, a new test project and have the wizard create the classes. Once this is done you may want to also create the private accessor functions for the class in the test project as well. Sometimes these need to be updated (recreated) if your class changes substantially.
Now you have a test project and your first test. Start by modifying the test to define a desired behavior of the method. Write enough code to (just barely) pass the test. continue on with writing tests/writing codes, specifying more behavior for the method until all of the behavior for the method is defined. Then move onto the next method or class as appropriate until you have enough code to complete the feature that you are working on.
You can add more and different types of tests as required. You can also set up your source code control to require that some or all tests pass before check in.

Categories