简体   繁体   中英

testing classes

I put together a class yesterday to do some useful task. I started alpha testing, and at some point realized I was adding alpha test related methods to the class itself. It hit me that they don't belong there. After a bit of head scratching I derived a test class from the base class that has access to the protected members as well. I put all of the testing related methods, and set up and tear down in the test class, and left the base class lean and mean as the old saying goes.

After browsing around here awhile I found one comment that suggested using this sort of technique by making the testing class a friend of the real class.

In retrospect both of those techniques should have been obvious to me.

What I am looking for, are techniques for specifically alpha testing/unit testing classes, without adding to the weight of the class being tested.

What techniques have you personally used, and recommend?

One of the goals of unit testing is to verify the interface to your classes. This means that, generally speaking, you shouldn't be testing the dirty innards of your class. The unit test is supposed to interact with the public inputs and outputs of your class, and verify that the behaviour is as expected. You are thus able to change the internal implementation of your class without affecting all of the other objects that depend on it. Obviously, I don't know the details in your situation but I would say that, as a general rule, if your unit test is trying to figure out the private details of the class, you are doing something wrong.

See also: This SO question . 另见: 这个问题Notice that it can be done (top answer), but also notice that the second-place answer (by a short margin) says more or less the same thing as I mention above.

It sounds like you don't want Unit testing, which is correctly the verification that the interface of a class works. You shouldn't have to change your class at all in order to do unit testing. If you are looking for a way to verify the internal state of your object so that it remains consistent, you should look into Design by Contract methods, which can verify internal state from within the object.

Those are good. I have usually also wanted the test class to not only be spearate from the original, but also in a complete different DLL/EXE, as well as testing the "real" compiled class from the "real" DLL/EXE into which it was compiled.

The one additional technique I've found is to re-define the class within the testing tool. Copy the class definition exactly, but make everything public. This allows the test tool to have 'white-box' access to the class, but the actual implementation is still from the real class code.

ie

class myClass
{
private:
    int foo;
public:
    myClass() { foo = 0; }
}

and then:

class test_myClass
{
public:
    int foo;
public:
    test_myClass();
};

void test()
{
    myClass *c = new myClass();
    test_myClass *t = (test_myClass*)c;
    // All methods are called on c.
    // White-box access is available through t.
};

Oh... and DevStudio 2008 now has some really cool unit testing capabilities, including the ability to declare a 'friend' assembly , which allows white-box access to all your internal classes in the assembly being tested.

I have done a lot of framework building - basically calling the classes/interfaces I wanted to test. There was no additional work in the classes.

I also built classes a few times that made the public methods virtual. I derived from those and made test classes/objects. The test object methods called the parent (real class) methods and also logged all calls and results. This was more for logging than testing, but it worked as well.

The methods above I did before all the hype about unit testing and the like. (circa late 1990s)

It worked well for me then, but I have not done too much with the Junit/nunit stuff and am eager to actually give them a whirl on real projects.

sample for one method

class Thing

{...

public: virtual DoStuff(); . .. };

class ThingTest : public Thing

{

virtual DoStuff()

{

//log the call and the parameters.

// make the call to the parent

// log the return value

// return the return value

}

};

eJames is right Unit Testing needs to focus on Interface that the inputs into the Class are producing the correct Output. Any private or friend variable are part of the implementation and are not tested specifically.

If you had made an error in a private routine to the class then it would show up incorrect output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM