Installation

  1. Install CMake:
  1. sudo apt install cmake
  1. Switch to home directory and:
  1. git clone --depth 1 https://github.com/google/googletest.git
  1. Build it:
  1. cd ~/googletest
  2. mkdir build
  3. cd build
  4. cmake -Dgtest_build_samples=ON -Dgtest_build_tests=ON ~/googletest
  5. make
  6. make test
  7. ./googlemock/gtest/sample1_unittest
  1. Install the googletest and googlemock .a and .h files:
  1. sudo cp -r -v ~/googletest/googletest/include/gtest /usr/local/include
  2. sudo cp -r -v ~/googletest/googlemock/include/gmock /usr/local/include
  3. sudo cp -v ~/googletest/build/googlemock/lib*.a /usr/local/lib
  4. sudo cp -v ~/googletest/build/googlemock/gtest/lib*.a /usr/local/lib


References

  1. Repository & Readme.md:
    https://github.com/google/googletest
  2. Build and install Google Test:
    https://gist.github.com/massenz/41bb2c8375294f4d9927
  3. Primer:
    https://github.com/google/googletest/blob/master/googletest/docs/Primer.md
  4. C++ Unit Testing with Google Test Tutorial (Youtube):
    https://www.youtube.com/watch?v=16FI1-d2P4E
  5. StackOverflow: How to configure and setup google test framework in linux
    https://stackoverflow.com/questions/19810731/how-to-configure-and-setup-google-test-framework-in-linux


Examples

TEST() and code in same file

Test Fail

01sqrt_fail.cpp

Run:

#include <iostream>
#include <gtest/gtest.h>

double squareroot (double) {
 
return 0;
};

TEST (SquareRootTest, PositiveNos) { 
 
EXPECT_EQ (18.0, squareroot (324.0));
 
EXPECT_EQ (25.4, squareroot (645.16));
 
EXPECT_EQ (50.332, squareroot (2533.310224));
}

TEST (SquareRootTest, ZeroAndNegativeNos) { 
 
ASSERT_EQ (0.0, squareroot (0.0));
 
ASSERT_EQ (-1, squareroot (-22.0));
}

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

  • g++ 01sqrt_fail.cpp -lgtest -lpthread -o 01sqrt_fail
  • ./01sqrt_fail

Test Pass

01sqrt_pass.cpp

Run:

#include <iostream>
#include <math.h>
#include <gtest/gtest.h>

double squareroot (double a) {
 
if(a<0)
   
return -1;
 
else
   
return sqrt(a);
};

TEST (SquareRootTest, PositiveNos) { 
 
EXPECT_EQ (18.0, squareroot (324.0));
 
EXPECT_EQ (25.4, squareroot (645.16));
 
EXPECT_EQ (50.332, squareroot (2533.310224));
}

TEST (SquareRootTest, ZeroAndNegativeNos) { 
 
ASSERT_EQ (0.0, squareroot (0.0));
 
ASSERT_EQ (-1, squareroot (-22.0));
}

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

  • g++ 01sqrt_pass.cpp -lgtest -lpthread -o 01sqrt_pass
  • ./01sqrt_pass


TEST_F() and code in same file

02bankacc_pass.cpp

Run:

#include <iostream>
#include <gtest/gtest.h>

struct BankAccount {

 
int balance = 0;
        
 
BankAccount() {
 
}

 
explicit BankAccount(const int balance)
 
: balance{balance} {
 
}

};

struct BankAccountTest : testing::Test
{ 
 
BankAccount *account;

 
BankAccountTest() {
   
account = new BankAccount;
 
}
 
~BankAccountTest() {
   
delete account;
 
}
};

TEST_F(BankAccountTest, BankAccountStartsEmpty) {
 
EXPECT_EQ(0, account->balance);
}

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

  • g++ 02bankacc_pass.cpp -std=c++11 -lgtest -lpthread -o 02bankacc_pass
  • ./02bankacc_pass

TEST_P() and code in same file

Test Fail

03bankacc_fail.cpp

Run:

#include <iostream>
#include <gtest/gtest.h>

struct BankAccount {

 
int balance = 0;
        
 
BankAccount() {
 
}

 
explicit BankAccount(const int balance)
 
: balance{balance} {
 
}
 
 
void deposit(int amount) {
   
balance += amount;
 
}

 
bool withdraw(int amount) {
 
}
};

struct BankAccountTest : testing::Test { 
 
BankAccount *account;

 
BankAccountTest() {
   
account = new BankAccount;
 
}
 
virtual ~BankAccountTest() {
   
delete account;
 
}
};

struct account_state {
 
int initial_balance;
 
int withdrawal_amount;
 
int final_balance;
 
bool success;
};

struct withdrawAccountTest : BankAccountTest , testing::WithParamInterface<account_state>
{
 
 
withdrawAccountTest() {
   
account->balance = GetParam().initial_balance;
 
}
};

TEST_P(withdrawAccountTest, FinalBalance) {
 
auto as = GetParam();
 
auto success = account->withdraw(as.withdrawal_amount);
 
EXPECT_EQ(as.final_balance,account->balance);
 
EXPECT_EQ(as.success,success);
}

INSTANTIATE_TEST_CASE_P(Default, withdrawAccountTest,
 
testing::Values(
   
account_state{100,50,50,true},
   
account_state{100,200,100,false}
   
));

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

  • g++ 03bankacc_fail.cpp -std=c++11 -lgtest -lpthread -o 03bankacc_fail
  • ./03bankacc_fail


Test Pass

03bankacc_pass.cpp

Run:

#include <iostream>
#include <gtest/gtest.h>

struct BankAccount {

 
int balance = 0;
        
 
BankAccount() {
 
}

 
explicit BankAccount(const int balance)
 
: balance{balance} {
 
}
 
 
void deposit(int amount) {
   
balance += amount;
 
}

 
bool withdraw(int amount) {
   
if (amount <= balance) {
     
balance -= amount;
     
return true;
   
}
   
return false;
 
}
};

struct BankAccountTest : testing::Test { 
 
BankAccount *account;

 
BankAccountTest() {
   
account = new BankAccount;
 
}
 
virtual ~BankAccountTest() {
   
delete account;
 
}
};

struct account_state {
 
int initial_balance;
 
int withdrawal_amount;
 
int final_balance;
 
bool success;
};

struct withdrawAccountTest : BankAccountTest , testing::WithParamInterface<account_state> { 
 
withdrawAccountTest() {
   
account->balance = GetParam().initial_balance;
 
}
};

TEST_P(withdrawAccountTest, FinalBalance) {
 
auto as = GetParam();
 
auto success = account->withdraw(as.withdrawal_amount);
 
EXPECT_EQ(as.final_balance,account->balance);
 
EXPECT_EQ(as.success,success);
}

INSTANTIATE_TEST_CASE_P(Default, withdrawAccountTest,
 
testing::Values(
   
account_state{100,50,50,true},
   
account_state{100,200,100,false}
   
));

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

  • g++ 03bankacc_pass.cpp -std=c++11 -lgtest -lpthread -o 03bankacc_pass
  • ./03bankacc_pass


Test Fail & Formatted Output

03bankacc_format.cpp

Run:

#include <iostream>
#include <gtest/gtest.h>

struct BankAccount {

 
int balance = 0;
        
 
BankAccount() {
 
}

 
explicit BankAccount(const int balance)
 
: balance{balance} {
 
}
 
 
void deposit(int amount) {
   
balance += amount;
 
}

 
bool withdraw(int amount) {
   
// if (amount <= balance) {
   
//   balance -= amount;
   
//   return true;
   
// }
   
return false;
 
}
};

struct BankAccountTest : testing::Test { 
 
BankAccount *account;

 
BankAccountTest() {
   
account = new BankAccount;
 
}
 
virtual ~BankAccountTest() {
   
delete account;
 
}
};

struct account_state {
 
int initial_balance;
 
int withdrawal_amount;
 
int final_balance;
 
bool success;

 
friend std::ostream& operator <<(std::ostream& os, const account_state & obj) {
   
return os
     
<< "initial_balance: " << obj.initial_balance
     
<< " withdrawal_amount: " << obj.withdrawal_amount
     
<< " final_balance: " << obj.final_balance
     
<< " success: " << obj.success;
 
}
};

struct withdrawAccountTest : BankAccountTest , testing::WithParamInterface<account_state> { 
 
withdrawAccountTest() {
   
account->balance = GetParam().initial_balance;
 
}
};

TEST_P(withdrawAccountTest, FinalBalance) {
 
auto as = GetParam();
 
auto success = account->withdraw(as.withdrawal_amount);
 
EXPECT_EQ(as.final_balance,account->balance);
 
EXPECT_EQ(as.success,success);
}

INSTANTIATE_TEST_CASE_P(Default, withdrawAccountTest,
 
testing::Values(
   
account_state{100,50,50,true},
   
account_state{100,200,100,false}
   
));

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

  • g++ 03bankacc_format.cpp -std=c++11 -lgtest -lpthread -o 03bankacc_format
  • ./03bankacc_format