Test Categories for Visual C++

Wednesday, April 30, 2014 – 9:52 PM

Recently I’ve been using the Visual Studio unit test runner for C++ and came across a trick for adding categories to C++ tests. While the test framework supports traits, a little work makes them much more usable.

    BEGIN_TEST_METHOD_ATTRIBUTE(methodName) 
        TEST_METHOD_ATTRIBUTE(L"TestCategory", "my_category")
    END_TEST_METHOD_ATTRIBUTE() 
    TEST_METHOD(methodName)
    {
        // ... 
    }

That’s a lot of code to  just add a category to each test.

You can add a specific macro to shorten all of this up, especially if you’re adding categories to all of your tests.

    #define TEST_METHOD_CATEGORY(methodName, category)          \
        BEGIN_TEST_METHOD_ATTRIBUTE(methodName)                 \
            TEST_METHOD_ATTRIBUTE(L"TestCategory", L#category)  \
        END_TEST_METHOD_ATTRIBUTE()                             \
        TEST_METHOD(methodName)

Now you an write tests like this:

    TEST_METHOD_CATEGORY(testMethod, "my_category")
    {
        // ...
    }

Better still you can do the same thing for classes. In this case the BEGIN_CLASS_METHOD_ATTRIBUTE can be used within another macro.

    #define TEST_CLASS_CATEGORY(className, category)                \
        TEST_CLASS(className)                                       \
        {                                                           \
            BEGIN_TEST_CLASS_ATTRIBUTE()                            \
                TEST_CLASS_ATTRIBUTE(L"TestCategory", L#category)   \
            END_TEST_CLASS_ATTRIBUTE()

Note that the MSDN page is incorrect in it’s documentation of this attribute. It is used inside the class and does not take any arguments.

Now you can add a category to a class and, if needed, override the category for individual methods.

    TEST_CLASS_CATEGORY(the_tests, "foo")
    // No '{' required, part of the macro.
        TEST_METHOD_CATEGORY(test, "bar")
        {
            // Test in category 'bar'.
            Assert::Fail(L"Ooops");
        }

        TEST_METHOD(test2)
        {
            // Test in category 'foo'.
            Assert::Fail(L"Ooops");
        }
    };

I’ve used this to organize the tests in the C++AMP Algorithms Library, so you can look what I did there if you want more examples.

Sorry, comments for this entry are closed at this time.