Wednesday, 30 November 2011

Automating C++ Unit Tests in MSVC

Test Driven Development using C++ can be more challenging than in other more trendy languages. But, with a bit of creativity and know-how, it really isn't too difficult.

In a recent project I wanted to follow a more formal TDD process than perhaps sometimes I would. I always write defensive code littered with assertions, etc., but always stop short of a full unit test suite for all my code.

Being such a fan of the Boost libraries, naturally I turned to boost.org and the Boost.Test library. It's very complete if a bit complex in its naming conventions, but I won't cover the library here, you can read the documentation for yourself here.

Let's talk about how to configure an MSVC solution for automated unit testing. It turns out not to be very difficult, but did take some trial-and-error.


Goals

With an automated unit test suite, I am trying to achieve a set of tests that satisfy these goals:
  1. the tests should run as a part of the build process
  2. if the application fails to build, don't run the tests
  3. building the project, the tests should be re-run even if the application hasn't changed
  4. the results of the unit test should be available in the Output Window with the compiler output
  5. if any of the tests fail, the build should fail
  6. if any of the tests fail, the failing line should be easily accessible in the IDE

Method

I have two projects in my Solution. The first (Project1) is the application I'm developing (in a complex app, there'll obviously be more projects for DLLs, etc.), the second (Project2) is the unit test application. (Goal 1)

In the Project Dependencies, set Project2 to be dependent on Project1. This will ensure the build order so the application builds before the unit tests. (Goal 2)

We'll use a file on disk to control the running of the tests, using a file-dependency mechanism. Before running the tests, we'll delete the file...
In Project Properties, Build Events, Pre-Build Event, set Command Line to
del "$(SolutionDir)$(Configuration)\$(ProjectName).txt"
Now, we'll use a Custom Build Step to invoke the test execution after the test suite has compiled.

In Project Properties, Custom Build Step, set Command Line to (all on one line)
"$(SolutionDir)$(Configuration)\$(ProjectName).exe" &&
echo Ok > $(SolutionDir)$(Configuration)\$(ProjectName).txt"
This trick will run the freshly built test suite application and, if it succeeds, will write "Ok" to a text file. Now, we have to tell MSVC where the file is that we've written to:
Set Outputs to
$(SolutionDir)$(Configuration)\$(ProjectName).txt
MSVC will use this file dependency to control whether the test suite succeeded or not. On success, the file contains "Ok", but if the test suite fails, the file will not be written and won't exist because of the delete in the pre-build step.(Goal 3)

Unit Tests

Using Boost.Test a very simple example test suite is shown below. Output of the running tests is send to stdout, which will be captured by MSVC and written to the Output Window. (Goal 4) If any tests fail, Boost.Test returns ERROR_FAILURE which will stop the build. (Goal 5)
#define BOOST_TEST_MODULE fileparts
#include "boost/test/included/unit_test.hpp"

BOOST_AUTO_TEST_CASE( free_test_function )
{
    BOOST_CHECK(false);
}
This test suite will always fail, producing the output below:
1>CustomBuildStep:
1>  Description: Performing Custom Build Step
1>  Running 1 test case...
1>  testsuite.cpp(13): error in "free_test_function":check false failed
1>  
1>  *** 1 failure detected in test suite "fileparts"
The error is in the correct format to enable you to double-click this line in the Output Window. (Goal 6)

Conclusion

This is a neat implementation with a few tricks and hacks that make a streamlines Unit Test environment for TDD in C++.

Friday, 3 December 2010

Email Inbox Concept

I have created a new and, I hope, innovative user interface for a web based email reader, and I would be very interested to hear your views. Please leave your comments on this blog.

What it so different?
The inbox concept is a web based email reader with a clean, crisp user interface and smooth animated navigation. Emails are organised into pages, and sorted by date. Ordering is slightly looser than strictly by date to take optimise the use of the space that is available.

Features

  • The size and shape of each email message changes dynamically based on attributes of the message, such as the length of the subject text, the number of messages in group & whether image attachments are present
  • Smooth animated navigation
  • Attached images are previewed in the main inbox view
  • Message groups; collation of messages with the same subject from multiple recipient helps to manage your inbox
  • Multiple messages (conversations) are grouped and shown in an accordion user interface.
  • Unread emails are shown with blue text

Try it
To try the inbox concept, follow this link and read the emails in the inbox. You can send emails to inboxconcept@gmail.com and see them appear in the inbox.


Limitations
This is a proof of concept, and not a fully functional email application. The Email Inbox Concept is read-only, and does not allow for sending, reply to, or forwarding emails. Emails are not marked as 'read' after they are opened in the UI.
The concept is restricted to the demonstration inbox and users can connect to their personal email from this application.


Disclaimer
The inbox concept is open to the entire world wide web. Any email messages sent to inboxconcept@gmail.com will appear on the site, and may therefore be indexed by and appear in search engine results from Google, Yahoo!, Bing, and others. Please don't send emails to the account unless you are happy that the content is freely accessible.

Monday, 11 October 2010

MapReduce with an embedded distributed file system

When I wrote my C++ MapReduce library, I had quite a bit of interest from potential users. One of the most frequent questions that came up was about scaling across multiple machines. To do this, there is a requirement for a lot of infrastructure to manage the execution of MapReduce Jobs, merge and sort intermediate results, manage cross-machine communication and provide resilience in the case of machine failures. One of the biggest components is the distribution of data files to be processed and consolidation of result data files across the network. This is typically done with a subsystem called the Distributed File System. Google's original MapReduce algorithm used GFS, the Google File System. Hadoop has the HDF, Hadoop File System.

I didn't want to go down the same route, because my idea for the MapReduce library is that it should be lightweight and easy to deploy. I don't want a dependency of complex configuration across multiple machines, and I want it easy to use on all platforms, including Windows, without a dependent software stack and configuration overhead.

My solution to this is an Embedded DFS so the DFS infrastructure is bound into the client application and runs without configuration. I want to be able to build a MapReduce program and run it on any number of machines in a network and it will "just work". No configuration, no messing, the subsystem takes care of it all.

Will this bloat client applications? No. The subsystems for MapReduce and DFS are very small, so the footprint overhead is minimal.

Early prototypes have proved the concept, and I can run multiple instances on multiple machines and they all find each other, communicate with each other and cope when one of more are unavailable, either by being shutdown cleanly or with a forced close.

Tuesday, 27 April 2010

Google grants license for Apache Hadoop

The H reports that Google has granted a license for one of its patents to the Apache Hadoop open source framework for distributed computing.

Wednesday, 14 April 2010

Software Scalability with MapReduce article published

I have published a new article about Software Scalability with MapReduce on my website.

This substantial article introduces some of the concepts of MapReduce and how they can be applied to scaling software even on a single machine. You don't need datacenters and large clusters to be able to take advantage of MapReduce.

Book Review - Computing for Numerical Methods using Visual C++

I have published online my book review of Computing for Numerical Methods using Visual C++ by Shaharuddin Salleh, Albert Y. Zomaya and Sakhinah Abu Bakar. I wrote this review in August 2009 for the ACM Special Interest Group on Software Engineering.

Saturday, 27 March 2010

MapReduce book available online (in draft)

An interesting book on MapReduce has been made available in draft form, called Data-Intensive Text Processing with MapReduce. I haven't read the whole thing in detail, but I like the author's writing style from the parts I have read, and look forward to reading the rest.