dotnet thoughts 

a dotnet developer's technical blog

How to unit test internal classes in .net

Often we used to isolate our classes using internal access modifier, in ideal scenario it doesn’t require to write unit tests for internal classes. But sometimes we require to do  test internal classes. We can do it using two ways

  1. Using InternalsVisibleTo attribute : This attribute helps to expose internal classes of an assembly to specified assembly. You need to put this attribute in the AssemblyInfo.cs class.
    [assembly: InternalsVisibleTo("SampleLib.Test")]
    

    If your production assembly is signed, you need to sign the test assembly as well, and also need to specify the PublicKey in the attribute. Like the following

    [assembly: InternalsVisibleTo
    ("SampleLib.Test, PublicKey=002400000480000094" +
                                  "0000000602000000240000525341310004000" +
                                  "001000100bf8c25fcd44838d87e245ab35bf7" +
                                  "3ba2615707feea295709559b3de903fb95a93" +
                                  "3d2729967c3184a97d7b84c7547cd87e435b5" +
                                  "6bdf8621bcb62b59c00c88bd83aa62c4fcdd4" +
                                  "712da72eec2533dc00f8529c3a0bbb4103282" +
                                  "f0d894d5f34e9f0103c473dce9f4b457a5dee" +
                                  "fd8f920d8681ed6dfcb0a81e96bd9b176525a" +
                                  "26e0b3")]
    

    You can get the public key from assembly using StrongName tool, like the following command : sn -Tp SampleLib

  2. Using Add existing file and link file option : You can link any number of files between projects. Right click on the Project, Add existing File, in the browse dialog, select the file, and select Add as link option from Add button. It will add a shortcut of the source file. This only works for classes that have dependencies that are shared between the test and the code project so it might get a bit too much work if you have large dependencies in your class files.

I prefer first option than second because adding a attribute will make it work. And doesn’t need to link new files to test project every time. You can also using conditional compilation attributes to make the attribute only for Debug version of the assembly.

Happy Unit Testing :)

Test impact analysis in Visual Studio 2010

Test impact analysis helps developers to identify which all tests should run after code changes. This feature only available in Ultimate and Premium editions and only works with Managed code.

  1. Create a class library project, it is our production code, this library allows numbers to Add and Subtract numbers. And here is the implementation.
    namespace DemoLib
    {
        public class Math
        {
            public int Add(int number1, int number2)
            {
                return number1 + number2;
            }
    
            public int Subtract(int number1, int number2)
            {
                return number1 - number2;
            }
        }
    }
    
  2. And here is the Unit Tests for both add and subtract methods.
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace DemoLib.Test
    {
        [TestClass]
        public class MathTests
        {
            [TestMethod]
            public void TestAdd()
            {
                int first = 10;
                int second = 20;
                int expected = first + second;
                Math math = new Math();
    
                var actual = math.Add(10, 20);
    
                Assert.AreEqual(expected, actual);
            }
    
            [TestMethod]
            public void TestSubtract()
            {
                int first = 10;
                int second = 20;
                int expected = first - second;
                Math math = new Math();
    
                var actual = math.Subtract(10, 20);
    
                Assert.AreEqual(expected, actual);
            }
        }
    }
    

    And here is TestList View

    TestList view

    TestList view

  3. We can get the Test Impact view from Test menu, Windows and Select Test Impact View.
    Test Impact View

    Test Impact View

    As it mentioned in the Test Impact View window, we need to enable the Test Impact.

  4. To enable Test Impact, edit the Test settings, from Test menu, which will open the Test Settings dialog. Select the Data and Diagnostics option from the left side. And check the Test Impact checkbox from the Grid.

    Test settings dialog

    Test settings dialog

  5. After enabling Test Impact, using the Test Setting window, select the Test Impact window, now we are ready to track the test impact for that we need to run the unit tests cases.

    Test Impact view after enabling Test Impact

    Test Impact view after enabling Test Impact

  6. Now run the unit test cases to enable tracking.
  7. Now I am modifying the source code, like the following.
    public int Add(int number1, int number2)
    {
        return System.Math.Abs(number1) + System.Math.Abs(number2);
    }
    

    Instead of adding the numbers directly, now I am adding the positive numbers, by taking absolute values. After changing the code, build the project, , Visual Studio automatically detect all the affected unit test cases and displays it in the Test Impact view. In our case, the TestAdd method.

    Test Impact view - Displaying affected unit tests

    Test Impact view - Displaying affected unit tests

    It also displays the changed methods. Instead of using the automated way, above mentioned, you can do this manually also. If you are making any code change, right click on the method and you can choose either Show calling Tests or Run calling tests, which will display or run the unit test cases.

    Right click on the code, for Show Calling tests or run calling tests

    Right click on the code, for Show Calling tests or run calling tests

Happy coding :)

Getting Code coverage using Open Cover and NUnit

In the last post I blogged about how to get code coverage using MSTest and Part cover. In this post I am blogging about measuring code coverage with Open cover. Today I found another alternative to measure code coverage. Its called Open cover. You can download Open Cover from here. Compared to Part cover, Open cover doesn’t have a UI part. Also open cover gives better performance compared to Part cover. You can find Performance comparison here. You can find the OpenCover command line parameters in Github wiki.

In this example I am using a NUnit as the unit testing application. And the following command gets the code coverage in XML file.

"C:\Program Files (x86)\OpenCover\OpenCover.Console.exe"
-filter:"-[DataAccess.*]* +[DataAccess*]* -[DataAccess.Test]"
-target:"C:\Program Files (x86)\NUnit 2.5.10\bin\net-2.0\nunit-console-x86.exe"
-register:user -targetargs:"/nologo DataAccess.Test.dll"
-output:coverage.xml

The filter part is similar like, PartCover application, like I am profiling only DataAccess component and I am not profiling DataAccess.Test application. And no need to specify

the filters to remove System and NUnit type of assemblies.

Open cover generate results as XML files and with the help of Report Generator application you can view the coverage details.

And here is the syntax to get the details using Report Generator.

ReportGenerator.exe" coverage.xml "C:\Study\CodeCoverage\"

And here is the report generated using ReportGenerator summary and next is the detailed report.

Code coverage summary

Code coverage summary

And next is the detailed report.

Detailed Coverage details

Detailed Coverage details

Happy Code coverage :)

How measure get code coverage by PartCover with MSTest

If you are using VS 2010 Premium or Ultimate, you can get the code coverage from VS itself (You can find more posts related to code coverage here.). But if you are using Professional or less, you won’t get this code coverage feature. From last few months I am using VS Pro edition, and some time breaking the CI build because of low code coverage of my class. Today I found an alternative, PartCover 4.0 which helps to measure code coverage. You can download PartCover 4.0 . Installation is pretty easy, like any other software, and it has two parts UI version and command line version. I this post I am talking about UI version, which is called Part Cover browser.

  1. Open the Part cover browser, it will be displayed like this.
    Part Cover Browser

    Part Cover Browser

  2. Select File menu and click on the Run Target menu. It will popup a Window like this.
    Run target settings

    Run target settings


    In the window,

    1. Executable File : It the application required to run unit tests, in this case it MSTest.exe, normally which will be available in C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ location.
    2. Working Directory : After choosing the Executable file, Part cover automatically fill this location, by the same location of Executable, but you may need to change it and select the location, where your assemblies created.
    3. Working Arguments : This entry is required if you want to pass any parameters to the unit test engine as command line argument. For MS Test, it will be “/noisolation /testcontainer:YOUR UNIT TEST ASSEMBLY.” If you are using NUnit it will bedifferent.
    4. Rules : And the next and most important thing is Rules, which helps Part cover to give you coverage metrics for the specified assembly. If you want to get coverage of a assembly by including it and you can remove coverage by excluding it, it can be done using + and – signs respectively. Here is an example. Ignore namespaces, start with Microsoft.TeamFoundation and Microsoft.VisualStudio – -[Microsoft.TeamFoundation.*]* or -[Microsoft.VisualStudio.*]*
      And to include namespaces start with MySampleApp. +[MySampleApp.*]*. Or you cover all using +[*].
    5. Now click on the Start button, you can see two command line windows running and after few seconds it will display code coverage in the left side Treeview like this. Goto the View menu and select View coverage details, it will display the source code, with code coverage information, like this.
      Part cover with Code coverage results

      Part cover with Code coverage results

You can save the configuration, for future purposes and load it before starting code coverage. Here is the code and test class files.

Source code

public class UserRepository
{
    private Dictionary<string, string> _users = new Dictionary<string,string>();

    public void AddUser(string name, string address)
    {
        if (_users.ContainsKey(name))
        {
            throw new Exception("User already exists");
        }
        _users.Add(name, address);
    }

    public string GetAddress(string name)
    {
        if (!_users.ContainsKey(name))
        {
            throw new Exception("User not exists");
        }
        return _users[name];
    }
}

And here is the unit test

[TestClass]
public class UserRepositoryTest
{
    private UserRepository _testObject;

    [TestInitialize]
    public void Setup()
    {
        _testObject = new UserRepository();
    }

    [TestMethod]
    public void TestAddUser()
    {
        string expectedUser = "anuraj";
        string expectedAddress = "anuraj's address";
        _testObject.AddUser(expectedUser, expectedAddress);

        string actualAddress = _testObject.GetAddress(expectedUser);
        Assert.AreEqual(expectedAddress, actualAddress);
    }

    [TestMethod]
    [ExpectedException(typeof(Exception))]
    public void TestAddUserWithExistingUsername()
    {
        string expectedUser = "anuraj";
        string expectedAddress = "anuraj's address";
        _testObject.AddUser(expectedUser, expectedAddress);

        _testObject.AddUser(expectedUser, expectedAddress);
    }
}

Happy coding. :)

Unit Test Adapter threw exception – Unable to load one or more of the requested types

Today evening while working(?) around unit tests and code coverage, I got an exception from Visual Studio 2010. I wrote two unit test cases and it was passing, then I enabled code coverage in my solution, and the passing unit tests started failing. And I am getting error message like Unit Test Adapter threw exception: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information. from Test results window. :( Initially I thought Microsoft PEX is the culprit ;) I searched for the solution and found few solutions;like Clean and Build, but it didn’t worked for me. From another blog I found some other solution like to modify the vsmdi file. But I didn’t tried that option. Later I come to know, I forgot to disable the signing of the assemblies. You can do this selecting Project Properties > Signing > Un-check the sign assembly checkbox. I disabled the signing in the assemblies and it started working. :D

Happy unit testing :)

« Newer PostsOlder Posts »