I have recently started trying to use TDD in one of my C++ projects. I am very new at this, and I have some very basic questions regarding to the way unit tests are compiled and used. I am using the Boost.Test library on Linux.
Is it common to compile a single large test program, containing all test suites, for all your units? How about splitting the tests into many smaller independent test programs?
How is linking handled (with
make
)? Every test program object must be linked with the object file(s) from my source program that contains whatever it is that's being tested. Is there a way to handle this automatically? To be more specific, is there anyway to write aMakefile
so thatmake
automatically determines what object files must be linked together to generate a certain unit test program?
Update: My code is organized in many .cpp/.h files, and is currently monolithic (no libraries). The unit tests are in a separate directory, usually in 1-to-1 relationship with the .cpp files from my source tree.
Update 2: Hoping that this will make my question less broad, here is an excerpt from the Makefile I am using:
$(TSTDIR)%.$(TEST): $(OBJDIR)%.$(TEST).$(OBJEXT) $(OBJDIR)%.$(OBJEXT)
@mkdir -p $(@D)
@$(CXX) -o $@ $^ $(TSTLIBS)
$(OBJDIR)%.$(OBJEXT): $(SRCDIR)%.$(SRCEXT) $(DEPDIR)%.$(DEPEXT)
@mkdir -p $(@D)
@$(CXX) $(CXXFLAGS) $(INCLUDES) -o $@ $<
$(TEST)
is just a marker I am using to differentiate between my unit tests and other files. Note that I am currently linking all test programs with the object file that bears the same name. However this will break if symbols from another object file are also needed.
Update 3: This is an example of what I am talking about in the above paragraph.
MyOtherClass.h:
class MyOtherClass
{
public:
int Foo();
}
MyOtherClass.cpp:
#include "MyOtherClass.h"
int MyOtherClass::Foo()
{
return 0;
}
MyClass.h:
#include "MyOtherClass.h"
class MyClass
{
public:
int Foo();
private:
MyOtherClass moc_;
}
MyClass.cpp:
#include "MyClass.h"
int MyClass::Foo()
{
return moc_.Foo();
}
TestMyClass.cpp would test if MyClass::Foo
returns 0. Using my current Makefile, this will not compile, as the test program needs to be linked with both MyClass.o and MyOtherClass.o.