Tuesday, 28 February 2017

How to test Cpp application code using Google test framework


Google Test is a unit testing library for the C++ programming language, based on the xUnit architecture. The library is released under the BSD 3-clause license.

Why Google Test Framework ?
  Google test framework is better than other frameworks such as CppUnit, CppTest,Cunit etc.
  Because of the following reasons
  •   You can repeat the same test a thousand times using the Google framework
  •    If you pass --gtest_repeat=2 --gtest_break_on_failure on the command line, the same test  
  •    is  repeated twice. If the test fails, the debugger is automatically invoked.
  •    You can perform death Tests (ASSERT )
  •    Temporarily disabling tests
  •    setup and teardown fixtures etc..
 For more documentation: http://www.ibm.com/developerworks/aix/library/au-googletestingframework.html
  
How to install Google test Framework?
   
Step 1:
   apt-get install libgtest-dev

# It is required to compile the gtest library before you start the application.
Step 2:  Go to your home directory

cd ~

Step 3: Compile the Google Test library (gtest)

g++ -I /usr/include/gtest -I /usr/src/gtest/ -c /usr/src/gtest/src/gtest-all.cc

Step 4: Build the (libgtest.a) static library from gtest-all.o objects (gtest)

ar -rv libgtest.a gtest-all.o

Step 5: Move the (libgtest.a) static library to /usr/lib directory, so that GCC linker can find the library.

mv libgtest.a /usr/lib/


----------------------------------------------------------------------
Sample Example to test the Employee details functionality
----------------------------------------------------------------------
-------------------------------
vim Employee_details.h
-------------------------------

#ifndef EMPLOYEE_DETAILS_H
#define EMPLOYEE_DETAILS_H

#include "string"

using std::string;

class Employee
{
  string employee_name;
  int employee_id;
  int salary;

  public:

  Employee();

  // Set functions
  void setEmployeeName(string name);
  void setEmployeeId(int employee_id);
  void setEmployeeSalary(int salary);

  // Get functions
  string getEmployeeName();
  int getEmployeeId();
  int getEmployeeSalary();

};

#endif /* EMPLOYEE_DETAILS_H */


---------------------------------
vim Employee_details.cpp
---------------------------------
/***************************
 * Employee Details
 *
 ***************************/

#include "Employee_details.h"

  // Default constructor
  Employee :: Employee()
  {

  }

  // set the Employee Name
  void Employee :: setEmployeeName(string name)
  {
      this->employee_name = name;
  }

  // set the Employee Id
  void Employee :: setEmployeeId(int id)
  {
      this->employee_id = id;
  }

  // set the Employee Salary
  void Employee :: setEmployeeSalary(int sal)
  {
      this->salary = sal;
  }

  // get the Employee Name
  string Employee :: getEmployeeName()
  {
      return this->employee_name;
  }

  // get the Employee Id
  int Employee :: getEmployeeId()
  {
      return this->employee_id;
  }

  // get the Employee Salary
  int Employee :: getEmployeeSalary()
  {
      return this->salary;
  }


------------------------------------
vim google_test_example.cpp
-----------------------------------
 
#include "gtest/gtest.h"

#include "string"

// Add the Employee details header file
#include "Employee_details.h"

// Test Case #1
TEST(Employee, testEmployeeName)
{

  string testName="muni";

  // Create emp object
  Employee *emp = new Employee();

  // Set the name
  if(emp)
     emp->setEmployeeName(testName);

  // Validate the Name
  EXPECT_EQ(emp->getEmployeeName(), testName);

  
  delete emp;
}

// Test Case #2
TEST(Employee, testEmployeeId)
{

  int id=3;

  // Create emp object
  Employee *emp = new Employee();

  // Set the name
  if(emp)
     emp->setEmployeeId(id);

  // Validate the Name
  EXPECT_EQ(emp->getEmployeeId(), id);

 
  delete emp;
}

// Test Case #3
TEST(Employee, testEmployeeSalary)
{
  int sal=100;

  // Create emp object
  Employee *emp = new Employee();

  // Set the name
  if(emp)
     emp->setEmployeeSalary(sal);

  // Validate the Salary
  EXPECT_EQ(emp->getEmployeeSalary(), sal);

  
  delete emp;
}

// Main Function
int main(int argc, char* *argv) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}

---------------
vi Makefile
--------------
all:
        g++ -c ./*.cpp
        g++ ./google_test_example.cpp Employee_details.o /usr/lib/libgtest.a -o google_test_example.bin -fPIC -O2 -g -Wall -lpthread

clean:
        rm *.o
        rm ./google_test_example.bin


Output of make file:
root@muni-VirtualBox:/home/muni/google_test# ls
Employee_details.cpp  Employee_details.h  Employee_details.o  google_test_example.bin  google_test_example.cpp  google_test_example.o  Makefile
-----------------------------------

How to run the google test?
-----------------------------------     
       
root@muni-VirtualBox:/home/muni/google_test# ./google_test_example.bin
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from Employee
[ RUN      ] Employee.testEmployeeName
[       OK ] Employee.testEmployeeName (1 ms)
[ RUN      ] Employee.testEmployeeId
[       OK ] Employee.testEmployeeId (0 ms)
[ RUN      ] Employee.testEmployeeSalary
[       OK ] Employee.testEmployeeSalary (0 ms)
[----------] 3 tests from Employee (1 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[  PASSED  ] 3 tests.



# Run the above test case twice
root@muni-VirtualBox:/home/muni/google_test# ./google_test_example.bin --gtest_repeat=2 --gtest_break_on_failure

Repeating all tests (iteration 1) . . .

[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from Employee
[ RUN      ] Employee.testEmployeeName
[       OK ] Employee.testEmployeeName (0 ms)
[ RUN      ] Employee.testEmployeeId
[       OK ] Employee.testEmployeeId (0 ms)
[ RUN      ] Employee.testEmployeeSalary
[       OK ] Employee.testEmployeeSalary (0 ms)
[----------] 3 tests from Employee (1 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (3 ms total)
[  PASSED  ] 3 tests.

Repeating all tests (iteration 2) . . .

[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from Employee
[ RUN      ] Employee.testEmployeeName
[       OK ] Employee.testEmployeeName (0 ms)
[ RUN      ] Employee.testEmployeeId
[       OK ] Employee.testEmployeeId (0 ms)
[ RUN      ] Employee.testEmployeeSalary
[       OK ] Employee.testEmployeeSalary (0 ms)
[----------] 3 tests from Employee (1 ms total)

[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (3 ms total)
[  PASSED  ] 3 tests.
 


No comments:

Post a Comment