The effect of redundant testing functions inside a C++ class - c++

When designing functions inside a C++ class, I often keep testing in mind. So when I finish all the functionalists of a class, very often several functions that are only used for testing purpose are added in the class as well. Take the following example:
class SimpleClass
{
public:
int a;
int b;
void fun1();
void fun2();
void testIntermediateResult();
private:
void _fun1();
void _fun2();
};
In this function testIntermediateResult is only needed for testing purpose. Is it a good practice just leave the function inside the class or should I do something like that:
class SimpleClass
{
public:
int a;
int b;
void fun1();
void fun2();
#ifdef TESTING
void testIntermediateResult();
#endif
private:
void _fun1();
void _fun2();
};
The philosophy here is when this class has been finished testing and will be given to the clients then TESTING will be defined and this function will not be inside the class. Therefore, my question is: is really needed to remove the testing function when the class is given to the client? Suppose the client will not use the testing function, what's the effect of adding several redundant testing functions inside a class? Thanks.

I'm assuming that your client is not going to be involved in testing the class that you're handing over. I would not want to add testing functions directly into the class itself as there's a possibility that they could disrupt the behaviour of the class. As for the client, I would prefer not to give them something with a test function in it since:
It's not necessary - it's not their job to test it.
They could decide to try to use it - who knows what'll happen then?
It's just simpler if they don't see it. As for using the pre-processor, this could be fraught with problems particularly if you have attributes that need to be guarded in the same way. If any of them are missed or your macro is redefined in the build process by the client then you could get run-time crashes due to class size mismatches etc.
I'd favour having a one-to-one external class to test your deliverable classes. Something like TestSimpleClass which performs the testing. There are a number of advantages to this approach:
It's entirely separate from your code and not built into it so you aren't bloating code or causing any potential issues with it.
It's going to test your class interface the way your client sees it (i.e. black box testing)
Because it's separate, you don't have to give it to your client - they never have to know about it.
If you really want to test the internals of the class, you can always make your test class a friend of your deliverable class. It's only one line extra in the deliverable class and you still don't have to ship your test classes or libraries.

Related

C++ Unit testing: Changing member scope

I'm writing unit tests for my class and would like to exercise methods that are private. I'm doing something like this:
class MyClass {
Myclass() {}
~MyClass() {}
#ifdef TESTING
public:
#else
private:
#endif
void MyMethod1();
void MyMethod2();
};
If TESTING is defined, I change the class signature to make everything public. In my test code, I just do something like this:
#define TESTING
#include "MyClass.h"
void MyTestMethod()
{
MyClass mc;
mc.MyMethod1(); // Now I can access MyMethod1
}
So that its only public in my test files and not anywhere else. My testing executable sees a header that describes a class that is all public. The code for the class is actually being built somewhere else (where TESTING is not defined), so the scope will differ when the testing project links against the library.
Does this have the potential to break anything? I'm worried that this could change vtables locations or compiler and linker expectations if the header differs from what was actually produced in the object file.
You risk ending up with low quality tests. Tests that are testing some implementation details not relevant to the actual function of the classes. Testing the public interface only drives you towards a good design and test cases that can stand code refactors without breaking.
Ugly, although it's possible but don't do it that way instead create a wrapper class for your tests and use the friend TestClass; keyword in MyClass.

Determine if method or member can be protected or private

It is possible to check (for example by gcc) which methods or members can be moved to protected or private section?
Consider the following part of code:
class foo{
protected:
void foo_method_1(){};
int foo_member_var;
};
class bar : public foo{
void bar_method_1(){
foo_method_1();
}
};
If you want to determine which members and methods of the foo class can be private, you have to move all of them to the private section. So it will look like this:
class foo{
private:
void foo_method_1(){};
int foo_member_var;
};
...
Now it won't compile, here's the first error thrown by GCC:
prog.cpp:5:8: error: 'void foo::foo_method_1()' is private
void foo_method_1(){};
From that you know, that you have to move the foo_method_1 to the protected section. So it will look like this:
class foo{
private:
int foo_member_var;
protected:
void foo_method_1(){};
};
...
Now it will compile. You have to repeat this process for every single method and member in your class. For public section you can do it in the same way as described above.
You can't do this programmatically, no. And that's actually a good thing.
Sure, you could create a tool that integrated with a C++ parser, then — one-by-one — made certain members functions private and left any there that didn't cause an error in your program.
But, in order to do that, your entire program would need to be visible to that tool. Maybe if you have a simple project that's not a problem, but if you're writing a library that's literally impossible.
Even if you could do it, your resulting class design would be an absolute mess. Only a human programmer knows which parts of the API are designed for public consumption or not, and that's not always the same as which parts of the API are currently being consumed.
Stick to the manual approach, but don't just replicate the way the machine would do it, randomly guessing based on what compiles and what does not compile. Use your brain and your memory of what this class is supposed to do, to determine which functions should be public and which should not.
Ideally, try to get it right when you're first designing your class! You should be spending far more time designing your program than actually programming it, lest you very quickly end up with maintenance nightmares like this.
No. The compiler sees your code, not your design.

Unit testing a class constructor

In C++ how would one test a class constructor? For example:
Class myClass{
int a;
public:
myClass(); //Constructor
void reset(); //resets a to 0;
};
//Constructor defined to initialize a to 0
myClass::myClass(){
reset();
}
//reset sets a to 0
void myClass::reset(){
a = 0;
}
How would I test the myClass() constructor? I can't access the private data member, so would it be valid to say if reset works then the constructor works?
I am going to rephrase your question to: how do I test properties of my class that are not directly observable from my tests because they are protected or private? Here are several possibilities in the order that I usually think about them:
Move the checking part of the test into the class by using an assert(). If what you want to test is that your constructor has successfully established some complex invariant, then you can put an assert() at the end of the constructor that verifies that invariant. Then all your test has to do is to call the constructor - the assert inside the constructor does the actual checking that the test would otherwise have done. If you habitually add asserts as you write the code then that assert will already be there (if asserts make your debug build too slow, use a profiler to pinpoint those asserts that are actually a problem).
Extract the complex piece of code that you want to test into a second class. You can then test the second class through its public interface. This option is attractive when extracting the second class improves the code even when not considering testability.
Change the design of your code to something more testable in some other way. Again, this is attractive when the change is an improvement even when not considering testability.
Strategic retreat. Testing code in isolation is good all other things being equal, but there is no law saying that all code must be tested in isolation. Sometimes the right answer is to just let that code be tested as a side-effect of testing something else. All your other tests for that class will call the constructor, after all, so if something is wrong with the constructor it will probably cause one of those other tests to fail. It may be harder to cover all paths this way and at the time that you get that failure it will be more trouble to track down the cause of the failure because now you do not know if the problem is the constructor or the other thing being tested. That may or may not be a big deal. Is it truly worth the trouble to test this code in isolation, taking into consideration what else you could be using that time on and the probability that this test will ever actually find a bug? Would a code review be a more useful way to spend that time? Is there something else that it would be more useful to do?
If you truly must test something that cannot be tested with assert() and where there is no acceptable refactoring to improve testability, then there are still some options. I've never had to use these for testing, but here they are:
Use a friend declaration to give your tests access to private fields on your class. Each class now needs to maintain a list of friend declarations for tests that need access. This can be a chore to maintain.
Maintain a separate interface for use by tests. Have a set of methods that give the access that you need and whose name has a prefix like "testOnly". So in your case it would be testOnlyGetA(). You will have to be disciplined in only calling these methods from tests and you now need to maintain a larger interface than before.
Hold your nose and do #define private public in your test file before including the header that you want to test.
Upd. Sorry, misunderstood.
You may add a friend testing function to a class or a class-member testing function (which is better to test implementation details, but sometimes is impossible due to testing framework restrictions)
You could add a boost test case to the class:
Class myClass{
private:
int a;
public:
myClass(); //Constructor
void reset(); //resets a to 0;
void test_a_reset() {
BOOST_CHECK_EQUAL(a, 0);
}
};
Im not sure about how you are doing the testing though. This may not be what you want.
You can declare a test class with the same memory layout of your original class, but all members being public.
void testMyClassConstructor()
{
class myClassPublic
{
public:
int a;
myClassPublic();
void reset();
};
typedef union
{
myClass* original;
myClassPublic* testView;
} u_myClass;
myClass testInstance;
u_myClass testUnion;
testUnion.original = &testInstance;
assert(testUnion.testView->a == 0);
}
This is fine in a white box test case, if you can't change the tested class' interface.
However, remember that any changes to the memory layout of the original class will break the unit test aswell.

mock object woes

We have the following problem: a number of classes that we cannot touch but need to unit test them unfortunately the classes are not designed with unit testing in mind so we issues creating mock objects to test the code.
Example:
class SomeOtherClass
{
public:
void foo2() { … }
};
class ClassToTest
{
public:
ClassToTest() {…}
void foo1() { SomeOtherClass A.foo2(); }
};
In the above example we would like to test foo1() but it needs foo2() so we would like to make foo2() belong to a mock object (in real life these functions/classes are vastly more complex and involve interaction with hardware configurations etc thus the need for mock objects/functions). Until now we have done something like this but it is really not optimal because the code seems to have side effects on other unit tests.
class MockSomeOtherClass
{
public:
foo2() { … } // mock function
};
#define SomeOtherClass MockSomeOtherClass
#include “ClassToTest.cpp”
...
Is there a better way to do this without changing the original classes (or with minimal changes)? We use CPPUnit for testing.
EDIT: added tag winapi to more clearly describe out environment.
There is a product called Typemock Isolator++ that appears to address the issues you have raised. I have not tried it yet, so can't comment on how well it works or how easy/difficult it is to use.
Unfortunately, you have to give them your email address to try it. The download is easy enough, but then you are redirected to this page which cheerfully directs you to "Register your software now to get a FREE trial! Please enter your details including a valid email in order to receive your activation key to start using Isolator++."

Does Mock Objects in C++ Always Requires Virtual Methods or Templates?

Suppose I have classes
class Inner {
public:
void doSomething();
};
class Outer {
public:
Outer(Inner *inner); // Dependency injection.
void callInner();
};
Proper unit-testing says I should have tests for Inner. Then, I should have tests for Outer that uses not a real Inner but rather a MockInner so that I would be performing unit-tests on the functionality added by just Outer instead of the full stack Outer/Inner.
To do so, Googletest seems to suggest turning Inner into a pure abstract class (interface) like this:
// Introduced merely for the sake of unit-testing.
struct InnerInterface {
void doSomething() = 0;
};
// Used in production.
class Inner : public InnerInterface {
public:
/* override */ void doSomething();
};
// Used in unit-tests.
class MockInner : public InnerInterface {
public:
/* override */ void doSomething();
};
class Outer {
public:
Outer(Inner *inner); // Dependency injection.
void callInner();
};
So, in production code, I would use Outer(new Inner); while in test, Outer(new MockInner).
OK. Seems nice in theory, but when I started using this idea throughout the code, I find myself creating a pure abstract class for every freaking class. It's a lot of boiler-plate typing, even if you can ignore the slight run-time performance degradable due to the unnecessary virtual dispatch.
An alternative approach is to use templates as in the following:
class Inner {
public:
void doSomething();
};
class MockInner {
public:
void doSomething();
};
template<class I>
class Outer {
public:
Outer(I *inner);
void callInner();
};
// In production, use
Outer<Inner> obj;
// In test, use
Outer<MockInner> test_obj;
This avoids the boiler-plating and the unnecessary virtual dispatch; but now my entire codebase is in the freaking header files, which makes it impossible to hide source implementations (not to mention dealing with frustrating template compilation errors and the long build time).
Are those two methods, virtuals and templates, the only ways to do proper unit-testing? Are there better ways to do proper unit-testing?
By proper unit-testing, I mean each unit-test tests only the functionalities introduced by that unit but not the unit's dependencies also.
I don't think you must mock out every dependency of your tested class in practice. If it is complicated to create, use or sense through, then yes. Also if it directly depends on some unneeded external resource such as a DB, network or filesystem.
But if none of these is an issue, IMO it is OK to just use an instance of it directly. As you already unit tested it, you can be reasonably sure that it works as expected and doesn't interfere with higher-level unit tests.
I personally prefer working unit tests and simple, clean, maintainable design over adhering to some ideal set up by unit test purists.
each unit-test tests only the functionalities introduced by that unit but not the unit's dependencies also.
Using a functionality and testing a functionality are two very different things.
I also think that using an instance on Inner directly is OK.
My problem is mocking external objects that are not part of my code (provided through static libraries or DLLs, sometimes 3rd party).
I am inclined to rewrite a mock DLL or library with the same class names, and then linking differently for test. Modifying the header file of the external dependency to add "virtual"s seems unacceptable to me.
Does anyone have a better solution?