C++ unit test testing, using template test class
Asked Answered
G

2

7

I’m doing some C++ test driven development. I have a set of classes the do the same thing e.g.

same input gives same output (or should, that’s what I’m try to test). I’m using Visual Studio 2012’s

CppUnitTestFramework. I wanted to create a templated test class, so I write the tests once, and can template in classes as needed however I cannot find a way to do this. My aim:

/* two classes that do the same thing */
class Class1
{
    int method()
    {
        return 1;
    }
};

class Class2
{
    int method()
    {
        return 1;
    }
};

/* one set of tests for all classes */
template< class T>
TEST_CLASS(BaseTestClass)
{
    TEST_METHOD(testMethod)
    {
        T obj;

        Assert::AreEqual( 1, obj.method());
    }
};

/* only have to write small amout to test new class */
class TestClass1 : BaseTestClass<Class1>
{
};

class TestClass2 : BaseTestClass<Class1>
{
};

Is there a way I can do this using CppUnitTestFramework?

Is there another unit testing framework that would allow me to do this?

Griner answered 3/7, 2013 at 7:3 Comment(0)
V
4

I do not know if there is a way to do this with CppUnitTestFramework, with which I am unfamiliar, but something you can certainly do in googletest is specify an arbitrary list of classes and have the framework generate (template-wise) the same test(s) for all of them. I think that would fit your bill.

You can download googletest as source here.

The idiom you will want is:

typedef ::testing::Types</* List of types to test */> MyTypes;
...
TYPED_TEST_CASE(FooTest, MyTypes);
...
TYPED_TEST(FooTest, DoesBlah) {
    /*  Here TypeParam is instantiated for each of the types
        in MyTypes. If there are N types you get N tests.
    */
    // ...test code
}

TYPED_TEST(FooTest, DoesSomethingElse) {
    // ...test code
}

Study the primer and the samples. Then go to the AdvancedGuide for Typed Tests

Also check out More Assertions

Versed answered 3/7, 2013 at 8:25 Comment(1)
Cheers for the answer. For anyone looking at this googletest is a little bit of a pain to get going. I used a combination of these to guides blog.knatten.org/2012/09/26/… and #532441. It does not compile in Visual Studio 2012 unless you set compiler to be 2010 version in the project properties.Griner
R
1

I had a similar problem: I have an interface and several implementations of it. Of course I do only want to write tests against the interface. Also, I do not want to copy my tests for each implementation.

Well, my solution is not very pretty but it is straightforward and the only one I came up with until now.

You could do the same for Class1 and Class2 and then add more specialized tests for each implementation.

setup.cpp

#include "stdafx.h"

class VehicleInterface
{
public:
    VehicleInterface();
    virtual ~VehicleInterface();
    virtual bool SetSpeed(int x) = 0;
};

class Car : public VehicleInterface {
public:
    virtual bool SetSpeed(int x) {
        return(true);
    }
};

class Bike : public VehicleInterface {
public:
    virtual bool SetSpeed(int x) {
        return(true);
    }
};


#define CLASS_UNDER_TEST Car
#include "unittest.cpp"
#undef CLASS_UNDER_TEST


#define CLASS_UNDER_TEST Bike
#include "unittest.cpp"
#undef CLASS_UNDER_TEST

unittest.cpp

#include "stdafx.h"
#include "CppUnitTest.h"

#define CONCAT2(a, b) a ## b
#define CONCAT(a, b) CONCAT2(a, b)

using namespace Microsoft::VisualStudio::CppUnitTestFramework;


TEST_CLASS(CONCAT(CLASS_UNDER_TEST, Test))
{
public:
    CLASS_UNDER_TEST vehicle;
    TEST_METHOD(CONCAT(CLASS_UNDER_TEST, _SpeedTest))
    {
        Assert::IsTrue(vehicle.SetSpeed(42));
    }
};

You will need to exclude „unittest.cpp“ from build.

Radiotelegram answered 1/11, 2017 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.