University of Leeds

Testing projects

Introduction

Up to this point we have focussed on simple unit tests and everything has been placed in one source file. However, this does not scale well to larger projects. We will now consider how to split up the main file, functions (or classes) and test functions.

Project Structure

The image below shows a suggested approach for larger projects. This is assuming more of a C-like approach in which a series of functions are placed in file separate from main(). However, it is equally applicable for classes in which each class will have its own tests defined in a separate file.

Diagram showing files in a software project.

Note how the testing files must include the function header so that it can call the functions to test them.

Makefiles

When working with projects that span multiple files, it is sensible to use a makefile for compiling. It is possible to add in extra commands to a makefile so that you can specify a debug build.

Makefile

# Set compiler
CC = g++

#Compile flags (-c to output object file .o)
CFLAGS = -c -Wall -Wextra -Wpedantic -std=c++11

all: main.exe

debug: CFLAGS += -DDEBUG -g
debug: main.exe

main.exe: main.o tests.o funcs.o
	$(CC) main.o tests.o funcs.o -o main.exe

main.o: main.cpp
	$(CC) $(CFLAGS) main.cpp

tests.o: tests.cpp
	$(CC) $(CFLAGS) tests.cpp

funcs.o: funcs.cpp
	$(CC) $(CFLAGS) funcs.cpp

clean:
	rm *.o main.exe

We can see that there are now debug: commands in the makefile. When this command is used, it just adds in additional flags to be used for compiling and then tells it to build main.exe. Note the extra flags used for warnings. These are -Wextra and -Wpedantic. These just tell the compiler to be extra pedantic when looking for potential problems with the code so we cna ensure we can as many problems as possible.

To build the project, we can simply type

make

or else

make all

If we wish to build the project using the debug configuration we can simply do

make debug

Note that if you then wish to build again and remove the debug, you will have to run

make clean

before you can re-build.

Using only object files

Note that you do not have to have all the source files to build the project, if you have the corresponding .o object files. For example, you may be working on a project in which you are required to write some functions. You are not involved in working on the main file and someone else has written the tests. You only need to modify funcs.h and funcs.cpp. Your team members may just provide you with main.o and tests.o. You can then focus on writing the functions and then only need to link to the provided object files. This ensures that you do not accidentally modify files you are not meant to be working on.

Diagram showing how to link .o files

The makefile to enable the above is shown below.

# Set compiler
CC = g++

#Compile flags (-c to output object file .o)
CFLAGS = -c -Wall -Wextra -Wpedantic -std=c++11

all: main.exe

debug: CFLAGS += -DDEBUG -g
debug: main.exe

main.exe: main.o tests.o funcs.o
	$(CC) main.o tests.o funcs.o -o main.exe

funcs.o: funcs.cpp
	$(CC) $(CFLAGS) funcs.cpp

clean:
	rm funcs.o main.exe