Adding Headers to Source Files

Note to self. Sometimes one needs to add a header part, e.g. copyright or license information to many files. To not have to do this manually one can conveniently do it with the script below.

[language:shell]
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
#!/bin/sh

project="MyProject"
author="Tommy Back"
data="29/1/16"
copyright="2016 Tommy Back"

files=$(find . -name "*.swift" -o -name "*.h" -o -name "*.m")

for f in $files; do
  if [ ! -f $f ]; then
    continue
  fi

  header="\
//\n\
//  ${f##*/}\n\
//  $project\n\
//\n\
//  Created by $author on $date.\n\
//  Copyright © $copyright. All rights reserved.\n\
//\n\
\
"

  echo -e $header | cat - $f > /tmp/out && mv /tmp/out $f
done

This example runs in an iOS project to add to all Swift and Objective-C files.

AWS S3 Pre-signed POST Example on Google App Engine

As a follow-up post to my post about Offloading Your Static Content for Your Web Service I have created a small example Google App Engine project to demonstrate the HTTP POST from the browser.

You can find the example on Github here.

If you’re only intersted in getting the AWS pre-signed POST in Go, please have a look at the small library I created and published on Github.

Two other Go related projects for AWS and S3:

Enjoy!

Offloading Static Content for Your Web Service

For web services with lot of static content that is user generated or user- consumed content like for instance sound or video, it would normally be sent to the backend and thus processed there. This means you need to pay bandwidth and processing of that data. It does not matter if you are hosted on a PaaS or run your own server infrastructure, you still need to pay to processthe data. You alos need to deal with scaling the delivery (see Content Delivery Networks).

Unless you really need to get the data to your service endpoint there is a much better way to offload this and that is to use Amazon S3 or something similar like Google Blob Store. These can function like a CDN and can scale globally across datacenters and continents as needed by your service.

Depending on the situation, e.g. if the web service is a public internet service, a company-internal service or who generates the content, who consumes it and how is it shared one would set up the overall system slightly different.

For internet services, the use case is many times that users generate content and upload that as part of the service for themselves, for sharing or both. The content can be private, shared or public depending on. Let’s now look at the situation with a public internet service like Youtube where you manage videos that users upload.

Use Case

In a scenario like Youtube where you have a site where users can publicly search, play and share videos you basically want a storage that is readable by anyone and writable as the service allows. Here read means search and download, and, writable means create. Direct deletion of files should not be allowed as this is not expensive in terms of bandwidth or processing and the system might still want to keep the contents and just mark it not available.

Overview

What we want to set up is a AWS S3 bucket with public read and nothing else. I.e. anyone can download given a URL that points of an object in the bucket. Then we want to let the owner of the bucket, i.e. the controlling service hand out permissions to upload as users want to add new videos to the service. This means the service is aware of uploads and can control them.

The permissions are essentially signed URLs or policies that describe what is allowed. E.g. user A is allowed to upload a file with a specific key (destination in the bucket), file size and within the next hour. After that the permission is no longer valid.

Let’s see how to set this up with AWS S3.

Bucket

The bucket needs to be set up with public read and nothing else. This is best done with a bucket policy like so:

{
  "Version": "2012-10-17",
  "Id": "Policy1234567890",
  "Statement": [{
    "Sid": "Stmt1234567890",
    "Effect": "Allow",
    "Principal": {
      "AWS": "*"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::bucketnamehere/*"
  }]
}

No other permissions should be per default except for the owner (Me) there is a ACL (Access Control List) that gives all rights. Those rights are later given on a case by case basis to users that want to upload content.

Let’s look at how to give permissions.

Pre-signed URLs

The simplest way to give permission to upload is to generate a pre-signed URL to be used with an HTTP PUT method. This means all necessary permission information is part of the URL as parameters.

Please note that browsers do not support HTTP PUT so one must either do it with Javascript or do the second option which is HTTP POST.

One can set an expiration when this URL no longer is valid.

With this method it is not possible to restrict e.g. the file size or automatically know if the request was successful. This is possible with the second option pre-signed POST.

Pre-signed POST

The second option that also supports browsers is to do an HTTP POST with some pre-signed content that AWS S3 can verify to allow the upload. This option is more advanced than a pre-signed URL and it is possible to control things much more with this. It is also more complicated as it is a HTML form sent as a multipart HTTP request.

The essence of this is that the owner (or someone with the right credentials) generate a policy that exactly describe what is allowed and signs it so that AWS S3 can verify that the HTTP POST is valid when it arrives.

Both expiration and file size limits are possible to set up with the policy [5].

One can also set up an HTTP redirect when something is successfully uploaded with the given permissions. This is of course useful to close the loop not knowing if someone actually uploaded what was intended and possibly leaving dangling ends in the service.

Summary

Today there are several good option how to offload user content to ease the workload on your endpoint. Options like Amazon S3 and Google Blob Store are very good options. The essensce is to have a storage that is scalable and restricted to what you need and then hand out permissions for read or write as needed by the users of your platform. This allows you to focus on building a great service and letting someone else deal with storing and delivering static content to your users, globally.

References

Custom Git Prompt

As an additional bonus to the previous post about Git workflows I’ll show how to customize the shell prompt to give you useful information. I have used this version as a starting-point with some additional fixes and improvements.

For me it’s always useful to immediately see what branch I am on, if there are local changes and how many commits I haven’t yet pushed. To show all this information in a compat way I have decided on the following:

current_dir + ' ' + branch_name + [*] + ['(' + 3 + ')'] + ' $ '

First comes the current dir and then the branch name. Then optionally an asterix for local uncommitted changes and lastly an optional number of unpushed commits.

Let’s dive in and see how to build this step by step. Each part of the prompt is got with a function – first our is the branch name.

1
2
3
4
function git-branch-name
{
    echo $(git branch | grep "^\*" | awk -F* {'print $NF'})
}

The second piece is to check whether there are local changes that are not committed.

1
2
3
4
5
6
function git-dirty {
    st=$(git status 2>/dev/null | tail -1)
    if [[ $st != "nothing to commit, working directory clean" ]] ; then
        echo "*"
    fi
}

Then let’s see how many commits we are ahead locally and grab the number.

1
2
3
4
5
6
function git-unpushed {
    brinfo=$(git status | grep ahead)
    if [[ $brinfo =~ ([0-9]+)[[:space:]]commit ]] ; then
        echo "(${BASH_REMATCH[1]})"
    fi
}

The next part detects if we’re in a git repo and then gitifies the prompt.

1
2
3
4
5
6
7
8
function gitify {
    git rev-parse --git-dir > /dev/null 2>&1
    if [[ $? != 0 ]] ; then
        echo ""
    else
        echo $(git-branch-name)$(git-dirty)$(git-unpushed)
    fi
}

The last function constructs the prompt and add colors for nice visibility.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function make-prompt
{
    local RED="\[\e[0;31m\]"
    local GREEN="\[\e[0;32m\]"
    local LIGHT_GRAY="\[\e[0;37m\]"
    local CYAN="\[\e[0;36m\]"

    PS1="\
${GREEN} \W\
${RED} \$(gitify)\
${GREEN}\
${LIGHT_GRAY} $ "

}

make-prompt

I’ve added all the above into a file called .bash_prompt that get sourced from .bashrc.

Git Workflow Overview

Short overview of the most important git commands and workflows. This is mainly focused on projects on Github.

Forking, Cloning and Remotes

Git allows you to work in several different ways. Two good ways to work are direct push and pull requests. The former is often used when you are alone or when you work on your own repo (which can be either a fork or not). The latter is usually the way to work in an open-source project so that people send pull requests for changes from their own forks of some repo.

To get started, let’s get a local repo by cloning say your fork of another repo you’d like to contribute to.

git clone <repo_url>

After this you have a local repo and a remote repo on Github. The repo repo is called origin. This is where you push changes.

If you forked an upstream repo, you should also add a remote upstream so that you can easily fetch and rebase.

git remote add upstream <upstream_repo_url>
git fetch upstream

If you collaborate with others it might as well be good to add their repos as remotes too so that you can grab changes from there and rebase on top of changes not yet upstream.

Making Changes

Changes to the code base should be done in clear and well described steps that are put into separate commits. I.e. a larger change will consist of a number of commits describing various parts on the way towards the change is completed.

A good workflow is to create a separate branch for some changes you’re making. This way you can easily work on multiple things in parallel and have good isolation between things. To create a new branch you start from a commit hash you want to use as the starting-point (usually this is HEAD of master).

git checkout -b some_descriptive_name

Now you’re in some_descriptive_name and it’s identical to where you where when you issued the checkout-branch command.

Now, let’s say you edited a files Example.cpp and Example.hpp adding a new function get_number(). Now you want to add the change into a commit and this is done by adding the files like this:

git add Example.cpp Example.hpp

After this add the change into a commit:

git commit -m 'Added function get_number() into Example.'

This procedure is repeated for a collection of changes (commits) until you’re ready to send a pull request. Before you can send a pull request you need to push your changes to your remote repo called origin:

git push origin <branch_name>

Creating a Pull Request

When you have a set of changes that you’d like to send upstream you do that by sending a pull request. This means that you submit your branch and the included changes to the upstream repo so that a maintainer can merge it.

Sending a pull request is done on Github from your own fork. Select the branch you are on and then click create pull request.

Once this is created it will go through review by whoever is a maintainer of the upstream repo.

Rebasing a Pull Request

One way of working is to rebase every pull request before it gets merged. This results in a clean commit history. When this is the process, you’ll need to fetch any changes that were merged upstream and rebase on top of those.

git fetch upstream
git rebase upstream/<branch>

This will catch up the current branch you are in with all changes upstream that you fetched and then replay your local changes on top of that. If you want you can automatically change pull to be fetch+rebase like this:

git config --global branch.autosetuprebase always

and then retroactively add it to existing branches like this:

git config branch.<branch_name>.rebase true

To update your pending pull request you need to update origin with your rebased branch. To do this you need to force push

git push +HEAD:<branch>

This will automatically update the pending pull request on Github to include your updated commits.

NOTE: force push rewrites history of your origin so be very careful with using it to not lose commits.

Resolving Conflicts when Rebasing

Sometimes when you rebase there are changes that conflict with yours and then git will stop and prompt you to make a choice what to do. In many cases there is an automatic merge, but if this fails you need to resolve the conflicts manually.

To do this you can start by looking at the files that have conflicts:

git status

This lists files that you need to update. I.e. one by one you open the files and look for e.g. HEAD to see where there’s something you need to address. When you have made the updates you need to add the files and continue with the rebase like this:

git add FileThatHadConflict.cpp
git rebase --continue

You might need to do this procedure multiple times depending on the conflicts and number of commits you have etc.

Interactive Rebase and Amending a Commit

During review of your pull request there might be things that need to be changed in a commit. There are two ways of dealing with this:

  • add a new commit to change things.
  • amend an existing commit.

The second option is cleaner, so let’s look at this.

First you’ll need to fetch latest upstream and rebase on that.

git fetch upstream
git rebase upstream/<branch>

Then you need to do an interactive rebase so that you can mark the commits you want to edit so that you can make changes directlyinto those.

git rebase -i upstream/<branch>

To edit change pick to e for one or more commits. Save and exit. Git will replay and stop at the marked commits so that you can make changes. So just make the change and then amend and continue rebase like this:

git add FileThatWasAmended.cpp
git commit --amend
# save commit info
git rebase --continue

Once you have done all you’re ready to force push the changes to your pull request.

git push origin +HEAD:<branch>

If you for some reason what to abort the rebase you can do:

git rebase --abort

Rebasing On Top of Another Branch

When you’re collaborating with others it might many times be good to share code before it hits upstream. This is easily done with git because upstream is just like any other repo. For convenience, add a remote to the repo you want to collaborate with like this:

git remote add foo <foo_repo_url>
git fetch foo

Now you can see foo’s branches with:

git branch -v

And getting code from someone is as easy as fetching and rebasing on top of upstream:

git rebase foo/some_branch

The same is true for pull requests. You can send pull requests between forks in Github too.

Some Other Useful Commands

To force HEAD to something in case of some major mistake you can do:

git reset --hard <commit_hash>

NOTE: be very careful with this command so you don’t lose anything.

Useful Links

Unit Testing: Part 4

In this post I will be showing something that is of major importance when designing software that can be tested. It is a very powerful technique to break dependencies and it’s called Dependency Injection (DI). I hope you enjoy it!

What is testable software?

In order to build high quality software it helps a lot to have unit tests as a central part of the development process. In modern software development this is well understood and you can read more about this in the other parts I have written about unit testing.

Before it is possible to write unit tests, one must have code that can be tested. It is said that good software design and testable code go hand in hand. In my experience this is very true. What this means in practice is simply that well-designed code has the properties that are necessary to have in order to test it too. One of the key properties is to have code that has low dependencies and especially external dependencies like network, database or printer should not exist as direct dependencies to the code that we want to test. Hence, we want independent parts that are well-defined.

So what is Dependency Injection?

As the name suggests, it is a technique that injects the dependencies. Without a real context this probably sounds a bit weird, so imagine a class that uses a network connection. Instead of only having the network connection internally, it is probably better to give it when creating an instance of the class. I.e. inject the network connection or preferably inject an interface that can be implemented as a network connection. I wrote “probably” because it is of course not always correct to inject everything. This is no silver bullet either.

Example in C++ with virtual interface

Let’s look at an example in C++ how it could look like when we break a dependency using DI. First, an example where a class uses a network connection internally to send some data.

class Client
{
public:
  void send(const char* buffer, std::size_t length)
  {
    connection_.send(buffer, length);
  }

private:
  Connection connection_;
};

This is considered to be bad, because the class depends directly on the network connection itself. What we rather want is that the class is given an interface to something that we can implement as the network connection for production code, and mock in test. So, what would that look like?

First we need an interface. We define an abstract base class (ABC) that we can use internally in the class.

struct IConnection
{
  virtual ~IConnection() {}
  virtual void send(const char* buffer, std::size_t length) = 0;
};

Next we need to modify the existing Connection class to implement the IConnection interface.

class Connection : public IConnection
{
public:
  virtual ~Connection() {}
  virtual void send(const char* buffer, std::size_t length)
  {
    // ...
  }
};

Then we need to pass in this interface into the class in question and then use it as before.

class Client
{
public:
  explicit Client(IConnection* connection) : connection_(connection) {}

  void send(const char* buffer, std::size_t length)
  {
    connection_->send(buffer, length);
  }

private:
  IConnection* connection_;
};

What we essentially have done is to instead of using a concrete class we now use an interface which means it can be exchanged for anything as long as it implements that interface. This is what we want, because then we can have one class that is the real network connection that we use for production code, and another class that we use in unit tests to not involve the network when testing the client itself. This is in line with good software design as well.

It is important to note that this is not always the wanted solution as there are other ways to achieve similar results. Let’s look at an alternative.

Example in C++ with a template

Again we start with the same initial client that uses the network connection directly.

class Client
{
public:
  void send(const char* buffer, std::size_t length)
  {
    connection_.send(buffer, length);
  }

private:
  Connection connection_;
};

Now instead we can change the class into a template so that we can pass in the connection.

template <typename TConnection>
class Client
{
public:
  explicit Client(TConnection& connection) : connection_(connection) {}

  void send(const char* buffer, std::size_t length)
  {
    connection_.send(buffer, length);
  }

private:
  TConnection& connection_;
};

This achieves the same results if having a template is fine. In some cases, this might not be ideal and in other this is even better than having a virtual interface.

The same mechanism works for functions as well, i.e. one can break the dependency on a passed in argument by passing in an interface or making it into a template function an thus passing in a template argument.

What is the bottom line?

To me, DI is simply another tool that can be used when it makes sense. In my view, it does not make sense to inject everything just because it’s possible. What does make sense to do every time is to write testable code and write unit tests to test it. This is part of the foundation of good quality.

DI is a concept that can be used across programming languages and here I have showed you how it can be used in C++. I hope you enjoyed the post!

Unit Testing: Part 3

Another topic that is closely related to unit testing, or testing in general of course, is bug fixing. In this part I will describe what I consider important and how I like to work when dealing with bugs.

How to approach a new bug?

When confronted with a new bug the goal is often simplified to only finding a fix. This is of course important, but it’s not enough. Equally important is to prevent the bug from happening again and also to not break anything else while fixing this one. To achieve the latter two, we need to rely on unit testing. First, the new bug needs to get unit tests that catch it so it becomes visible when it happens again. Second, to avoid breaking other things we need to have enough unit tests to be comfortable making changes to the code base so we can fix the bug we’re working with.

What is the best workflow?

There are many ways one can work and below is a way I have found to work extremely well. It takes some discipline but it’s a clear and straight-forward way.

Reproduce the bug

In order to properly understand and fix a bug one needs to reproduce it and see how the software fails. This is not always possible and in the worst case one cannot understand what the problem really is or what triggers it. Let’s focus on the ones that can be reproduced and fixed.

Use CI builds to track down when the bug was introduced

Again, the Continuous Integration system can show its powers, because now we can use old builds to quickly find the first build that introduced this problem (assuming it’s something that has been working at some point of course). If we find the last build where it works we can check what was changed in the following build looking at the change list. This I have found to be a very effective way of finding the introduction and to understand what parts of the code to look at. This basically means going back in time to when the bug was introduced.

Add tests to catch the bug

Once we can reproduce the bug we need to write one or more unit tests that trigger this bug. This is key considering future prevention of the same bug.

Fix the bug and pass the tests

Now we are set to fix the code so that the bug gets resolved and all the unit tests pass.

Commit fix and verify that CI passes

Lastly we commit the fix and make sure that the CI system passes.

This workflow is something I know works well and is concerned with programming and unit testing. It does not discard other types of testing or quality assurance that can come in addition to this later on.

Next part

In the next part I’ll write about dependency injection which is a very powerful technique to break dependencies and thus get testable code. I hope you enjoyed this one!

Unit Testing: Part 2

There are many related topics that come up when talking about unit testing. One of the most important ones in my mind is Continuous Integration. In this post I’ll explain how I see Continuous Integration and its relationship with unit testing.

What is Continuous Integration?

Continuous Integration (CI) is a development process that runs whenever there are changes to be integrated into what one is building. The goal of CI in my view is to provide a platform to incrementally build high quality software and give transparency how changes affect things.

In the case of software, CI takes source code changes and then rebuilds the software to incorporate these. While incorporating the changes the process applies any defined quality assurance checks to see if the build passes. Essentially this means that one sets up the quality assurance mechanisms that are needed in order to catch issues that are relevant.

This is a key concept in modern software development and especially in Agile software development methodologies like Scrum.

Where do unit tests fit in?

Unit tests are part of the quality assurance mechanism and are run in order to make sure that the code changes are not breaking things. This is what unit testing automation is all about and this is a key ingredient of a good CI implementation.

In order to have a sound CI system with automated unit tests, there are a few key things to consider. Let’s look at the ones I consider most important.

There must be enough unit test coverage

It’s clear that one have to start from zero unit tests at some point and it’s preferable if this is when there is zero source code as well. Adding unit tests after the fact is usually very slow and hard, so keep them with from the start. They are not only there to prove that things work but also to help while doing the development work.

The unit tests must be fast

One of the properties of a good unit test is that it runs very fast.

The goal is to have lots of unit tests because they increase the chances to catch bugs and thus increase software quality. Having many unit tests should not affect the time it takes to do a build very much, because we want to run all the tests for every build. It takes practice and skill to develop great software and the same goes for writing great unit tests.

Changing code means adding and adjusting unit tests to cover the changes

Working with unit tests are part of building software and therefore they are added, changed and removed as code is added, changed and removed. Very simple and takes discipline, especially when time is short.

Failing unit tests means failing the build

It is important to fail the build when there are failing unit tests. Even if there is only a single failing unit test. No compromise. Ever. This is part of being professional.

Why is Continuous Integration so great?

The main thing about CI is that it’s a platform, a framework or simply a process that can take any shape one needs in order to get fast feedback to changes one is making while developing software. It sits in the venter of software development and can be hooked into other systems like source control and issue tracking systems to extend the automation of the software development process.

Put even simpler – it is the platform for automation which is a very powerful thing.

Next part

In the next part I’ll write about bug fixing and unit tests. I hope you enjoyed this one!

Unit Testing: Part 1

There exists lots of great information and books about unit testing and I’m not trying to re-invent that or necessarily come with anything new. This is more of a distilled version preliminary for myself how I think and go about unit testing and what I have found to work well. If someone else finds it useful, even better!

What is unit testing really?

Unit testing is about writing code that tests e.g. classes and functions as you’re developing software to check that things work as expected. Hence, this activity is something software engineers do themselves and not something other people do after code has been written! This realization is fundamental and important. Think of unit tests as a safety net for us programmers so that we don’t break things. It’s also important to understand that unit tests are for small things, generically called units. Unit tests are not aimed at testing functionality across several parts or features in a system. They’re about making sure that the building blocks are delivering what they promise so one can integrate them into larger software systems. Other types of testing targets other testing needs such as functional-, integration- as well as performance testing. These are all important and it’s crucial to understand and keep them separate.

Other important properties of unit tests are determinism, independency and speed. The first means that a test behaves in a deterministic manner and not random. Independency means that there are no external dependencies like database, network or disk. It’s key to have very fast tests that are isolated and deterministic so that all tests can be run anytime you want, e.g. after any code change. Typically fast in this context means seconds to minutes and the number of tests means thousands or more.

Unit tests have more to them than only testing the integrity of the code, they also function as a specification of what something should do and how it should work. They show how to use specific classes and functions and this help newcomers as well as others to understand a code base or an API.

For unit tests to be valuable they must first of all be up to date and in use, but also descriptive, clean and focused. The added benefit means that when something breaks one will know precisely what broke because the tests are so clear and targeted. To achieve this one needs to be disciplined and have good practices and conventions.

What does a good unit test look like?

There are several ways to write good unit tests and here is what I have found to work very well for me in C++. Let’s look at the following example test case.

TEST(Client, successfully_connects)
{
  // Arrange
  Client client;
  // Act
  bool connected = client.connect();
  // Assert
  ASSERT_TRUE(connected);
}

Firstly, it’s very important to read the test case clearly and immediately understand what it means and what to expect. My preferred way for test name is to write it in lowercase with underscores to delimit the words. This is much clearer than UpperCamelCase. It’s important to name it according to what it’s doing and what to expect so everyone clearly understands.

Secondly, I prefer to use AAA, that is, Arrange, Act and Assert to divide the test into clear parts. I don’t aim to be dogmatic, but this works well most of the time. The first part arranges the necessary start (closely related to a fixture), the second part does the action, and the last part asserts what the test tests. This keeps the tests short, simple and clear. I find this providing a clear structure so anyone will understand the test and it restricts the tester to keep things short and focused. Many times I have seen single tests testing multiple things over multiple screens. This is not what you want! You want to have the user understand what the preconditions are i.e. the start and then understand what happens when you do “one thing”. That’s it. Keep it simple is the key to success here as well.

How to use fixtures to be DRY?

To keep things clean and clear it’s important to not clutter and repeat things. This is where fixtures enter the stage. I primarily think of a fixture as the preconditions that is the starting point for the test. They are about setting up state and tearing it down after the test.

For the previous test case example, we only have a starting point of the creating the client, so it doesn’t give much immediate simplification, however, for larger number of tests this is very powerful. Let’s take a look at what it would look like with a fixture.

namespace
{
  struct ClientFixture
  {
    Client client_;
  };
}

TEST_F(ClientFixture, successfully_connects)
{
  // Arrange
  // Act
  bool connected = client_.connect();
  // Assert
  ASSERT_TRUE(connected);
}

As a side note, in C++ in .cpp files it’s good practice to put code like the fixture into an anonymous namespace, because it should only be accessible in this compilation unit. If it’s not put in an anonymous namespace it will cause linker errors if the same fixture name is also elsewhere. So, put it into the anonymous namespace.

With the fixture we can now easily add another test that uses the same fixture and thus saves us in this trivial example the code under arrange that created the client. This is now implicitly available through the fixture.

TEST_F(ClientFixture, successfully_disconnects_even_if_not_connected)
{
  // Arrange
  bool connected = client_.isConnected();
  // Act
  bool disconnected = client_.disconnect();
  // Assert
  ASSERT_FALSE(connected);
  ASSERT_TRUE(disconnected);
}

How to keep unit tests valuable and affordable?

To keep unit tests valuable one needs to spend an effort to maintain their high quality. That means to refactor tests as the code they test change and to of course write new tests as new code is developed. All this comes at a price upfront, but pays itself back many times over the lifetime of a code base. This is key to understand in order to be successful long-term.

Another insight I have had is that one must take a pragmatic approach to what one tests and balance it with what needs to be done. One could of course spend close to an infinite amount of time writing tests and not get any working software to ship. That balance is got through experience in building software as well as understanding oneself and what is needed to produce quality software.

Next part

There are several related topics to unit testing like Continuous Integration, bug fixing, TDD and more. I’ll cover these in later parts about unit testing. I hope you enjoyed it!

Light-weight Header Only C++ Unit Testing Framework

Unit testing is something I care about a lot and I’ve come to realize the enormous benefits it brings when you want to refactor and make changes to software. This is something I do a lot, because I like to evolve things and thus have a basis where I can make changes and at the same time feel confident that it still works. Another very important aspect of unit tests is that you can communicate how something is expected to work, i.e. the specification, both to yourself and also to others. This is very important and powerful.

Currently, my main programming language is C++ and I’m using Google test to write and run unit tests. This is a great framework and I’m very happy with it. However, as an interesting exercise I decided to developed a small and light-weight unit testing framework that would work similarly to Google test, i.e. similar macros and so forth. My goal was to write a header-only test framework that has the most important features needed for unit testing. Also it should integrate with Continuous Integration systems like Hudson/Jenkins, i.e. the XML output must be readable by Hudson/Jenkins.

I’ve completed an initial version I’m using in a few toy projects and I thought it could be nice to share it in case someone else might find it useful. It’s available for download on github, so please have a look and let me know what you think.

In coming posts I’ll describe how to use it and what my preferences when it comes to unit testing.