So on an Embedded, Real-Time blog why am I taking about Visual C++ and googletest?
With the growth and acceptance of agile techniques, such as Test Driven Design (TDD), which is very well explained in James Grenning’s book Test Driven Development for Embedded C, we now have a set of tools and techniques that are:
- Natural to use (as they use the native language)
- Easy to use (to varying degrees)
- Free
that allow the quality of embedded software to be significantly improved prior to target based testing.
However, It is important to note that TDD does not solve (or even address) may of the complications of developing and testing software for an embedded environment, but at the same time it should not be ignored.
Contents
So why Visual C++ express edition and googletest?
First, Visual C++ is not my first tool of choice, this selection came from working with a customer, it was their choice. Saying that, the express edition is free to use (I am assuming you will be using a professional cross-complier for target development) and it has become one of the best standards conforming C++ compilers around. Also I am not claiming to be a Visual C++ expert as I don’t develop software targeted at Windows.
googletest (gtest) is, in my experience to date, by far the easiest unit testing framework around for testing C++. For testing C I prefer Unity, which I’ll discuss in a later post. googletest is also supported by googlemock (gmock), which is an essential part of being able to use a unit testing framework for host testing of embedded software (my next post will look at setting up gmock). Finally, gtest was also part of the customers requirements.
As with many of these projects, all the information is out there, but what I hope to do is save you a little of the pain I went through getting the project setup and working.
I will assume you have Visual C++ 2010 express edition installed, if not go ahead and install it following the default Microsoft process.
Next, download the googletest zip file and unzip it to known location. I suggest something easy, either C:\gtest-1.6.0, or as in my case C:\src\gtest-1.6.0.
Building the gtest libraries
This couldn’t be easier. Simply navigate to the directory \gtest-1.6.0\msvc and open the Visual C++ project gtest (gtest.sln).
You will be asked to convert the project from an older format to a newer one. Go ahead and do this. Finally you’ll end up with four projects:
Go ahead and build these (F7) and ignore any warnings. Once successfully built, look in the directory \gtest-1.6.0\msvc\gtest\Debug and you will find two library files
These are Debug build libraries (the ‘d’ in the library name indicates this). If you want Release build libraries then change the build option to Release and rebuild. You will find the library files gtest.lib and gtest_main.lib in \gtest-1.6.0\msvc\gtest\Release. However, for the purposes here I’m assuming we only need to work with Debug builds.
Building a Visual C++ gtest Project
The key steps to build a gtest project are:
- Create a new project
- Win32 Console Application
- Add test fixture file
- and remove default main
- Configure project properties
- Additional Include Directories
- \gtest-1.6.0\include
- Add gtest (debug) libraries
- gtestd.lib
- gtest_maind.lib
- Modify Runtime Library:
- Multi-threaded Debug (/MTd)
Create a new Visual Studio project
Create a new Win32 Console Application project (gtest_VC_setup)
using the Application Wizard, unselect the option for using Precompiled headers as cause some build problems.
You will get a default project main file containing the following code:
// gtest_VC_setup.cpp : Defines the entry point for the console application.
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
Build (F7) and run (Ctrl+F5) to check everything is okay with the project.
Add test fixture file
We now can write a simple test to check out the gtest libraries. Create a new C++ file (Ctrl+Shift+A), here named testFixture.cpp. Add the following code to this file:
// testFixture.cpp
#include "gtest/gtest.h"
TEST(setup_test_case, testWillPass)
{
EXPECT_EQ(42, 42);
}
Regarding the main function (_tmain above) we have two options. Either we can write the main code required by gtest, or we can use a default main which gtest supplies as part of the gtest_main library. For now, we will use the gtest default. To do this we need to remove the file gtest_VC_setup.cpp from the build (if you right-click on the filename, the you will see the option “Exclude from Build”).
Now build the project; you will see the error:
- fatal error C1083: Cannot open include file: ‘gtest/gtest.h’: No such file or directory
Configure project properties
gtest Include Directory
We now need to configure the project to look in the correct place for the header gtest.h. Open the project property pages (Alt+F7). Select:
- Configuration Properties
- C/C++
- General
- Additional Include Directories
And add the path to \gtest-1.6.0\include
Rebuild the project; you will now see the error:
• LINK : fatal error LNK1561: entry point must be defined
Add gtest libraries to the build
The error is because we have removed the main function, and thus there is now no program entry point. As stated, we want to use the supplied gtest main, so we need to include the gtest_main.lib library in our build. While we are there we might as well add the gtestd.lib library to the build as well as we’ll need it anyway.
Open the project property pages (Alt+F7). Select:
- Configuration Properties
- Linker
- General
- Additional Library Directories
And add the path to \gtest-1.6.0\msvc\gtest\Debug
Then select:
- Configuration Properties
- Linker
- Input
- Additional Dependencies
And add gtestd.lib and gtest_maind.lib
Rebuild, and you will get yet a further error:
- fatal error LNK1169: one or more multiply defined symbols found
Modify Runtime Library
Now here is an area I’m note entirely sure why I need to change the runtime library option, but to remove the linker error change the runtime library from:
- Multi-threaded Debug DLL (/MDd)
to:
- Multi-threaded Debug (/MTd)
In the project property pages, select:
- Configuration Properties
- C/C++
- Code Generation
- Runtime Library
to change the option.
Finally you will get a clean build which results in an executable. Running the project (Ctrl+F5) will result in the following output:
Test gtest
As one last step it is worth checking that gtest is functioning correctly by adding a failing test. Modify testFixture.cpp to include:
// testFixture.cpp
#include "gtest/gtest.h"
TEST(setup_test_case, testWillPass)
{
EXPECT_EQ(42, 42);
}
TEST(setup_test_case, testWillFail)
{
EXPECT_EQ(42, 0);
}
Build and run, giving a final output of:
And finally…
Easy, once you know how! There is no real rocket science here, or anything specifically new, but I’m hoping that using this guide you can now start playing with googletest. Also, I am sure there are probably better ways to set the project up, but as I said before, using VC++ is only a means-to-an-end rather than my final target compiler, so I tend to work using the path of least resistance.
To follow up there will be further postings on getting googlemock setup and running with Visual C++ and then I will explore gtest and gmock further.
As always, all constructive feedback welcome and please let me know if you had any problems.
- Navigating Memory in C++: A Guide to Using std::uintptr_t for Address Handling - February 22, 2024
- Embedded Expertise: Beyond Fixed-Size Integers; Exploring Fast and Least Types - January 15, 2024
- Disassembling a Cortex-M raw binary file with Ghidra - December 20, 2022
Co-Founder and Director of Feabhas since 1995.
Niall has been designing and programming embedded systems for over 30 years. He has worked in different sectors, including aerospace, telecomms, government and banking.
His current interest lie in IoT Security and Agile for Embedded Systems.
Pingback: Sticky Bits » Blog Archive » Setting up googlemock with Visual C++ 2010 Express Edition
Seems to work for VS 2012 also. Only the current included VS projects' project settengs need to be altered.
In the Preprocessor Definitions a definition has to be added:
_VARIADIC_MAX=10
More explanation:
https://stackoverflow.com/questions/12558327/google-test-in-visual-studio-2012
You also need to do this in projects where you use the testing framework.
Hi Niall, I know you wrote this a long time ago...
I just followed your instructions and it all works as you explained - thanks very much!
I'm actually using gtest 1.8.1 with VS 2010 since that's the latest version that supports pre-C++ 11 - which is what VS 2010 is. Thanks a lot for your help. I now need to get it working testing some MFC DLL code...
Hi Michael,
Yes that does seen a long time ago. Internally we’ve moved on from GTest to using Catch2/doctest. the benefit is these are header-only frameworks so much easier to setup and integrate, especially when setting up a CI environment. They both have C++98/03 branches to help support legacy code.
Glad it was useful,
Niall.