Getting Started With GTest (C++) with Xcode!

This is an inaugural post as well as a useful little tutorial on how to setup G-Test for C++ with Xcode. There are some other tutorials out there, but I figured I’d go into specifics for the complete beginners out there.

First you’re going to need to check out the code for google test. Either:

git clone http://git.chromium.org/external/googletest.git

or

just download the zip from the googletest webpage

Once you have it, go into the xcode/ directory and open up the Xcode project. So, since Google doesn’t seem to update C++ support for Xcode very often, the config of the Xcode project is a bit outdated, so we’re going to have to manually update it. What worked for me was to just comment out SDKROOT and GCC_VERSION in Config/General.xcconfig and to update MACOSX_DEPLOYMENT_TARGET = 10.7 (Note: This might not be necessary if you’re using an older version of Mac OsX or Xcode, but assuming you’re using the latest, you’ll probably need to do this.)

So that’s it. Build it by hitting the big Run button. With these changes, the build should succeed. Go to the directory where you built it (if you don’t know where that is, check Xcode->Preferences->Locations->Derived Data, that’s your build directory). That’s your Framework.

Now the interesting part, using it. Other than this tutorial and the Google intro to their framework you can use this, it’s IBM’s intro to the framework which is pretty useful:

http://www.ibm.com/developerworks/aix/library/au-googletestingframework.html?ca=drs-

For the purposes of this intro and for a little tie in to the next tutorial, we’re going to be doing a bit of test driven development. If you don’t know TDD, it’s when you actually create the tests first for your use cases (the various functions of your app), before you even write the code. Then you write the least amount of code possible to make your tests pass. So to start, all your tests are failing. Weird eh? The point of this is to make very concise functional code that has large test coverage through each iteration of development. Anyways, so I’m actually creating a small version of the dc function of your terminal. If you don’t know what it is, check it: http://linux.about.com/library/cmd/blcmdl1_dc.htm . It’s basically a stack-based calculator (if you’re REALLY a beginner and don’t know what a stack is: http://en.wikipedia.org/wiki/Stack_(abstract_data_type) ).

Anyways, let’s get started:

In Xcode create a New Project. For the purposes of this application I’m going to use Shell (Or Command Line) application. For most testing suites you’ll be using this anyways. You’re going to need to add the gtest.framework that you built to this project:

right click -> add to this project -> go to your build directory and choose gtest.framework

Note: If you can’t see your build directory. Copy the stuff in your build maybe to where you’re keeping your code which isn’t a hidden directory and select it from there.

Make sure the framework was added under the Build Phases tab under Link Binary With Libraries. That’s it for setup. Now for some coding!

Create a new file tests.cpp and:

#include “gtest/gtest.h”

Since we’re going to be exercising a little bit of our Comp Sci skills we’re actually going to implement a stack when we write the actual code, so let’s test the functionality of this stack and the basic adding of numbers to the stack. To do TDD we do need the method calls without the implementation so essentially we’re just going to make stack.h.

template <class T>
class Stack {
public:
  Stack(void);
  ~Stack(void); //Destructor
  int empty(void);
  int push(T &);
  T pop(void);
  T peek(void);
private:
  int top;
  T* nodes;
};

And then the tests in tests.cpp:

#include "stack.h"
#include "gtest/gtest.h"

TEST (StackTest, PushAndPeek) {
    Stack intStack;
    int a = 12;
    int b = 15;
    EXPECT_EQ (12, intStack.push(a));
    EXPECT_EQ (15, intStack.push(b));
    EXPECT_EQ (15, intStack.peek()); 
    //make sure adding in LIFO Order
    EXPECT_EQ (15, intStack.peek()); 
    //Should still be there
}

TEST (StackTest, PushAndPop) {
    Stack intStack;
    int a = 12;
    int b = 15;
    EXPECT_EQ (12, intStack.push(a));
    EXPECT_EQ (15, intStack.push(b));
    EXPECT_EQ (15, intStack.pop()); 
//make sure adding in LIFO Order
    EXPECT_EQ (12, intStack.pop()); 
//Should have removed 15, then removed 12
    EXPECT_EQ (-1, intStack.pop()); 
//Should return -1 because there is nothing on the stack
}

Note: The reason I’m assigning a = 12 and b=15 is because XCode will throw a an error saying you cannot assign a temporary value to a non-constant lvalue of type int.

Also I’m going to make the main function in main.cpp, I’m going to allow for two options on starting the program: either run the tests or just run the program.

#include <iostream> 
#include <string>
#include "gtest/gtest.h"
#include "stack.h"
using namespace std;

int main(int argc, char * argv[])
{
    string input;

    cout << "Hey there! Welcome to MiniDc! 
If you wanna run the tests, type in tests. \n
Other wise just hit enter to continue...\n";

    getline (cin, input);

    if(input == "tests"){
        ::testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    }

    return 0;
}

Obviously, it won’t build because there are no definitions for the Stack yet, but the beginnings are there and the tests are there, so that’s a little start to TDD (Test Driven Development) and the Google C++ Test Framework. I will follow with some subsequent posts on actually filling up the code for the stack. Implementing the MiniDc functionality and more descriptions of the GTest functions! Stay tuned!

Advertisements

One comment

  1. what a splendid tutorial!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: