Working with Jetbrains dotCover

At Lightning Tools we like to make sure we are creating solid Web Parts and Tools for SharePoint. We currently use Jetbrains TeamCity for our Continuous Integration (CI) and find it a great part of our application lifecycle, it’s great to be able to commit our code to CVS and see if it builds on the Build Server – the whole team gets notified of all successful and failed builds, so this gives us ownership of any issues.

We also write Unit Tests, lots of Unit Tests to make sure everything still does what it should do after tweaking or adding new features.  One key metric for unit testing is determining how much of the code is tested when the unit tests run, this is called ‘Code Coverage’.  We have started using JetBrains dotCover which shows you which parts of a method are covered by a unit test and which parts are not, it also gives you a percentage of coverage. To show you how this can be useful I will do a simple validation class walkthrough.

Prerequisites

  • Visual Studio 2010
  • JetBrains Resharper
  • JetBrains dotCover

Walkthrough

  1. In this example we will be creating a class project and a test project
  2. Create a new Class Library project in Visual Studio , I have named the project ‘Validation’

    Add Class Library Project Item

  3. Rename the Class file to ‘TextValidator.cs’
  4. Add a new method to the class, we will have 3 validation checks in this method (must contain a value, must have a length no great than 10, each character must be a letter)
    using System.Linq;
    
    namespace Validation
    {
        /// <summary>
        /// A simple Class to Validate Text
        /// </summary>
        public static class TextValidator
        {
            /// <summary>
            /// Determines whether the specific input text is Valid.
            /// </summary>
            /// <param name="input">The input text.</param>
            /// <returns>
            ///     <c>true</c> if text is valid; otherwise, <c>false</c>.
            /// </returns>
            public static bool Validate(string input)
            {
                // Set initial state to valid
                bool isValid = true;
    
                // Check to make sure input has been entered
                if (string.IsNullOrEmpty(input))
                {
                    isValid = false;
                }
                // Check to make sure the length is not greater than ten
                else if (input.Length > 10)
                {
                    isValid = false;
                }
                else
                {
                    // Check to see if any of the characters are not letters
                    if (!input.Any(character => char.IsLetter(character)))
                    {
                        isValid = false;
                    }
                }
    
                // return result of validation test
                return isValid;
            }
        }
    }

  5. Now we have a simple method we can create our unit tests to test to make sure that each scenario is tested
  6. Add a new ‘Test Project’ to your Solution, I have name mine Validation.Tests

    Add Test Project Item

  7. Rename the UnitTest1.cs class to TextValidatorTests.cs , make sure you update the code too, it should look like the following. The reason we have renamed it is because this class will contain all of the tests for our TextValidation class in the ‘Validation’ project.

    Configure Unit Test Class

  8. Next we will write our first test, rename the Test1Method to:

    public void Validate_NullValue_FalseReturned()

    here we are using the syntax – MethodUnderTest_WhatWeAreTesting_ExpectedResult

  9. Add the following to the body of your method

    [TestMethod]
    public void Validate_NullValue_FalseReturned()
    {
        // Arrange
        string input = null;
        bool expected = false;
        bool actual;
    
        // Act
        actual = TextValidator.Validate(input);
    
        // Assert
        Assert.AreEqual(expected, actual);
    }

    We have made sure we have added the Arrange, Act, Assert comments to allow other people to understand the main components of the test, when a unit test gets a bit bigger then this can be a real advantage.

  10. We are ready to run our Unit Test to see if it passes, click on the symbol next to the test method and click ‘Run’ to execute it.

    Run Unit Test using ReSharper

  11. We can see that the Unit Test has ‘Passed’ successfully – by passing in a null value the result is false.

    View Unit Test Results

  12. Next we will use dotCover to what else we need to test on our method to make sure we are covering all execution paths. We must remember that 100% code coverage does not equal bug-free code or that the code is correct, it just tells us that our code is covered by tests.

  13. In the ‘Unit Test Sessions’ Window click on the the dotCover icon to begin to analyse our code coverage, once completed you will see some graphs to show you how  much of our code is covered

    Code Coverage Results for first test

    if we expand to our TextValidation we can see the methods and their coverage

    Code Coverage Results for first test breakdown

    here we can see that only 44% of our Validate method is covered, if we double click on the method name it will take us to the code and show us something very interesting

  14. We can see here in Green the areas which are used by our Unit Tests, in Red are the areas that are currently not tested

    Code Coverage Code Highlighting For First Test

  15. I am sure by now you can see by now why this is useful, we can see that we need to write a Unit Test which passes in an input where the length is greater than 10

  16. Add the following Unit Test to the TextValidatorTests class to test with an input with a length of 20 characters – we are expecting this to return false again.

    [TestMethod]
    public void Validate_InputLengthIs20_FalseReturned()
    {
        // Arrange
        string input = "radiopharmaceuticals";
        bool expected = false;
        bool actual;
    
        // Act
        actual = TextValidator.Validate(input);
    
        // Assert
        Assert.AreEqual(expected, actual);
    }

  17. Run the test as before and code coverage. Make sure you select the Validation.Tests namespace before running so that it runs and does code coverage for everything in that namespace, this is because we want to see how all of our tests cover our main code, if you want you can run dotCover on just one Unit Test to see how much of a method that single Unit Test covers

  18. Lets check out how that has effected the code coverage

    Code Coverage results for second test

    We can see we have gone up from 44% to 67% code coverage of our Validate method, if we look again at the code we will be able to see the less than 10 check is now in green

    Code Coverage code highlighting for second test

  19. This is great, we are getting there but need just one more test to make sure we have all of this method covered with tests, lets get to our final test

  20. Add the following method to our TextValidatorTests class – here we are going to test if a non-text character cause a false result

    [TestMethod]
    public void Validate_InputContainsNonLetters_FalseReturned()
    {
        // Arrange
        string input = "12345";
        bool expected = false;
        bool actual;
    
        // Act
        actual = TextValidator.Validate(input);
    
        // Assert
        Assert.AreEqual(expected, actual);
    }

  21. Again run the tests and run dotCover

  22. We now have 100% code coverage of our Validate method!

    Code Coverage results for final test

    and our code

    Code Coverage code highlightning for final test

    beautiful, beautiful green! We are all covered

  23. One thing to note here is that we have written 3 Unit Tests to match our three logic gates in our code but we have not written a test to make sure a Valid input gets through. I don’t foresee a problem here but dotCover is not here to make sure you are doing everything right, it is a fantastic tool to assist your common sense and attention to detail.

  24. Lets just add a final test to make sure that a correct input is OK

    [TestMethod]
    public void Validate_ValidInput_TrueReturned()
    {
        // Arrange
        string input = "Valid";
        bool expected = true;
        bool actual;
    
        // Act
        actual = TextValidator.Validate(input);
    
        // Assert
        Assert.AreEqual(expected, actual);
    }

  25. And the final results are in….

    Final Unit Test Results 

I hope you have found this walkthrough useful

 

<Phill />