Tips and Tricks for Using WinUnit with Microsoft Visual Studio

Introduction

In an earlier article, we saw how developers can use WinUnit for authoring unit test cases for their code. While the article demonstrated the use of WinUnit as a command line tool, most of the developers use Microsoft Visual Studio for their coding. Let us understand how we can integrate WinUnit into the Microsoft Visual Studio IDE. We will also explore some tips and tricks on using WinUnit and what are the scenarios where WinUnit should be used.

Integrating WinUnit with Microsoft Visual Studio

To get started, you want to make sure that your have the WinUnit include files in your project include path. You can set that in the Project Properties of your C++ Library project. Go to Configuration Properties -> C/C++ and add the path to the WinUnit header files to the “Additional Include Directories” setting.

Configuration Properties
Figure 1

Now that you have WinUnit header files in your include path, you can easily create WinUnit tests and refer to the WinUnit macros without running into unresolved references in your C++ project.

To add the facility of running WinUnit tests after you build your binary, you need to configure WinUnit as one of the available external tools in Microsoft Visual Studio and then set it up as a post-build step.

Navigate to the External Tools window by going to the Tools menu and selecting External Tools (Tools -> External Tools)
Here, click “Add” to add the information about WinUnit as visible from the screenshot below.

click
Figure 2

Add “WinUnit” as the title and in the “command” filed, make sure you have the full path to the winunit.exe of the desired bitness. For arguments, make you that you miss out on the enclosing quotes.

Check the “Use Output windows” and uncheck “close on exit” and click OK to add WinUnit to the external tools list.

At this point, you can now invoke WinUnit from the Tools menu itself.

Invoke WinUnit from the Tools menu
Figure 3

Now, if you are a super-developer, you can setup the execution of the unit tests as part of the build step as soon as the build is done.

For this, go to the Project Properties Page and select Configuration Properties -> Build-Events ->Post-Build Event and set the “command line” property to the full path to winunit.exe followed by “$(TargetPath)”. Make sure to include the quotes.

For my machine the command line looks like “C:\Users\vipul\Documents\articles\Unit testing for native applications using WinUnit\WinUnit-1.2.0909.1\Bin\x64\WinUnit.exe" "$(TargetPath)

The command line looks like this
Figure 4

Now that you have WinUnit as part of the build step, as soon as you build your application, WinUnit executes as the last part of the build process.

WinUnit Assert Macros

The most useful macros I have encountered are the following. There are more macros besides these.

Macro Purpose
WIN_ASSERT_EQUAL To check equality
WIN_ASSERT_NOT_EQUAL To check inequality
WIN_ASSERT_TRUE To check if condition is true
WIN_ASSER_FALSE To check if condition is false
WIN_ASSERT_THROWS To check if expression throws C++ exception
WIN_ASSERT_NULL To check if expression is NULL
WIN_ASSERT_NOT_NULL To check if expression is not NULL

When the assert fails, it is indicative of a test failure. These Assert macros are simply a wrapper of Win32 Assert API but also include the file and line number and sometimes a string representation of the failing expression.

If you want to log something informational in a test, you can use WIN_TRACE macro.

WinUnit Class Members & File List

WinUnit contains 3 different classes

  1. WinUnit::Assert class similar to .NET’s Assert class
  2. WinUnit::AssertException class
  3. WinUnit::Environment class.

WinUnit is contained in 2 header files – WinUnit.h and WinUnitLogger.h. The function prototypes in WinUnitLogger.h are supposed to be implemented by a custom logger if custom logging is desired on top of WinUnit.

Advanced Usage of WinUnit

WinUnit also provides a facility called “fixtures”, which offers a way to “Setup” and “Cleanup” before and after the test.
To create a fixture, you need to define new sections in your test called “SETUP” and “TEARDOWN”.

Also you have to now start your test using BEGIN_TESTF instead of BEGIN_TEST. You also pass in the fixture name as the second argument following the test name.

You then end the test with END_TESTF instead of END_TEST.

Guidelines for using WinUnit

To keep things simple, do not create more than one test file per class. Also, from my personal experience, it keeps code sane by having at least one unit test per method. More tests per function are OK as long as they don’t repeat the same code path.
Since WinUnit relies on C++ exceptions to do its magic, make sure to compile your test dll with the /EHsc flag.

Choose the appropriate WIN_ASSERT macro for your scenario. There are string versions of the macros available for string comparisons too.

Use fixtures (discussed above) to ensure your setup and cleanup are done properly.

Ensure you have proper names for the Unit test so that it becomes very easy to understand what unit test condition failed to speed you finding root cause. Ditto for the informational message printed in some cases, when the assertion fails.

Related Articles

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read