Developing the CODESYS runtime with TDD



I was recently working in the CODESYS runtime again, developing some components for a client and I thought the experience wold make the basis of a good post on bringing legacy code into a test environment, to enable Test Driven Development (TDD)

The CODESYS runtime is a component based system, and for most device manufacturers is delivered as a binary for their target system and a collection of header files and interface definitions. Much of the interface is generic, however there are platform specific headers that abstract the underlying RTOS. Device manufacturers often develop bespoke runtime components, to access proprietary IO for example. To help with this the delivered software package includes template components as a starting point for development. This means that, according to Michael Feathers definition of legacy code (code without tests), the starting point when developing a CODESYS component is legacy code. In this example the starting point was a partially developed component, legacy code.


The Plan

I tend to follow a fairly standard process when bringing legacy code under test. The basic process is well described in TDD How-to: Get your legacy C into a test harness on James Grenning’s blog.  I follow roughly the same process, with minor changes, my process can be summarised as follows

  • Select appropriate tools
  • Create a test harness with no reference to the code to be tested and a dummy failing test. Observe it fail. Fix the test and observe it pass.
  • Decide the boundaries of the code I want to test, and include this source in the test harness build.
  • Make the test harness compile (not link)
  • Make the code Link using exploding fakes.
  • Ensure the dummy test still passes
  • Add the first test of the code under test (expect it to crash or fail)
  • Make the test pass by adding initialisation, and using better fakes.
  • Add more tests, always observe them fail (force a failure if needs be – to check that the error output is meaningful), factor out common code into helper functions. Keep the tests small and testing one thing.
  • Add profiling, I like to be able to observe which parts of the code are under test before I make any changes. Particularly if the code under test has large complex functions it is the only way that I trust I have sufficient coverage before making code changes.


The development build of the component uses a gcc cross compiler on linux. The build is controlled by a makefile and there is already an eclipse project.

I will use the native gcc compiler to run the tests

For the testing framework I’m using googletest 1.8, my preferred test framework for C and C++

To help with creating fakes and mocks I will use Mike Long’s Fake Function Framework (fff).

I will add plugins to eclipse so that the whole process can happen in a single environment.


The first test

There are two ways of using googletest, one is to build it as a library and link it to the tests, the other is to fuse the source into a single file, and then include the fused source in the tests. On linux I tend to just build the library with default settings.

I’ve created a new folder called UnitTests to which I’ve added a makefile and a single source file with this content

#include "gtest/gtest.h"
TEST(FirstTest, ShouldPass)
} // namespace

The makefile, references just this source file, the include path has the path to googletest/include. The link line is shown below (I’ve omitted the paths for simplicity)

g++ FirstTest.o gtest_main.a -lpthread -o UnitTest

This builds, and when run fails as below


Change the the ASSERT_EQ so that the test passes, rebuild and re-run the tests.

Compiling with the UUT

The CODESYS component that that I’m working on consists of a single source file (The Unit Under Test UUT), and it links into a target specific library

To get the test application to compile I had to add three directories to the include path


NOTE: If the CODESYS runtime delivery is for a different operating system to the development system then it may be necessary to create fake versions of the headers in the Platforms directory. It may also be necessary to fake some of the RTOS header files.

Linking – Exploding Fakes

Having resolved the includes there are lots of unresolved symbols. A good starting point is to generate a file of exploding fakes, the idea here is to ensure that you know when you are faking code. Have a look at James’ exploding fake generator, this can easily be adapted to any linker and any test framework. Save the output of your failed link into a file, execute to generate a file of exploding fakes which you include into your build.

make >& make.out make.out explodingfake.c

The only other change required is to copy explodingfakes.h somewhere on the include path for the tests and adapt it to work with gtest as shown.

#include "gtest/gtest.h"
#define EXPLODING_FAKE_FOR(f) void f() { FAIL() << "go write a proper stub for " #f; }

Now the test application should run and pass again, none of the UUT is yet being executed.


Testing – Part 1

CODESYS components have well defined interfaces, and I find it pays to test from those interfaces rather then exposing internals of the component wherever possible. Taking this approach tends to lead to less fragile tests that are testing the functionality rather than the implementation.

All components implement CmpItf, an interface that allows the component to be registered and initialised. CmpItf requires a single extern function ComponentEntry to be declared, all other functions in the interface are accessed through function pointers returned by this function call. So my starting point is to write tests that test this interface.

The first tests are straight forward, and soon the ComponentEntry call itself is factored out into the test constructor.

#include "gtest/gtest.h"
extern "C"
#include "CmpMyComponentDep.h"
DLL_DECL RTS_INT CDECL ComponentEntry(INIT_STRUCT *pInitStruct);
class CmpItfTest: public ::testing::Test
m_rResult = ComponentEntry(&m_InitStruct);
RTS_RESULT m_rResult;
INIT_STRUCT m_InitStruct;
TEST_F(CmpItfTest, ComponentEntryShouldSucceed)
ASSERT_EQ(ERR_OK, m_rResult);
TEST_F(CmpItfTest, ComponentEntryShouldSetComponentID)
ASSERT_EQ(0x166B2002, m_InitStruct.CmpId);
TEST_F(CmpItfTest, CmpGetVersionShouldReturnCorrectVersion)
ASSERT_EQ(0x03050800, m_InitStruct.pfGetVersion());

Fairly soon I am testing code that calls into other CODESYS components, as soon as I do, the exploding fakes show up in the tests.



Using The Fake Function Framework

Now I need a more powerful fake, this is where the fake function framework comes in to it’s own. Creating a fake for EventOpen can be as simple as adding the following to the test source file, and making sure fff.h is on the include path

#include "fff.h"
#include "CmpEventMgrItf.h"

Having added this the link will fail with a message like

CmpEventMgrItf.fff.c:7: multiple definition of `EventOpen'

Remove the line from explodingfakes.c for EventOpen, and the tests should now run again.

It is then possible to write a simple test to prove that the EventOpen function has been called.

TEST_F(CmpItfTest, HookCH_INIT3ShouldOpenEvent)
    ASSERT_EQ(1, EventOpen_fake.call_count);

The Fake Function Framework includes facilities for recording a history of argument calls, setting return values and the ability to provide a custom fake. It makes a very powerful tool for testing C code, I’m not going to cover all of the features here there are plenty of other examples on the web. Do note though that fakes need to be reset for each new test. The constructor for my test fixture looks like this

    m_rResult = ComponentEntry(&m_InitStruct);

As tests grow and there become multiple test files using the same fakes it makes sense to pull the fakes out into separate files,. I follow a pattern, if I am faking functions defined in a file called XXX.h, I create XXX.fff.h and XXX.fff.c and define my fakes in these files. Most of the time I take the approach of generating each fake manually, one by one as required.

CODESYS specifies the interface to all components in .m4 files, in the delivery I have there are 164 interface files specified. I know that over time these interfaces will be extended, and more interfaces added. I have generated a tool to process the interface definitions and automatically generate fff fakes for each API function in each of the interfaces. I then build these fakes into a static library that can be linked with any component I develop.

There is a danger in automating fake generation, it becomes very easy to not realise when you are using a fake. Most API functions in CODESYS return an RTS_RESULT, ERR_OK means success. ERR_OK has the value of zero which is also the default value returned by fff fakes. If developing new code this isn’t a problem. But when bringing a legacy component under test it can lead to code appearing to be tested when it isn’t. This can be avoided by still using exploding fakes within fff.

To achieve all of this using the test library all I need in the tests is an include of the appropriate fake header file,

#include “CmpEventMgrItf.fff.h”

and the test constructor is changed to reset all of the CmpEventMgrItf fakes, set all of the fakes to explode, and then for the two functions that I want to fake I can disable the exploding behaviour.

    m_rResult = ComponentEntry(&m_InitStruct);
// Allow normal fake operation for these functions, all others in the interface will explode if called.
EventOpen_fake.custom_fake = NULL; 
EventRegisterCallbackFunction_fake.custom_fake = NULL;

What does the fakes library look like?

To show what is included in the library of fakes, for those who are interested below is the content of the CmpEventMgrItf fakes cut down to show just the two functions that have been used.


#ifndef __CmpEventMgrItf__FFF_H__
#define __CmpEventMgrItf__FFF_H__
#include "fff.h"
#include <string.h>
#include "fff_explode.h"
#include "CmpEventMgrItf.h"
DECLARE_FAKE_VALUE_FUNC2( RTS_RESULT, EventRegisterCallback , RTS_HANDLE , ICmpEventCallback * );
RTS_RESULT EventRegisterCallback_explode( RTS_HANDLE , ICmpEventCallback * );
#define FFF_CmpEventMgrItf_FAKES_LIST(FAKE) 
#endif /* __CmpEventMgrItf__FFF_H__ */

Other than including headers three things are happening in this file. Firstly the fff fakes are declared, secondly prototypes for exploding functions are declared and finally a list of all faked functions is created allowing operations to be done on all fakes in one statement.


#include "CmpEventMgrItf.fff.h"
DEFINE_FAKE_VALUE_FUNC2( RTS_RESULT, EventRegisterCallback , RTS_HANDLE , ICmpEventCallback * );
RTS_HANDLE EventOpen_explode( EVENTID  a, CMPID  b, RTS_RESULT * z ){ fff_explode("EventOpen"); return (RTS_HANDLE)0; }
RTS_RESULT EventRegisterCallback_explode( RTS_HANDLE  a, ICmpEventCallback * z ){ fff_explode("EventRegisterCallback"); return (RTS_RESULT)0; }

The fff fakes are defined along with definitions of the exploding fakes. Each exploding fake calls fff_explode, which is declared in a separate module allowing the way it explodes to be changed for a different testing tool..


#ifndef __FFF_EXPLODE_H__
#define __FFF_EXPLODE_H__
#define FFF_EXPLODE(a) a##_fake.custom_fake = a##_explode;
#ifdef __cplusplus
extern "C"
void fff_explode(const char * func);
#ifdef __cplusplus
#endif /* __FFF_EXPLODE_H__ */

The macro FFF_EXPLODE(a)  sets the custom_fake variable in an fff fake to point to the exploding fake.


#include "fff_explode.h"
#include "gtest/gtest.h"
#ifdef __cplusplus
extern "C"
void fff_explode(const char * func)
    FAIL()<<"Time to use fake for "<<func;
#ifdef __cplusplus

Keeping it fast

As I mentioned in the tools section the production code is being built in eclipse. I want to build the test code in eclipse as well, and I want everything to work seamlessly.

I added a second Build Configuration to the production code build, and made this build the unit tests. Having done this I want to run the tests every time I build (Or rather I want to run the tests after every code change, and have the code rebuilt if required). This requires an optional component to be installed in eclipse. Go to Help->Install New Software…, choose to Work with: –All Available Sites– and then under Programming Languages select C/C++ Unit Testing Support, click Next>, Next>, Finish and wait for the install to complete. Restart eclipse when prompted.

Now right click on your project in eclipse and selectRun As->Run Configurations... Create a new C/C++ Unit Test configuration. Use Search Project to find your Unit Test application, then on the C/C++ Testing tab, select Google Tests Runner.


When you run this configuration, it should force your tests to be built and then display the results graphically. Clicking on any failures will take you to the failing tests.



Particularly when bringing legacy code under test, I like to be able to visualise what is being tested and what isn’t. If you are using gcc then this becomes very easy.

Add these compiler flags to the compilation of the unit under test, and to the link line.

-fprofile-arcs -ftest-coverage

Building and then running with profiling generates .gcda and .gcno files, these are specific to a particular build, so to ensure there are no mismatches in versions add to the link rule in the makefile an action to remove all .gcda and .gcno files from the object directory.

Now having run your tests look in the object directory in eclipse and you will see .gcda and .gcno files, double click one of them. In the dialog that pops up, ensure that your unit test executable is selected, and choose “Show coverage for the whole selected binary“.

For me the key is not the amount of code covered, much more, what has been covered by my tests. Each file can be inspected and it is very clear what was run by the tests and what wasn’t. This helps me decide if I have sufficient coverage before making changes. For example, the bars below show that my tests don’t cover all of the initialisation functions.


ExportFunctions is a standard function that is part of all components, the implementation shouldn’t change. The image below shows that the test suite invokes it, but there must be a return statement inside the EXPORT_STMT. Without code coverage I may never have known that some of the code wasn’t being exercised. Inspecting the code will then tell me if I need to add tests or not. This may be a trivial example but I hope it shows why inspecting test coverage helps you understand what is being tested. You can then make informed decisions about increasing the coverage, or accepting that you have gone far enough.


Once I’m happy with the coverage in an area I want to change I can start more traditional TDD development. Having started TDD, I tend not to use code coverage checks very often. Being rigorous about TDD tends to lead to 100% coverage, the main time I re-use the coverage checks is if I have refactored the UUT, it helps to show not just that the existing functionality still passes, but that I haven’t inadvertently added some untested functionality.

Summary and next steps

Investing the time to get the component under test has given me a re-useable test harness that allows me to extend and refactor the code with confidence. Future development can happen much faster than it would otherwise, as much of the functionality can be proven before taking the software anywhere near the embedded target.

Some components it is worth investing the time to create pre-canned functionality through custom_fakes. Consider these components


With no further work fff can be used to simulate failures, check the sizes being allocated and return fixed data structures on allocations. However in some tests we just want the memory allocation to work, so having a simple set of custom fakes that can be used to delegate these calls functional equivalents is worth while. Another useful extension can be to track allocation and freeing of memory, then in a test fixture setup tracking can be enabled, and in the teardown it can be checked.


This component provides string manipulation and other utility functions, in most cases it is preferable to have a working double than the standard fff fake. If you have a source code distribution of the runtime code I would attempt to link this with the tests.

SysTime and SysTimeRTC

One of the great advantages of Unit Testing in embedded systems is being able to run tests faster than realtime. Develop custom_fakes that allow you to take control of the progress of time.

Continuous Integration

Tests are only useful when they are run. Setting up a continuous integration system to build and test each component every time there is a change to the source code is the way to go.

Continuous Delivery

How far can you go towards continuous delivery? Using a combination of free tools, and the CODESYS Test Manager I have set up delivery pipelines that build the embedded code, run unit tests, performed static analysis, generated documentation, package up instrument firmware packages, build and test CODESYS libraries, automated version number management, create CODESYS packages, deploy the code into test systems and invoke automated testing (integration and system). If the tests all pass then the packages can be promoted to potential release candidates ready for final human validation as required.


gcov code coverage in eclipse and Jenkins


This post gives step by step instructions for adding code coverage with gcov to a google test eclipse project that is built as part of a CI process on Jenkins. This post starts from the point of already having a project compiled by a gnu compiler, in an eclipse CDT project that is being build on Jenkins. These posts give the information required to get to this stage.

Using google test with CDT in eclipse
Integrating SVN, Trac and Jenkins with eclipse
Automating eclipse CDT build on Jenkins

To enable code coverage with gcov the project needs to be instrumented (build with flags that cause the raw coverage information to be saved when an executable runs). Having built the code with these flags enabled, and run the executable, both eclipse and Jenkins can be configured to view the coverage.

Enabling code coverage in the build

To determine what code coverage the unit tests have in the unit test project in eclipse: Right click on the project and select Properties->C/C++ Build->Settings->Tool Settings->GCC C++ Compiler->Debugging and check Generate gov information (-ftest-coverage -profile-arcs).

Still in the Properties->C/C++ Build->Settings->Tool Settings select MinGW C++ Linker->Miscellaneous and then in the Linker flags box add -ftest-coverage -fprofile-arcs.
Click OK to close the properties dialog. clean the project and the build, then look in the Debug folder and there should be a .gcno file for every source file.

Coverage Reports in eclipse

CDT includes support for gov, however this support relies on external tools that must be in the path. I tried to add them to the path in the eclipse project, I couldn’t get it to work, so I had to extend the Windows environment variable path. The path needs to include a path to addr2line, c++filt and nm, with my install of minGW I added c:mingwbin. Shutdown and restart eclipse so that it has access to the new path.
Now run your unit test application in eclipse, this will generate a .gcda for each source file. Now if you open any .gcda or .gcno file you should see
Click OK and the gov tab should be opened with coverage shown
NOTE: If you get an error here the most likely reason is that the gcov data is not all from a single binary version of the test application. The quick way to resolve this is to delete the Debug directory, rebuild and rerun the tests.
NOTE: When you double click on a file in the gov tab it opens the associated source file and should show line by line the coverage. Except in my scenario it doesn’t for linked folders. To see line by line coverage open the file of interest from the linked folders, open the file from under the unit test project, the coverage will show. This is being tracked as bug 447554 in the eclipse bugzilla. (Update 9 January 2016 – This is now fixed in updates-nightly-mars, Thank you Jeff)

Coverage in Jenkins

To get a coverage report added to the Jenkins job we have to convert the gcov output into a a format that can be understood by Jenkins (using gcovr) and then configure Jenkins with the cobertura plugin.


gcovr is a python application, so before it can be used you need python installed on the jenkins slave. Download and install active python from In my case I downloaded the ActivePython (x64). I accepted all defaults on the installer.
Open a command prompt and install gcovr
pypm -g install gcovr

I found it very hard to get the correct options on gcovr for the files I wanted in the output. I installed activepython and gcovr in the same way on my desktop machine, and experimented in the eclipse workspace. For me with an eclipse workspace at C:UsersDavidworkspace. Running the command below from C:UsersDavidworkspacehex2numSource I got the desired output. i.e. coverage for each source and include file being tested in hex2num.

python c:Python27Scriptsgcovr -r . –object-directory= ….hex2numUnitTestDebug -f .*\hex2num\Include\ -f .*\hex2num\Source\ 


Cobertura is a plugin for Jenkins that displays code coverage. To install the plugin login to Jenkins and go to Manage Jenkins->Mange Plugins->Available, select Cobertura Plugin, click Install without Restart.

For the Jenkins job you are configuring (in this example hex2num) go to the job configuration page, select Add Build Step->Execute Windows batch command. Add the following to go to the correct directory, I have added flags to generate xml output to a named file.

cd hex2numsource

python c:Python27Scriptsgcovr -r . –object-directory= ….hex2numUnitTestDebug -f .*\hex2num\Include\ -f .*\hex2num\Source\ -x -o ….gcovr.xml

Then select Add post-build action->Publish Cobertura Coverage Report, enter the path to the generated results file. Selecting Advanced allows a variety of options to be set.
Run a build and you should start to see code coverage reports, once a second build has been run you should start to see graphs. You can also drill in for more details.

Getting painted files to show in Cobertura

Although cobertura is displaying coverage there are two problems
  1. The package names don’t read well
  2. Painted source files don’t show as cobertura cannot find the source files

To resolve this I wrote a small python script to patch the paths in the gcovr.xml files. Save this source as

import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
import sys
paths = sys.argv[2:]

tree = ET.ElementTree(file=gcovrXmlFilename)
for packageElement,path in zip(tree.iter(tag=’package’),paths):
for classElement in packageElement.iterfind(‘classes/class’):
filename = classElement.get(‘filename’)
filename = filename.split(‘\’)[-1:][0]
filename = path+”/”+filename
classElement.set(‘filename’, filename)

In the jenkins job, change the windows batch command that runs gcovr so that it looks like this.

The script reads the file in the first argument (gcovr.xml), renames the first package(directory) to the next argument and sets the path for all classes (files) in the package, the second argument is processed similarly. More arguments can be added for additional packages.
In Jenkins you can then see nicely painted sources like this

Automating eclipse CDT build on Jenkins

In my previous posts I have shown how to setup Jenkins to work with SVN and trac running on the Raspberry PI. I have also shown how to configure eclipse to work with google test and how to configure eclipse to work with SVN and trac. This post covers how to automate the build of the eclipse projects under Jenkins and how automate running the unit tests.

Jenkins Configuration

Jenkins Slave Setup

First of all install all of the tools that you need for your build on a Jenkins slave, in my case eclipse CDT with a selection of plugins, and Mingw. Eclipse is not on the path by default, so I created a system environment variable ECLIPSE_DIR on the slave, with the path to where eclipse is installed. I also restarted the Jenkins slave service so that it had access to the new environment variable.
Decide on a label for these tools, I will use two, eclipse mingw. Login to Jenkins to add the labels to the slave with the tools installed. Go to Manage Jenkins->Manage Nodes, select the node and add the labels


Jenkins Job Configuration

Add the job to Jenkins, from the Jenkins home page select New Item, name the job and select Freestyle project, click OK. My example project is called Hex2Num, a simple utility I’ve written, it consists of two eclipse projects (a unit test project and the application), the unit tests are written using googletest, documentation is handled with doxygen, gcov is used for code coverage.
There is quite a bit of configuration, on the job page, so section by section

Name and Description

Fill in a meaningful description


If you are using trac and have integrated trac and Jenkins (see Integrating Trac and Jenkins) then fill in the URL to access trac.

Restricting where the build runs

Only the build to run on slaves that have the labels mingW and eclipse
Source Code Management

The source is stored in a single module in subversion, fill in the URL and any required credentials.


Click Add build step->Execute windows batch command, this command builds all of the projects in the workspace as DEBUG.


Click Add Post-Build action->Scan for compiler warnings and select gnu 4


Google Tests

Go back and add another  build step, Click Add build step->Execute windows batch command, this command executes the unit test application and generates an xml results file that can be interpreted as Unit results.
Add another post-build action, Click Add Post-Build action->Publish Unit test result report and enter the name of the result file.


After a few builds have been run two graphs will appear on the Jenkins page for the job.

Using Google Test with CDT in eclipse


I like to use test driven development, currently my preferred framework is googletest. When I came to use eclipse CDT with the MinGW toolchain I found I had lots of little issues to get over to achieve what I wanted, namely a rapid TDD environment that I could also build from the command line (so that it can be automated under Jenkins). This post collects together the steps to get a simple application and associated unit test application building.



Clicked the Download Installer button on the MinGw home page This downloads an installer for MinGW. I then selected the following components


eclipse CDT

I downloaded the Eclipse Installer from and ran the install selecting the C/C++ development environment.

Create Projects

My personal preference is to have two projects for a component, the actual component (executable, library etc), and an executable that is a unit test for the code in that component. I find this works well for me as a pattern because it works the same if I am working on a library or cross compiling.
Launch eclipse, close the welcome menu and you should end up in the C/C++ perspective. In the Project Explorer right click and select new C/C++ Project. Select Executable->Empty Project and the MinGW GCC toolchain, give your project a name, for this example I have chosen the name demo.
Click Finish. Then right click on the project and add a new folder called Main, in that folder create a new file called demo.cpp. In Main.cpp create a minimal main function as shown and save the file. (If you forget to save you may well see an error about undefined reference to WinMain@16)
int main(int argc, char **argv)
return -1;
When I got to this point I found that I could build the program, and debug it without error. But if I tried to run it windows pops up an error saying that demo.exe has stopped working. This can be resolved by changing the linker flags. On the demo project, select properties then C/C++ Build->Settings. Set the Configuration to [All Configurations], then under Tool Settings select MinGW C++ Linker->Miscellaneous and in the Linker flags box type -static-libgcc -static-libstdc++ as shown.
You should now be able to build, run and debug demo.exe.
Repeat the above process to create a second project called demotest, ensure that you can build, run and debug remotest too.

Add Googletest to the test project

I downloaded googletest-release-1.7.0 from and unzipped the content locally. Google now recommend compiling google test with each project, the easiest way of achieving this I find is merging google test into a single header and source file. To do this you need python installed, I downloaded and installed python 2.7.10 from
Then open a command prompt in the root of the unzipped googletest-release-1.7.0 directory and run . <demotest project dir>contrib
where <demotest project dir> is the path to the demotest project in your workspace. Now open eclipse and you should see gtest in the demotest project.
Next we need to ensure that the include path finds the test headers to do this, open the properties dialog for the remotest project. Under C/C++ General->Paths and Symbols, select [All Configurations] and GNU C++, then add the contrib include directory as a workspace include.
Prove the project still builds – For me it builds with a single compiler warning – I will ignore that for now.
The next step is to add code to run google test. Edit demotestMainMain.cpp so that it has the content below
#include “gtest/gtest.h”
int main(int argc, char **argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
At this point if you build and run you should get this output.
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[  PASSED  ] 0 tests.

Starting TDD

The first test I want is to prove that my demo.exe returns 0 when called with no arguments.
First addd a folder called Tests to the remotest project, in that create a
Create two folders in the demo project called Source and Include. In the demotest project add a folder called Tests, and in that a new file DemoTest.cpp with this content
class DemoMainTest : public :: testing::Test
ASSERT_EQ(0, ::Demo(0, NULL));
A TDD purist would say I am doing too much at once, this adds a test to show that a function called Demo, called with two NULL arguments returns 0. If you try to compile now the build will fail because the file demo.h doesn’t exist.
To get this to compile and link we need to add the file Demo.h and Demo.cpp, but these files should actually be part of the demo project and not demotest.
In the demo project add a new folder Include and in that add Demo.h with this content
int Demo(int argc, char **argv);
Still in the demo project ass a new folder Source and in that add Demo.cpp with this content
int Demo(int argc, char **argv)
return -1;
In the demo project properties, under C/C++ General->Paths and Symbols, select [All Configurations] and GNU C++, then add the Include directory as a workspace Include.
Also edit the existing Main.cpp in the demo project to call the demo function.
#include “demo.h”
int main(int argc, char **argv)
return Demo(argc,argv);

At this stage the demo project should compile and link.

We now need to get the demotest project to reference this source and include path.
In the demotest project properties under C/C++ General->Paths and Symbols, in the Source Location tab click the Link Folder… button, click Advanced>> , check Link to folder in the file system, click Variables…, select WORKSPACE_LOC and click Extend…, find demo/source, click OK all the way out.
In the demotest project properties under C/C++ General->Paths and Symbols, select [All Configurations] and GNU C++, then add the Include directory as a workspace include.
All being well, the workspace should now look like this
You can now build, and run, the test should fail
[==========] Running 1 test from 1 test case.
[———-] Global test environment set-up.
[———-] 1 test from DemoMainTest
[ RUN      ] DemoMainTest.Returns0
..TestsDemoTest.cpp:12: Failure
Value of: ::Demo(0, __null)
  Actual: -1
Expected: 0
[  FAILED  ] DemoMainTest.Returns0 (0 ms)
[———-] 1 test from DemoMainTest (0 ms total)
[———-] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] DemoMainTest.Returns0
Change the return value in Demo.cpp to 0, save, rebuild and re-run and the test should pass.
[==========] Running 1 test from 1 test case.
[———-] Global test environment set-up.
[———-] 1 test from DemoMainTest
[ RUN      ] DemoMainTest.Returns0
[       OK ] DemoMainTest.Returns0 (0 ms)
[———-] 1 test from DemoMainTest (0 ms total)
[———-] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.
Now we are in a good position to start TDDing, as long as you add test files to the Tests folder, source to the Source folder and include files to the includes folder there should be no further need to mess with the build.

Test Runner

At this stage we are up and running, but it is still a bit clunky running the tests. Fortunately eclipse CDT has a test runner that supports google test. Unfortunately it is not installed by default. To install go to Help->Install New Software…, choose to Work with: –All Available Sites– and then under Programming Languages select C/C++ Unit Testing Support, click Next>, Next>, Finish and wait for the install to complete.
Restart eclipse when prompted.
Select Window->Show View->Other… and select C/C++ Unit
In the Project Explorer right click on demotest and then Run As->Run Configurations…, double click C/C++ Unit and then under the C/C++ Testing tab select Google Tests Runner.
Click Run and all being well you should see
Now you can really start moving with TDD 🙂

Version Control

At this stage it is a good idea to put the project under version control. Under eclipse the workspace is specific to a single folder on a specific machine, so it should not normally be placed under version control. Also any files generated by the build do not need to be version controlled, so before looking at what files to version control clean both projects from inside eclipse. If you are not using eclipse to manage your version control it is then a good idea to exit eclipse.
Using explorer the workspace looks like this
Both the RemoteSystemsTempFiles and .metadata folders are created by eclipse and do not need to be version controlled. The Debug folder under each project is created when a Debug build is performed and also does not need to be version controlled, if a Release build has been performed then there will be a folder called Release, again this doesn’t need to be version controlled. Everything else should be placed under version control.
To prove you have everything required under version control, it is a good idea at this point to verify that a clean checkout of your code builds. To do this create a new empty workspace directory (e.g. Workspace2) and checkout the projects from your version control system into that workspace. Then launch eclipse and select Workspace2 as your workspace
When eclipse starts there will be no projects in the Project Explorer, even though the projects exist in the Workspace2 folder on the file system. Right click in the Project Explorer and select Import…, then General->Existing Projects into Workspace
click Next>, then Browse…, this will open a Browse For Folder dialog opened on the workspace, click OK.
Then click Finish on the Import dialog, both projects should then be imported and can be build as before.
NOTE: Depending on your version control system and any plugins that may be installed you may be able to import projects directly from the VCS into a new workspace.

Command Line Build

The managed build in eclipse CDT is very easy to manage when working in the GUI, however there are situations when a command line build is required, such as when projects need to be built by a continuous integration system. Typically under CI the command line will need to cope with the situation where projects have been checked out from the VCS into a clean workspace folder, this example when executed from the root of the workspace folder creates the eclipse workspace artefacts, imports all of the projects in the workspace and builds the Debug configuration for each project.

<path to eclipse>eclipsec.exe –launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -data . -importAll . -no-indexer -build “.*/Debug”

The first few arguments on this command line are standard eclipse arguments, see running eclipse and eclipse runtime arguments for details.
There are many other options – at the time of writing the options are
   -import     {[uri:/]/path/to/project}
   -importAll  {[uri:/]/path/to/projectTreeURI} Import all projects under URI
   -build      {project_name_reg_ex{/config_reg_ex} | all}
   -cleanBuild {project_name_reg_ex{/config_reg_ex} | all}
   -no-indexer Disable indexer
   -I          {include_path} additional include_path to add to tools
   -include    {include_file} additional include_file to pass to tools
   -D          {prepoc_define} addition preprocessor defines to pass to the tools
   -E          {var=value} replace/add value to environment variable when running all tools
   -Ea         {var=value} append value to environment variable when running all tools
   -Ep         {var=value} prepend value to environment variable when running all tools
   -Er         {var} remove/unset the given environment variable
   -T          {toolid} {optionid=value} replace a tool option value in each configuration built
   -Ta         {toolid} {optionid=value} append to a tool option value in each configuration built
   -Tp         {toolid} {optionid=value} prepend to a tool option value in each configuration built
   -Tr         {toolid} {optionid=value} remove a tool option value in each configuration built
               Tool option values are parsed as a string, comma separated list of strings or a boolean based on the option’s type