Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Boost Licence Version Build Status Coveralls Github Issues


Testing

"If you liked it then you should have put a test on it", Beyonce rule

GUnit

Google.Test/Google.Mock/Cucumber on steroids

  • Improve your productivity with GUnit, a library which extends/simplifies Google.Test/Google.Mock and adds support for Gherkin (Behaviour Driven Development) to it.

    • Why it's based on Google.Test/Google.Mock?
      • (+) Google.Test is widely used (The most popular testing framework according to https://www.jetbrains.com/research/devecosystem-2017/cpp)
      • (+) Google.Test is stable
      • (+) Google.Test is powerful
      • (+) Google.Test comes with Google.Mock
      • (+) Google.Test is well documented
      • (-) Google.Test doesn't have support for - gherkin style - tests
      • (-) Google.Test and Google.Mock have a lot boilerplate macros

Motivation Examples

No more base classes and labels as identifiers - GUnit.GTest / GUnit.GTest-Lite

               Google.Test                        |                     GUnit.GTest
--------------------------------------------------+------------------------------------------------------
#include <gtest/gtest.h>                          | #include <GUnit.h>
                                                  |
struct CalcTest : testing::Test {                 | GTEST("Calc Test") {
 void SetUp() override {                          |   Calc calc{};
   calc = std::make_unique<Calc>();               |
 }                                                |   // SetUp
                                                  |
 void TearDown() override { }                     |   SHOULD("return sum of 2 numbers") {
                                                  |     EXPECT_EQ(5, calc->add(4, 1));
 std::unique_ptr<Calc> calc;                      |   }
};                                                |
                                                  |   SHOULD("throw if division by 0") {
TEST_F(CalcTest, ShouldReturnSumOf2Numbers) {  |     EXPECT_ANY_THROW(calc->div(42, 0));
  EXPECT_EQ(5, calc->add(4, 1));                  |   }
}                                                 |
                                                  |   // TearDown
TEST_F(CalcTest, ShouldThrowIfDivisionBy0) {   | }
  EXPECT_ANY_THROW(calc->div(42, 0));             |
}                                                 |

Output

[----------] 2 tests from CalcTest                | [----------] 1 tests from Calc Test
[ RUN      ] CalcTest.ShouldReturnSumOf2Numbers   | [ RUN      ] Calc Test
[       OK ] CalcTest.ShouldReturnSumOf2Numbers   | [ SHOULD   ] return sum of 2 numbers
[ RUN      ] CalcTest.ShouldThrowIfDivisionBy0    | [ SHOULD   ] throw if division by 0
[       OK ] CalcTest.ShouldThrowIfDivisionBy0    | [       OK ] Calc Test (0 ms)
[----------] 2 tests from CalcTest (1 ms total)   | [----------] 1 tests from Example (0 ms total)

No more hand written mocks - GUnit.GMock

struct interface {
  virtual ~interface() = default;
  virtual int get() const = 0;
  virtual void foo(int) = 0;
  virtual void bar(int, const std::string&) = 0;
};
               Google.Test                        |                     GUnit.GMock
--------------------------------------------------+------------------------------------------------------
#include <gmock/gmock.h>                          | #include <GUnit.h>
                                                  |
struct mock_interface : interface {               |
  MOCK_CONST_METHOD0(get, int(int));              |
  MOCK_METHOD1(foo, void(int));                   |
  MOCK_METHOD2(bar, void(int, const string&));    |
};                                                |
                                                  |
int main() {                                      | int main() {
  StrictMock<mock_interface> mock{};              |   StrictGMock<interface> mock{};
  EXPECT_CALL(mock, foo(42));                     |   EXPECT_CALL(mock, (foo)(42));
                                                  |
  interface& i = mock;                            |   interface& i = mock.object();
  i.foo(42);                                      |   i.foo(42);
}                                                 | }

Simplified creation and injection of SUT (System Under Test) and mocks - GUnit.GMake

class coffee_maker {
 public:
   coffee_maker(iheater&, ipump&, igrinder&);
   ...
};
               Google.Test                        |                     GUnit.GMake
--------------------------------------------------+------------------------------------------------------
 #include <gtest/gtest.h>                         | #include <GUnit.h>
 #include <gmock/gmock.h>                         |
                                                  |
 TEST(CalcTest, ShouldMakeCoffee) {               | GTEST("Calc Test") {
   StrictMock<mock_heater> heater{};              |   std::tie(sut, mocks) = // auto [sut, mocks] in C++17
   StrictMock<mock_pump> pump{};                  |     make<coffee_maker, StrictGMock>();
   StrictMock<mock_grinder> grinder{};            |
   coffee_maker sut{heater, pump, grinder};       |   EXPECT_CALL(mocks.mock<iheater>(), (on)());
                                                  |   EXPECT_CALL(mocks.mock<ipump>(), (pump)());
   EXPECT_CALL(heater, on());                     |   EXPECT_CALL(mocks.mock<igrinder>(), (grind)());
   EXPECT_CALL(pump, pump());                     |   EXPECT_CALL(mocks.mock<iheater>(), (off)());
   EXPECT_CALL(grinder, grind());                 |
   EXPECT_CALL(heater, off());                    |   sut->brew();
                                                  | }
   sut->brew();                                   |
 }

Support for - Gherkin style - BDD (Behaviour Driven Development) scenarios - GUnit.GSteps

Feature specification

Test/Features/Calc/addition.feature
Feature: Calc Addition
  In order to avoid silly mistakes
  As a math idiot
  I want to be told the sum of two numbers

  Scenario: Add two numbers
    Given I created a calculator with value 0
      And I have entered 20 into the calculator
      And I have entered 30 into the calculator
     When I press add
     Then The result should be 50

Steps Implementation

Test/Features/Calc/Steps/CalcSteps.cpp
#include <GUnit.h>

GSTEPS("Calc*") { // "Calc Addition.Add two numbers"
  auto result = 0;

  Given("I created a calculator with value {n}") = [&](int n) {
    Calculator calc{n};

    Given("I have entered {n} into the calculator") = [&](int n) {
      calc.push(n);
    };

    When("I press add") = [&] {
      result = calc.add();
    };

    Then("The result should be {expected}") = [&](int expected) {
       EXPECT_EQ(expected, result);
    };
  };
}

Usage

SCENARIO="Test/Features/Calc/addition.feature" ./test --gtest_filter="Calc Addition.Add two numbers"

Output

[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 tests from Calc Addition
[ RUN      ] Calc Addition.Add two numbers
[    Given ] I have created a calculator with value 0         # CalcSteps.cpp:10
[    Given ] I have entered 20 into the calculator            # CalcSteps.cpp:12
[    Given ] I have entered 30 into the calculator            # CalcSteps.cpp:14
[     When ] I press add                                      # CalcSteps.cpp:16
[     Then ] the result should be 50 on the screen            # CalcSteps.cpp:19
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (7 ms total)
[  PASSED  ] 1 tests.

Overview

  • GUnit.GTest - Google.Test with strings and more friendly macros
    • Test cases with string as names
    • No more SetUp/TearDown (SHOULD clauses)
    • One (GTEST) macro for all types of tests
    • 100% Compatible with tests using GTest
  • GUnit.GTest-Lite - lightweight, limited, no-macro way of defining simple tests
  • GUnit.GMock - Google.Mock without hand written mocks
    • No more hand written mocks!
    • Support for more than 10 parameters
    • Quicker compilation times
    • Support for unique_ptr without any tricks
    • Support for overloaded operators
    • Support for mocking classes with constructors
    • 100% Compatible with Google Mocks
  • GUnit.GMake - Makes creation of System Under Test (SUT) and Mocks easier
    • No need to instantiate SUT (System Under Test) and mocks
      • Automatic mocks injection
  • GUnit.GSteps - Behaviour Driven Development
    • Support for - Gherkin style - BDD tests

Quick Start


  • [Optional] For gherkin support
    • Compile gherkin-cpp
    $cd libs/gherkin-cpp && make lib
    $ls libs/gherkin-cpp
      libgherkin-cpp.a
      libgherkin-cpp.so
    • Add include paths
      • -I GUnit/gherkin-cpp/include
      • -I GUnit/json/src
    • Link with libgherkin-cpp.{a, so}
      • -L libgherkin-cpp
    • Write some feature tests...
    • Compile and Run!

  • To run GUnit tests/benchmarks
    $mkdir build && cd build && cmake ..
    $make && ctest

Requirements

Tested compilers

User Guide

FAQ

Acknowledgements

You can’t perform that action at this time.