Notes From My GoogleTest Demo


I recently gave a demo of GoogleTest at Kjeller Software Community / Oslo C++ Users Group. These are the notes from my demo. My apologies to those who did not attend, these might not make much sense unless you saw the demo.

Installation

See my post about installation and setup of GoogleTest in your project.

Test types

TEST(TestCaseName, TestName)
A single test TestName belonging to the TestCaseName test case. The TEST macro converts this into class TestCaseName_TestName

TEST_F(TestFixtureName, TestName)
A single test TestName belonging to the TestFixtureName test case, which uses a fixture. The TEST_F macro converts this into class TestFixtureName_TestName : public TestFixtureName. You need to implement the TestFixtureName : public ::testing::Test class also.

TEST_P(TestFixtureName, TestName)
A single parametrized test TestName belonging to the TestFixtureName test case, which uses a fixture with a parametrized interface. You need to implement the TestFixtureName : public ::testing::WithParamInterface class also. Use GetParam() to get the parameter, and INSTANTIATE_TEST_CASE_P to instantiate tests.

Finally remember that you can use SetUp() and TearDown(), but might just as well use the plain constructor and destructor. A reason to use TearDown() instead of the destructor is if it might throw an exception (which destructors should not do).

Assertions

Here are some examples of assertions:
ASSERT_TRUE
ASSERT_FALSE
ASSERT_EQ
ASSERT_DOUBLE_EQ
ASSERT_LT
ASSERT_THROW

You can also write your own assertion functions:
AssertionResult predicateFunction(...)

Or just write a void function that does all the asserts internally:
void assertWhatever()

Some final tips

Use one test project per production project, for instance NoFlyListTest for NoFlyList. This makes it easy to find the tests for a project. If the rest of your code is decoupled, it might also speed up linking a lot, since you only need to link the test project, and not your entire solution. This especially helps if you are doing TDD, in which you will typically compile and link several times a minute.

Write short tests, and only test one thing per test. This will make it easy to figure out what went wrong when tests break in the future.

Write tests before you implement the code that passes them. This will verify that the test didn’t pass just by accident. It will also let you see how the failing test looks like, so you can make sure it is self-explanatory enough that someone will understand what went wrong when it breaks.

Don’t be a terrorist, you’ll end up in a bad place.

Source Code

If you want to have a look at the code from my Kjeller Software Community demo, it is available on GitHub.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.

Installing and Using GoogleTest with Visual Studio


Important note: This blog post is one of the top hits on Google for “googletest visual studio”. It is however quite old, and might no longer reflect the best way to use GoogleTest with Visual Studio. 

Google C++ Testing Framework (aka. GoogleTest) is a unittesting framework for C++. This post describes how to install it, and set it up in your project. I am using GoogleTest 1.6.0 here, but other versions should be similar. The instructions provided are for Visual Studio 2010, but 2012 should be exactly the same.

Installation

First of all, download the latest version from the GoogleTest download page, and unzip it. Inside, you will find a directory called msvc, which contains the Visual Studio solutions:

In this directory, you will find two solutions, gtest.sln, and gtest-md.sln. Which one you want depends on whether you are using a static or dynamic runtime. If you are unsure which one to use, take a look in your existing solution:

If you are using the DLL version of the runtime, use the gtest-md.sln solution, otherwise use gtest.sln. Before you open the solution though, make sure it is not read only, as Visual Studio will want to convert it to your version:

Open the solution you want, agree to convert the solution. Make sure you build it both in Debug and Release versions. The resulting libraries end up in gtest-1.6.0\msvc\gtest\Debug and gtest-1.6.0\msvc\gtest\Release, respectively. This is a good time to copy the libraries to wherever you keep libraries for your projects. The files you will need are gtestd.lib and gtest_maind.lib from the Debug directory, and gtest.lib and gtest_main.lib from the Release directory. In addition, you need all the headers from gtest-1.6.0\include. (Of course, you could just copy the entire gtest-1.6.0 directory and not care about which files you need.)

Setup for Your Project

I suggest to use one test project per production project. This makes it easy to find the tests you are looking for. Also, if your code is nicely decoupled, you might be able to link just these two projects, and not your entire solution. This can speed up your “red-green-refactor” cycle considerably. Finally, this makes it easy to exclude your test code from the final binary you ship. Here is an example from my Kjeller Software Community presentation:

Set the following properties for your test project:

  • Make sure to set up the test project to use the same runtime library as your production project (MT / MTd / MD / MDd).
  • Add an additional include directory c:\wherever\you\put\gtest\include
  • Add an additional library directory c:\wherever\you\put\the\libs
  • Under Linker -> Input , add a dependency on gtest.lib for your Release configuration, and gtestd.lib for your Debug configuration. Unless you want to write your own main function that runs all the tests, also add a dependency on gtest_main.lib / gtest_maind.lib, respectively. This will add a main() method to your project which discovers and runs all the tests.
  • Under Properties -> Linker -> System, set SubSystem to Console, to keep the test-window open after the tests have run.

Also make sure that your test project depends on the production project:

And that’s it! Now you can start writing and running tests, but since the documentation already describes that pretty well, I will not go into that here. If you want to have a look at the code from my Kjeller Software Community demo, it is available on GitHub.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.

New Software Community, and Google Test Demo


Together with Håkon K. Olafsen, I founded Kjeller Software Community earlier this summer. Our first meetup is due this Wednesday (September 26). I will do a demo of Google C++ Testing Framework, aka. GoogleTest, and afterwards we will have a few beers and chat about programming and all things geeky. Hopefully we will also get some good suggestions for future events and meetups. The meetup will happen at Klimt pub in Lillestrøm, at 6:00 pm.

This meetup is done in cooperation with Oslo C++ Users Group, of which I am also a member. If you are into C++, and live in the greater Oslo area, that group is also highly recommended.

Notes from the talk, and a blog post about Google Test will be up later this week.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter. You can also follow Kjeller Software Community on Twitter.

Uniform Initialization Simplifies Testing


In which I demonstrate the use of uniform initialization, and show how it is particularly well suited to unit tests.

In C++0x, there is Yet Another Way to initialize objects, using the {} syntax (uniform initialization). Except, it isn’t really new, it’s the way we’ve always been initializing arrays and structs:

int i[] = {1,4,9};

The difference is we can now use this syntax to initialize any object. Why does this matter, and what is wrong with the old constructor syntax? Nothing is wrong with it in fact, and it will still see a lot of use. But in some cases, {} leads to simpler and easier code.

One area in particular is initialization of containers. It was always a bit of a hassle to initialize for instance a vector, where you would need to do something like this:

    string a[] = {"foo", "bar"};
    vector<string> v(a, a+2);

In C++0x however, you can do

    vector<string> v = {"foo", "bar"};

One area where I find myself initializing containers manually a lot is in unit tests. Here is an example:

#include <gtest/gtest.h>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int count_sheep(const vector<string>& animals) {
    return count(animals.begin(), animals.end(), "sheep");
}

TEST(TestCountSheep, returns_zero_when_there_are_no_sheep) {
    ASSERT_EQ(0, count_sheep({"pig", "cow", "giraffe"})); //here
}

TEST(TestCountSheep, returns_all_sheep) {
    ASSERT_EQ(2, count_sheep({"sheep", "cow", "sheep"})); //and here
}

Note the calls to count_sheep(), where the container is declared and initialized in line, without any mention of string, vector or temporary arrays!

To compile this, you need g++ 4.5 (sudo apt-get install g++-4.5). It might also be possible in Visual Studio 2010 if you are so inclined. This example also uses the Google C++ Testing Framework (sudo apt-get install libgtest-dev). Here is the full command to compile and run the example:

g++-4.5 * -std=c++0x -lgtest_main -lgtest -lpthread && ./a.out

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter