Unit tests in c++ for a Java GUI

I have worked with C++ in my early days of programming (between 1997 and 2000), but I used to work with Borland C++ Builder and Microsoft Visual C++, in that time I have not heard about unit tests yet, after that I worked with Delphi, PHP, ASP, ColdFusion,  …
Since 2002 I worked most of the time with Java, and learned a lot since then, lots of good practices, a lot more about object orientation and I learned to love unit tests.
Little time ago I starter working with C++ again, but I’m already in love with unit tests, and want to do them for my C++ code too, and this post is a very short example of how a Java programmer can work with C++ and do unit tests.

A C++ project starts with a Makefile, I’m used with ANT and do not like the idea of enumerating all my source files in a build configuration file like most examples of Makefiles do, so I created a simple but very flexible Makefile for my project.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TESTDIRECTORIES := test
DIRECTORIES := src
SOURCES := $(foreach dir,$(DIRECTORIES),$(wildcard $(dir)/*.cpp))
TESTSOURCES := $(foreach dir,$(TESTDIRECTORIES),$(wildcard $(dir)/*.cpp))
OBJECTS := $(patsubst %.cpp,%.obj,$(SOURCES))
TESTOBJECTS := $(patsubst %.cpp,%.obj,$(TESTSOURCES))
TESTOBJECTS += $(filter-out src/main.obj,$(OBJECTS))
TARGET := example
LINK := g++
CC := g++
CFLAGS := -c
LFLAGS :=
 
all: $(OBJECTS)
	$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS)
 
test: $(TESTOBJECTS)
	$(LINK) $(LFLAGS) -lcppunit -o $(TARGET)_unit $(TESTOBJECTS) 
	./$(TARGET)_unit
 
%.obj:%.cpp
	$(CC) $(CFLAGS) -o $*.obj $*.cpp

With this make file, all cpp files in the src directory will be part of the target executable, more directories can be added just enumerating the source directories in the “DIRECTORIES” variable, the same for the test code, under the test directory and the “TESTDIRECTORIES” variable.
The trick here is the combination of the functions foreach and wildcard, the function pathsubst is used to change the extensions from .cpp to .obj and the filter-out function is used to remove the main.cpp (the entry point for the main application) from the test objects.
This Makefile is the nearest I could get from ANT functionality for C++ programming, but of course it can be improved a lot.
But the Makefile is not the target of this post, I’m writing this post to tell you about CppUnit, a great unit test framework for C++.
I started writing this unit test runner using CppUnit:
testRunner.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/BriefTestProgressListener.h>
 
int main (int argc, char* argv[])
{
    // informs test-listener about testresults
    CPPUNIT_NS :: TestResult testresult;
 
    // register listener for collecting the test-results
    CPPUNIT_NS :: TestResultCollector collectedresults;
    testresult.addListener (&collectedresults);
 
    // register listener for per-test progress output
    CPPUNIT_NS :: BriefTestProgressListener progress;
    testresult.addListener (&progress);
 
    // insert test-suite at test-runner by registry
    CPPUNIT_NS :: TestRunner testrunner;
    testrunner.addTest (CPPUNIT_NS :: TestFactoryRegistry :: getRegistry ().makeTest ());
    testrunner.run (testresult);
 
    // output results in compiler-format
    CPPUNIT_NS :: CompilerOutputter compileroutputter (&collectedresults, std::cerr);
    compileroutputter.write ();
 
    // return 0 if tests were successful
    return collectedresults.wasSuccessful () ? 0 : 1;
}

CppUnit is very flexible, allowing lots of outputs for the tests, I’ll write another post about this soon, but the idea of this runner is to use the CppUnit test registry, what makes a lot easier to work, because you can forget about the runner, just write your tests and register it.
It is almost like the fileset you pass to the junit task of ANT but written in C++.
After the test runner is ready, you can start writing your tests.
C++ different from Java, you use 2 files for each class, one header and one implementation file.
Let’s start with the header …
mainTest.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef MAINTEST_H
#define MAINTEST_H
 
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "../src/HelloWorld.hpp"
 
using namespace std;
 
class MainTest : public CPPUNIT_NS :: TestFixture
{
    CPPUNIT_TEST_SUITE (MainTest);
    CPPUNIT_TEST (testHello);
    CPPUNIT_TEST_SUITE_END ();
 
    public:
        void setUp (void);
        void tearDown (void);
        void testHello (void);
    private:
        HelloWorld *hello;
};
CPPUNIT_TEST_SUITE_REGISTRATION (MainTest);
#endif

In this header we have a simple class declaration, extending TestFixture from the cpp unit namespace.
C++ is a static language without reflection, because of that CppUnit has the macros you can see in the top of the class declaration, you need one CPPUNIT_TEST line for each test method you write.
Ant the line: CPPUNIT_TEST_SUITE_REGISTRATION (MainTest);
Does the magic of test auto registration.
After this you can write your test as you do in Java:
mainTest.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "mainTest.hpp"
 
void MainTest::setUp(){ 
	hello = new HelloWorld("Test");
}
 
void MainTest::tearDown(){
	delete hello;
}
 
void MainTest::testHello(){
	string expected("Hello Test\n");
	CPPUNIT_ASSERT_EQUAL(expected,hello->sayHello());
}

As in JUnit we have a setUp and a tearDown method, this methods does exactly the same thing, they initialize/uninitialize the variables you will use in your test code, and the “testHello” method is our test.
the assertions in CppUnit are done using macros.
These are the available assertions:

  • CPPUNIT_ASSERT(condition)
  • CPPUNIT_ASSERT_MESSAGE(message,condition)
  • CPPUNIT_FAIL( message )
  • CPPUNIT_ASSERT_EQUAL(expected,actual)
  • CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)
  • CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)
  • CPPUNIT_ASSERT_THROW( expression, ExceptionType )

A lot less assertion types than junit, but enough for working.
After the test done, now we just need to write our code!
HelloWord.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <iostream>
 
#ifndef MAIN_HPP
#define MAINHPP
class HelloWorld{
private:
	std::string name;
public:
	HelloWorld(char* name);
	std::string sayHello();
};
#endif

and the implementation:
HelloWord.cpp

1
2
3
4
5
6
7
8
9
10
11
#include "HelloWorld.hpp"
 
HelloWorld::HelloWorld(char* name){
	this->name = name;
}
 
std::string HelloWorld::sayHello(){
	std::string result("Hello ");
	result = result + name + "\n";
	return result;
}

To run the tests, you just need to type in the console:
make test
With all tests written and passing, the last step is the application runner (like the test runner).
main.cpp

1
2
3
4
5
6
7
8
#include "HelloWorld.hpp"
int main(int argc, char** argv){
	if (argc >= 2) {
		HelloWorld* hello = new HelloWorld(argv[1]);
		std::cout << hello->sayHello();
		delete hello;
	}
}

And you have your first test driven C++ application up and running!
PS.: if you are using my makefile, remember that application code is placed into src folder and test code is placed into test folder.
PS2.: the example was tested on linux with cpp unit installed using the package manager, if you want to install cpp unit from source, remember to update CFLAGS with the include path and LFLAGS with the library path. and if you are not using g++ as the compiler and linker, change the CC and LINKER variables with appropriated values.

If you enjoyed this post, make sure you subscribe to my RSS feed!

easyb-test - Grails Tests Made Easy (in a way your boss can read)

Have you ever read about easyb? and about Grails? May be you answer yes to one or both previous questions, but this is the first time you will find them together I guarantee, at least in a plugin form.

This is the first post I’m writing about my latest toy project (at least for now it is only a toy project).

The project is hosted at GitHub, and any help will be very welcome since I do not work every day with Grails, but I did a presentation about grails in the last weekend and wanted to use BDD instead of the traditional GUnit based unit tests, I already use Easyb for some of my Java projects, then I wanted to make Easyb and Grails to work together.

It was not an easy task, because of some craziness of Grails class loader, but it is working fine now.

You can write a test with the easyb sintaxe, and the test will look line this:

scenario "Project creation", {
	given "A new project", {
	  project = new Project()
	}
	when "the project name is supplied", {
		project.name = 'My test project'
	}
	and "there is no other project with that name", {
		validateproject = {
			project.validate().shouldBe true
		}
	}
	then "a new project must be created", {
		validateproject()
		project.save(flush:true).shouldNotBe null
	}
}
scenario "User association with a project", {
	given "Any existing project", {
		project = Project.findAll()[0]
	}
	when "a list of users is supplied", {
		users = [new User(login:'testUser1',password:'testUser1',email:'test1@test.com').save(),new User(login:'testUser2',password:'testUser2',email:'test2@test.com').save()]
	}
	then "the users must be associated with that project", {
		users.each{
			ProjectMembership.link(it,project)
		}
	}
}

You can even show it to your boss, because the output of this test is some thing like this:

Story: project management
  scenario Project creation
    given A new project
    when the project name is supplied
    when there is no other project with that name
    then a new project must be created

  scenario User association with a project
    given Any existing project
    when a list of users is supplied
    then the users must be associated with that project

And the best part of it, is that you can use your tests as the specifications of your next grails project!
If you want to know more about the easyb sintax, take a look at the project site.
If you want to know more about grails, take a look at the project site.
If you want a new functionality in this plugin, I’ll probably accept all patches and push requests you send-me :D
And finally, if you want to install the plugin, download it from here and run:
grails install-plugin grails-easybtest-latest.zip

You will need to place the tests you write in the folder tests/behavior
And to run the tests, just type: grails easyb-test
Any doubts or suggestions leave a comment here :D
I hope it can be useful to others.

If you enjoyed this post, make sure you subscribe to my RSS feed!

Tips for the SCEA 5 Beta exam - part 3

Yesterday I finished the third and last part of the SCEA 5 Beta exam …
The only bad news is that the results will only be available after February 15th :(

One good thing, is that this is the only certification I took until now that worth something!
The first objective test is very easy if you already work with system architecture and know at least a little about each Java EE technology …
The second part is not hard too, you have to design a system for a given problem, the only hard part on the Beta was to do it within 2 weeks, and for me those ware two full weeks, I was moving from one city to another, and already had some other things to do, at the end I could work on the project for only 20 hours (it was specified for between 40 and 60 hours), I hope I did it well enough …

The third and last part, is basically to prove that it was really you that created the project …
Before going to the test place, make sure you read all that you send with your project, write down every decision you make and why you made it, this two little tips will help you a lot in the final part of this certification …

Well, not I’ll wait untill February 15th to know if I cleared the exam :D
Good luck for me and for every one that read to here :D

If you enjoyed this post, make sure you subscribe to my RSS feed!