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.
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
#ifndef NO_STDIO_REDIRECT
#define NO_STDIO_REDIRECT
#endif
#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
{
[TestClass]
public ref class MyTestClass
{
private:
TestContext^ testContextInstance;
public:
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
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
[ClassInitialize()]
static void ClassInitialize(TestContext^ testContext) {
if ((stdout_capture = freopen(
"MyTestClass_outputfile.txt", "w", stdout
)) == NULL) {
exit(-1);
}
};
// Use ClassCleanup to run code after all tests in a class have run
[ClassCleanup()]
static void ClassCleanup() {
stdout_capture = freopen("CON", "w", stdout);
fclose(stdout_capture);
};
// Use TestInitialize to run code before running each test
[TestInitialize()]
void TestInitialize() {};
// Use TestCleanup to run code after each test has run
[TestCleanup()]
void TestCleanup() {};
#pragma endregion
[TestMethod]
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);
};
};
}
#endif
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.