Saturday, January 11, 2014

Unit testing in Native C++ using Visual Studio 2013

Test driven development TDD is used in many languages. and can be used in c++ as well. The support for unit test in native C++ was added in VS2012 and I thought I'll write a short blog post on how to get started in VS2013. I'll be using VS 2013 Express for Desktop for this blog post.

I'll use a static library but it is possible to add test projects to EXE or DLL projects as well for more information on that see: http://msdn.microsoft.com/en-us/library/hh419385.aspx

Start Visual Studio 2013:

Visual Studio 2013 for Desktop
We start by adding the projects that should be tested MathLibrary and add a test project MathLibraryTests.

Choose "Add project":
Add project from start page

Add project from FILE menu
In the Add Project dialog, change the project to be a Visual C++ win32 project and the Name to be MathLibrary:

   
New Project dialog



In the Win32 Application wizard choose Next:
Win32 Application Wizard - Step 1


 In the Next step choose Static Library:



 Choose finish and the solution and MathLibrary project is created:


Build the MathLibrary project. Note in the output windows that the MathLibrary.lib file ends up in the Debug folder that is in the Solution folder.


Create the Test project by right clicking the solution and choose New Project:

In the New Project dialog, choose a Visual C++ Native Unit Test project and give it the name MathLibraryTests:


Link the MathLibrary with the MathLibraryTests project, this is done with three steps in the MathLibraryTests projects Properties:

1. Add the MathLibrary.lib to the Additional Dependencies in the linker input settings:

2. Add the path to the MathLibrary.lib file in the Additional Library Directories in the linker general settings:

3. Add the include files path in the Include Directories  in the
VC++ Directories:


Rebuild the MathLibraryTests project, The output should say that the build was successful:

The projects are now in place and we can start testing the application functionality. The functionality in this case will take a string with numbers and calculate the sum of the numbers.
 
Add a new unit test CalculatorTests, Right click the test project and choose "Add new item":


In the Add Item dialog, choose Test C++ Unit Test Class and give it the name CalculatorTests:


Add a new test method by renaming TestMethod1 to CalculateSumWithEmptyStringArgumentReturnsZero:
        TEST_METHOD(CalculateSumWithEmptyStringArgumentReturnsZero)
        {
            // TODO: Your test code here
        }

Add the Arrange, Act, Assert AAA implementation in the test method:
        TEST_METHOD(CalculateSumWithEmptyStringArgumentReturnsZero)
        {
            //Arrange
            int expected = 0;
            Calculator calculator{};
            std::string strArgument{ "" };

            //Act
            auto actual = calculator.CalculateSum(strArgument);

            //Assert
            Assert::AreEqual(expected,actual,L"Should return 0",LINE_INFO());

        }

Run the test project:


Failed or in this case a compiler error = Red

The reson is simple we need to implement the class and metod in the MathLibrary.

Right click the MathLibrary project and choose Add class:

Name it Calculator:


Add a  method CalculateSum,
calculator.h:
#pragma once

#include

class Calculator
{
public:
    Calculator();
    ~Calculator();
    int CalculateSum(std::string stringNumbers);
};

calculator.cpp:
#include "stdafx.h"
#include "Calculator.h"


Calculator::Calculator()
{
}


Calculator::~Calculator()
{
}

int Calculator::CalculateSum(std::string stringNumbers)
{
    return 0;
}

Include calculator.h in the CalculatorTests class.

Run the test:



Result passed = Green:


Refactor and clean the code = Refactor

Re run the unit test, so no errors have been added.

Continue by adding a new test...

Test Failed.

Add new functioanlity...

Test passed

Refactor.

Test passed...

Well that's not all there is to it, but it's a start. After a while you will see the need for initializing and clean up as well as Stub, Fake, Mock object. 

1 comment:

Roberto Cardenas Isla said...

Hello, I want to do something like this, but with the only different that I want to test an Arduino Project. I am using Arduino and Visual Studio 2013 Community with the Visual Micro extension. Then When I add the rederence of my Arduino Project to my TestSuite, the Test project raise en error because it doesnt find the Arduino classes. Did you see or try to test Arduino Projects?