C++ Unit Testing Redirecting stdout

Posted in software by Christopher R. Wirz on Mon May 22 2017

Unit tests are important when ensuring that your code is executing correctly as you will more-than-likely write future methods that call that code (if not, why write it?!). In order to ensure functional correctness, unit tests are used. Using Visual Studio 2015 or higher, MS Test libraries can be written in C++ using the /clr compiler flag.

Note: This post assumes Visual Studio 2015 Release 2 with v140 compiler.

There is unfortunately a bug that is known to the user community regarding debugging C++ unit tests. Due to this bug, you can't hit breakpoints in your unit tests to inspect parameters. Foruntately, there is a way to direct print statements to a text file.

#ifdef _MSC_VER && ((_MANAGED == 1) || (_M_CEE == 1) ) // Chceck if /clr

// don't let vs capture standard output

#include "stdafx.h"
// Needed for file Input/output
#include <stdio.h>
#include <stdlib.h>

using namespace System;
using namespace System::Text;
using namespace System::Collections::Generic;
using namespace Microsoft::VisualStudio::TestTools::UnitTesting;

namespace MyTestLib
	public ref class MyTestClass
		TestContext^ testContextInstance;
		/// <summary>
		///Gets or sets the test context which provides
		///information about and functionality for the current test run.
		property TestContext^ TestContext
			TestContext^ get()
				return testContextInstance;
			System::Void set(TestContext^ value)
				testContextInstance = value;

		#pragma region Additional test attributes

		static FILE* stdout_capture;

		// Use ClassInitialize to run code before running the first test in the class
		static void ClassInitialize(TestContext^ testContext) {
			if ((stdout_capture = freopen(
		        "MyTestClass_outputfile.txt", "w", stdout
		    )) == NULL) {
		// Use ClassCleanup to run code after all tests in a class have run
		static void ClassCleanup() {
			stdout_capture = freopen("CON", "w", stdout);
		// Use TestInitialize to run code before running each test
		void TestInitialize() {};
		// Use TestCleanup to run code after each test has run
		void TestCleanup() {};
		#pragma endregion 

		void My_Unit_Test()
		    // keep it simple for this example
		    int i = 1;

		    // This will write to the text file
		    printf("Testing the value of %d", i);

		    // Always evaluates true
		    Assert::AreEqual(i, 1, 0.0001);

Using the printf statement, output from the unit tests can be directed to the text file. This is also a great option if the unit tests are being run at a gated checkin. In this approach, you can still verify the output is as expected - possibly with a hash function.

Looking for a job?