jabk
jabk

Reputation: 1458

Unit testing with google test

I want to learn using google test framework with everyday projects, so I looked up a few tutorials, but I have no idea how to get started.

I'm using Qtcreator in Ubuntu 14.04, I downloaded gtest.zip from the google site and unzipped it, but here is where it all stoped.

This is the code i want to "gtest":

//main.cpp
#include <iostream>
#include <cstdlib>
#include "fib.h"
using namespace std;


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

    int n = atof(argv[1]);

    fib fibnumber;
    cout << "\nDesired number is: " << fibnumber.fibRec(n) << endl;

}

//fib.h

#ifndef FIB_H
#define FIB_H

class fib
{
public:
    int fibRec(int n);
};

#endif // FIB_H

//fib.cpp
#include "fib.h"

int fib::fibRec(int n)
{

    if(n <= 0) return 0;
    if(n == 1) return 1;
    else return(fibRec(n-1)+fibRec(n-2));

}

So where do i even begin, I want to make unit test and compile it without any plugins, but i don't know how to make use of the file I unzipped and then use it to write a unit test.

Upvotes: 3

Views: 11771

Answers (2)

Unapiedra
Unapiedra

Reputation: 16197

The google Testing framework works by building it as part of your source code. That means there is no library that you have to link to, instead you build the library when you compile your code (there is a good reason for this).

Have a look at the official documentation: https://github.com/google/googletest/blob/main/docs/primer.md

#Steps

  1. Try to build a test testcase for your program. I can't tell you how to do it with Qtcreator but that should be easy enough to find. Create a test that will definitely fail, like the one below.

    TEST(MyFirstTest, ThisTestShallFail) { EXPECT_EQ(1, 2); }

  2. Run this very simple test to check that it fails. If you want, change it to make it pass.

  3. Start creating your unit tests. Check for a few easy number. Check boundary conditions etc.

Upvotes: 4

ggulgulia
ggulgulia

Reputation: 3060

In addition to @Unapiedra's suggestions, I would suggest to write a separate test file and a separate source/implementation file to test the code with google test framework and link the project using a build system or better a build generator system.

My example below demonstrates this using a cmake build generator. (My assumption here is that the user is familiar with cmake)

Note: although in practice it is recommended to write code incrementally using the Test Driven Development philosophy, I don't do it since the purpose here is to show how a simple unit test can be written and compiled using google test framework.

charOperations.hpp

#ifndef CHAR_OPERATIONS_H
#define CHAR_OPERATIONS_H

#incude <string>

    class CharOperations{
        private :
               // ... 
        public:

            //converts lower case characters to upper case
            // and returns a std::string object from this
            std::string convertToUpper(const char letter){ 
                char upCase = std::toupper(static_cast<unsigned char>(letter));
                return std::string(1, upCase);
            }


            //converts upper case characters to lower case
            // and returns a std::string object from this
            std::string convertToLower(const char letter){ 
                char loCase = std::tolower(static_cast<unsigned char>(letter));
                return std::string(1, loCase);
            }

            // more functions ...
    };
#endif //class definition ends

test_example.cpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "CharOperations.hpp"

//declare a test fixture so that the object
// CharOperation need not be declared in each test
//Each test fixture has to be publicly derived from 
// testing::Test 
class CharOperationsTest : public testing::Test{
    //class object public so that it is accessible
    //within the tests that are written
    public:
        CharOperations charOps;
};

// now write the tests using macro TEST_F 
// which is used for testing with test fixtures
//1st parameter to TEST_F is the name of the fixture
//second parameter to TEST_F is the name of the test
//each test has to have a unique name.

//test #1
TEST_F(CharOperationsTest, ConvertsCharToUpperCaseString){
    ASSERT_THAT(charOps.convertToUpper('a') testing::Eq("A");
}

//test #2
TEST_F(CharOperationsTest, ConvertsCharToLowerCaseString){
    ASSERT_THAT(charOps.convertToLower('A') testing::Eq("a");
}

//more tests ...

//run all tests 
int main(int argc, char **argv){
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.2.3)                                                                                                                 
project(TDD CXX)               
enable_testing()
set(CMAKE_CXX_STANDARD 11)     

find_package(PkgConfig REQUIRED)
pkg_check_modules(gtest REQUIRED gtest>=1.8.1)
pkg_check_modules(gmock REQUIRED gmock>=1.8.1)

include_directories(${gtest_INCLUDE_DIRS})
include_directories(${gmock_INCLUDE_DIRS})

add_executable(test.out  ##target executable name
               test_example.cpp 
               )

target_link_libraries(test.out ${gtest_LIBRARIES})

A general suggestion for writing tests: It can be observed in the file test_example.cpp, the Macros/Functions Test. Eq and InitGoogleTests reside under the namespace testing. Hence it might be prudent to declare a using namespace testing declaration at the beginning of the file after all #includes. Lastly needles to say to compile in a separate build directory

Upvotes: 0

Related Questions