views:

79

answers:

3

Hi Guys,

This will probably be a bot of a waffly question but ill try my best.

I have a simple c++ program that i need to build testing for. I have 2 Classes i use besides the one i actually am using, these are called WebServer and BusinessLogicLayer.

To test my own code i have made my own versions of these classes that feed dummy data to my class to test it functionality.

I need to know a way of somehow, via a makefile for instance, how to tell the source code to use the test classes over the normally used classes. The test classes are in a different "tester" c++ file, and the tester c++ file also has its own header file.

Regards

Paul

P.S. This is probably a badly worded question, but i dont know any better way to put my question.

A: 

You can define abstract base classes that declare the public interfaces for your components, then wire the objects together at runtime (in main() or something else fairly high up in the food chain). In testing, you simply wire up different objects.

Marcelo Cantos
"Wiring up" different objects at runtime is not trivial. It will require recoding wherever WebServer or BusinessLogicLayer are constructed on the stack (which I admit shouldn't be many places for these classes). If you make the decision at a high level (e.g. in main()) then you have to pass it down somehow to the classes that need it. WebServer and BusinessLogicLayer may be things you don't want to have real and phony versions of at the same time, which means you're "wiring up" classes, not objects. And if they have to be constructed before main() executes (e.g. static objects)... not trivial.
Beta
You can declare, say, the WebServer using a singleton interface. `main()` is responsible for creating the appropriate derived class instance and assigning it as the singleton to be returned. Code that wants to interacts with the WebServer simply accesses the singleton API. This is one of the few valid uses of singletons.
Marcelo Cantos
If both WebServer and BusinessLogicLayer can be singletons, you can get away with this. But then you must not have any static members initialized to point or refer to them (which would be a natural thing to do) *either now or in future revisions of the code*. Also anyone who wants to build a working version must have the testing code too, or the linking will fail. And this method is not extensible to your other, non-singleton classes.
Beta
Yes, there are gotchas with singletons. Of course, there's more than one way to use singletons. You could instead define a factory class as the singleton, thus allowing the code base to instantiate as many WebServers as it wants and with no dependency on static data, while still leaving it to `main()` to decide which WebServer derived class will be created.
Marcelo Cantos
A: 

To build debug and release versions of a program with source code in directories ${SRC_DIR_1} and ${SRC_DIR_2}:

CXX      := g++
CPPFLAGS  = ...
CXXFLAGS  = ...

SRC_DIR_1 := ...
SRC_DIR_2 := ...

ifeq (${debug},1)
  BIN_DIR  := ./obj_debug
  CXXFLAGS += -g
else
  BIN_DIR  := ./obj_release
  CXXFLAGS += -DNDEBUG
endif

# Make sure that the directory exists.
TEMP := ${shell test -d ${BIN_DIR} || mkdir ${BIN_DIR}}

# Tell make to search each directory
VPATH := ${SRC_DIR_1}:${SRC_DIR_2}

# You can modify this to use a suffix other than .cc
${BIN_DIR}/%.o : %.cc
    ${CXX} ${CPPFLAGS} ${CXXFLAGS} -c $< -o $@

# Build the requested version of the program.
ifeq (${debug},1)
  default: program_name_debug
else
  default: program_name
endif

tidy::
    @${RM} -r ./obj_*

In the Project Configuration dialog, specify the target name as "program_name, program_name_debug". (Replace program_name with the name of your program.)

To build the program, invoke "make debug=X" with X replaced by either 0 or 1.

Reference

anijhaw
A: 

Why does your tester code have a header file of its own? Your test code should have the same interface as the code it emulates, and using the same header file prevents a lot of headaches.

Anyway, this will work:

real_program: WebServer.o BusinessLogicLayer.o

test_program: tester.o

real_program test_program: MyClass.o OtherThings.o
    $(LINK) $^ -o $@
Beta