Reusing tests in cppUnit

Discussion in 'C++' started by Belebele, Jan 15, 2007.

  1. Belebele

    Belebele Guest

    Suppose I want to test several implementations of the same protocol
    (interface with clearly defined semantics) using cppUnit. How to reuse
    the test that checks the semantics?

    Take, for example, the simple SetterGetter interface and the even
    simpler implementations Impl1 and Impl2.

    class SetterGetter {

    SetterGetter& operator=(SetterGetter const& ); // Not Implemented

    public:
    virtual ~SetterGetter() {}

    virtual void set(int ) = 0;

    virtual int get() const = 0;
    };


    class Impl1: public SetterGetter {

    /* This class clearly fails to comply with
    the intended semantics, thus the protocol
    test should fail when passed an object of
    this class */

    public:
    virtual void set(int ) {}

    virtual int get() const {return 0;}
    };


    class Impl2: public SetterGetter {
    int i_;

    public:
    virtual void set(int i) {i_ = i;}

    virtual int get() const {return i_;}
    };


    I would like to write a single class that tests the semantics and that
    can be reused for any implementation of the protocol. Any ideas?

    I made an attempt, but it did not work. The output said that there was
    a Segmentation fault. See below:

    class TestSetterGetter: public CppUnit::TestCase {

    CPPUNIT_TEST_SUITE( TestSetterGetter );

    CPPUNIT_TEST( testSetGet );

    CPPUNIT_TEST_SUITE_END();

    SetterGetter *psetterGetter_;

    public:
    TestSetterGetter(): psetterGetter_(0) {}

    void set(SetterGetter& sg) {psetterGetter_ = &sg;}

    void testSetGet() {
    psetterGetter_->set(0);
    CPPUNIT_ASSERT_EQUAL(0, psetterGetter_->get());
    }
    };


    class TestImpl1: public TestSetterGetter {

    Impl1 impl1_;

    public:
    TestImpl1() {set(impl1_);}
    };
    CPPUNIT_TEST_SUITE_REGISTRATION( TestImpl1 );


    class TestImpl2: public TestSetterGetter {

    Impl2 impl2_;

    public:
    TestImpl2() {set(impl2_);}
    };
    CPPUNIT_TEST_SUITE_REGISTRATION( TestImpl2 );
     
    Belebele, Jan 15, 2007
    #1
    1. Advertising

  2. Belebele

    Belebele Guest

    Never mind, I got it ...

    The solution that worked for me is:
    1. Create the test base class, that derives from cppUnit::TestCase, and
    define the tests for the protocol in it. Two things to notice: the
    termination macro for the declaration of the tests in the fixture must
    be CPPUNIT_TEST_SUITE_END_ABSTRACT() and the class should not be
    registered as a fixture. See below (the auto_ptr is to avoid having to
    deallocate the memory explicitly):

    #include <memory>
    using namespace std;

    class TestSetterGetter: public CppUnit::TestCase {

    CPPUNIT_TEST_SUITE( TestSetterGetter );

    CPPUNIT_TEST( testSetGet );

    // Different termination macro for the test declarations.
    CPPUNIT_TEST_SUITE_END_ABSTRACT();

    auto_ptr<SetterGetter> psetterGetter_;

    virtual auto_ptr<SetterGetter> makeSetterGetter() = 0;

    public:
    void setUp() {psetterGetter_ = makeSetterGetter();}

    void tearDown() {}

    protected:
    void testSetGet() {
    psetterGetter_->set(1);
    CPPUNIT_ASSERT_EQUAL(1, psetterGetter_->get());
    }
    };
    // No test registration here.



    2. Then, for the implementations of the tests of the different
    implementations (sorry for the tongue twisting), one thing to notice is
    that the initialization of the test declaration requires a different
    macro which includes a declaration of the base test. See below:
    class TestImpl1: public TestSetterGetter {

    // A different macro for the initialization of the test
    declarations.
    CPPUNIT_TEST_SUB_SUITE( TestImpl1, TestSetterGetter );

    CPPUNIT_TEST_SUITE_END();

    auto_ptr<SetterGetter> makeSetterGetter() {
    return auto_ptr<SetterGetter>(new Impl1());
    }

    public:

    // In my example, no extra tests to add here

    };
    CPPUNIT_TEST_SUITE_REGISTRATION( TestImpl1 ); // Just register your
    fixture and you will be in business.


    class TestImpl2: public TestSetterGetter {

    CPPUNIT_TEST_SUB_SUITE( TestImpl2, TestSetterGetter );
    CPPUNIT_TEST_SUITE_END();

    auto_ptr<SetterGetter> makeSetterGetter() {return
    auto_ptr<SetterGetter>(new Impl2());}

    public:

    // In my example, no extra tests to add here

    };
    CPPUNIT_TEST_SUITE_REGISTRATION( TestImpl2 );

    All of this complication only because reflection is nowhere to be seen
    on C++.
     
    Belebele, Jan 15, 2007
    #2
    1. Advertising

  3. On Jan 15, 8:19 pm, "Belebele" <> wrote:
    > Never mind, I got it ...
    >


    snipped...

    A similar (but IMHO cleaner) approach is the (google-able)
    'Parametrised test case'

    Andrew
     
    andrewmcdonagh, Jan 15, 2007
    #3
  4. Belebele

    Belebele Guest

    > A similar (but IMHO cleaner) approach is the (google-able)
    > 'Parametrised test case'


    I looked it up. I don't feel I understood it very well. It got the
    impression that can be used to run the same test on a set of input
    data. It was not clear to me how to apply it to the example I posted.
    Also, I could not even find the ParameterizedTestCase.h file in my
    cppUnit installation (1.10.2)

    Could you please elaborate? Could you use the example from my previous
    posts? Thanks.
     
    Belebele, Jan 22, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Roy Smith

    Forking sub-process in CppUnit?

    Roy Smith, Jul 4, 2003, in forum: C++
    Replies:
    0
    Views:
    406
    Roy Smith
    Jul 4, 2003
  2. Scott

    Xcode and cppunit

    Scott, Apr 27, 2004, in forum: C++
    Replies:
    2
    Views:
    1,066
    Scott
    Apr 27, 2004
  3. Steven T. Hatton

    Is CppUnit un-C++

    Steven T. Hatton, Sep 4, 2004, in forum: C++
    Replies:
    9
    Views:
    506
    Daniel T.
    Sep 6, 2004
  4. To Forum

    CPPUNIT

    To Forum, Jan 13, 2005, in forum: C++
    Replies:
    1
    Views:
    571
    Stephen Howe
    Jan 14, 2005
  5. Hooyoo
    Replies:
    59
    Views:
    5,073
    Gianni Mariani
    Nov 3, 2006
Loading...

Share This Page