{"id":14969308,"url":"https://github.com/cpp-testing/gunit","last_synced_at":"2025-05-16T07:07:10.006Z","repository":{"id":41579750,"uuid":"77401922","full_name":"cpp-testing/GUnit","owner":"cpp-testing","description":"GUnit - Google.Test/Google.Mock/Cucumber on steroids","archived":false,"fork":false,"pushed_at":"2025-04-02T15:45:51.000Z","size":8340,"stargazers_count":266,"open_issues_count":22,"forks_count":57,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-05-16T07:07:03.784Z","etag":null,"topics":["bdd","cucumber","gherkin","googlemock","googletest","gunit","mock","tdd"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cpp-testing.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-26T19:05:42.000Z","updated_at":"2025-05-07T04:40:55.000Z","dependencies_parsed_at":"2023-02-01T05:45:46.495Z","dependency_job_id":"0e1e8456-a37e-4a5f-9698-ff02dedd8187","html_url":"https://github.com/cpp-testing/GUnit","commit_stats":{"total_commits":351,"total_committers":25,"mean_commits":14.04,"dds":0.2991452991452992,"last_synced_commit":"9872bc31cf0bbd8a1934907696c925358a8be0e5"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpp-testing%2FGUnit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpp-testing%2FGUnit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpp-testing%2FGUnit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cpp-testing%2FGUnit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cpp-testing","download_url":"https://codeload.github.com/cpp-testing/GUnit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485065,"owners_count":22078767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","cucumber","gherkin","googlemock","googletest","gunit","mock","tdd"],"created_at":"2024-09-24T13:41:34.749Z","updated_at":"2025-05-16T07:07:04.991Z","avatar_url":"https://github.com/cpp-testing.png","language":"C++","readme":"\u003ca href=\"http://www.boost.org/LICENSE_1_0.txt\" target=\"_blank\"\u003e![Boost Licence](http://img.shields.io/badge/license-boost-blue.svg)\u003c/a\u003e\n\u003ca href=\"https://github.com/cpp-testing/GUnit/releases\" target=\"_blank\"\u003e![Version](https://badge.fury.io/gh/cpp-testing%2FGUnit.svg)\u003c/a\u003e\n\u003ca href=\"https://github.com/cpp-testing/GUnit/actions/workflows/linux.yml\" target=\"_blank\"\u003e![Build](https://github.com/cpp-testing/GUnit/actions/workflows/linux.yml/badge.svg)\u003c/a\u003e\n\u003ca href=\"https://github.com/cpp-testing/GUnit/actions/workflows/macos.yml\" target=\"_blank\"\u003e![Build](https://github.com/cpp-testing/GUnit/actions/workflows/macos.yml/badge.svg)\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/cpp-testing/GUnit\" target=\"_blank\"\u003e![Coveralls](https://codecov.io/gh/cpp-testing/GUnit/branch/master/graph/badge.svg)\u003c/a\u003e\n\u003ca href=\"http://github.com/cpp-testing/GUnit/issues\" target=\"_blank\"\u003e![Github Issues](https://img.shields.io/github/issues/cpp-testing/GUnit.svg)\u003c/a\u003e\n\n---\n\n### Testing\n\n\u003e \"If you liked it then you should have put a test on it\", Beyonce rule\n\n## GUnit\n\u003e [Google.Test/Google.Mock](https://github.com/google/googletest)/[Cucumber](https://github.com/cucumber/cucumber/wiki/Gherkin) on steroids\n\n* Improve your productivity with GUnit, a library which extends/simplifies [Google.Test/Google.Mock](https://github.com/google/googletest) and adds support for [Gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) (Behaviour Driven Development) to it.\n\n    * Why it's based on [Google.Test/Google.Mock](https://github.com/google/googletest)?\n        * (+) Google.Test is **widely used** (The most popular testing framework according to https://www.jetbrains.com/research/devecosystem-2017/cpp)\n        * (+) Google.Test is **stable**\n        * (+) Google.Test is **powerful**\n        * (+) Google.Test comes with **Google.Mock**\n        * (+) Google.Test is **well documented**\n        * (-) Google.Test **doesn't have support for - [gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) style - tests**\n        * (-) Google.Test and Google.Mock have a lot **boilerplate macros**\n\n### Motivation Examples\n\n\u003e #### No more base classes, labels as identifiers and special assertions - [GUnit.GTest](docs/GTest.md) / [GUnit.GTest-Lite](docs/GTest-Lite.md)\n  ```cpp\n                 Google.Test                     |               GUnit.GTest\n  -----------------------------------------------+-----------------------------------------\n  #include \u003cgtest/gtest.h\u003e                       | #include \u003cGUnit.h\u003e\n                                                 |\n  struct CalcTest : testing::Test {              | GTEST(\"Calc Test\") {\n   void SetUp() override {                       |   Calc calc{};\n     calc = std::make_unique\u003cCalc\u003e();            |\n   }                                             |   // SetUp\n                                                 |\n   void TearDown() override { }                  |   SHOULD(\"return sum of 2 numbers\") {\n                                                 |     EXPECT(5 == calc-\u003eadd(4, 1));\n   std::unique_ptr\u003cCalc\u003e calc;                   |   }\n  };                                             |\n                                                 |   SHOULD(\"throw if division by 0\") {\n  TEST_F(CalcTest, ShouldReturnSumOf2Numbers) {  |     EXPECT_ANY_THROW(calc-\u003ediv(42, 0));\n    EXPECT_EQ(5, calc-\u003eadd(4, 1));               |   }\n  }                                              |\n                                                 |   // TearDown\n  TEST_F(CalcTest, ShouldThrowIfDivisionBy0) {   | }\n    EXPECT_ANY_THROW(calc-\u003ediv(42, 0));          |\n  }                                              |\n  ```\n\n  \u003e Output\n  ```sh\n  [----------] 2 tests from CalcTest             | [----------] 1 tests from Calc Test\n  [ RUN      ] CalcTest.ShouldReturnSumOf2Numbers| [ RUN      ] Calc Test\n  [       OK ] CalcTest.ShouldReturnSumOf2Numbers| [ SHOULD   ] return sum of 2 numbers\n  [ RUN      ] CalcTest.ShouldThrowIfDivisionBy0 | [ SHOULD   ] throw if division by 0\n  [       OK ] CalcTest.ShouldThrowIfDivisionBy0 | [       OK ] Calc Test (0 ms)\n  [----------] 2 tests from CalcTest (1 ms total)| [----------] 1 tests from Example\n  ```\n\n\u003e #### No more hand written mocks - [GUnit.GMock](docs/GMock.md)\n  ```cpp\n  struct interface {\n    virtual ~interface() = default;\n    virtual int get() const = 0;\n    virtual void foo(int) = 0;\n    virtual void bar(int, const std::string\u0026) = 0;\n  };\n  ```\n  ```cpp\n                 Google.Test                     |           GUnit.GMock\n  -----------------------------------------------+--------------------------------------\n  #include \u003cgmock/gmock.h\u003e                       | #include \u003cGUnit.h\u003e\n                                                 |\n  struct mock_interface : interface {            |\n    MOCK_CONST_METHOD0(get, int(int));           |\n    MOCK_METHOD1(foo, void(int));                |\n    MOCK_METHOD2(bar, void(int, const string\u0026)); |\n  };                                             |\n                                                 |\n  int main() {                                   | int main() {\n    StrictMock\u003cmock_interface\u003e mock{};           |   StrictGMock\u003cinterface\u003e mock{};\n    EXPECT_CALL(mock, foo(42));                  |   EXPECT_CALL(mock, (foo)(42));\n                                                 |\n    interface\u0026 i = mock;                         |   interface\u0026 i = mock.object();\n    i.foo(42);                                   |   i.foo(42);\n  }                                              | }\n  ```\n\n\u003e #### Simplified creation and injection of SUT (System Under Test) and mocks - [GUnit.GMake](docs/GMake.md)\n  ```cpp\n  class coffee_maker {\n   public:\n     coffee_maker(iheater\u0026, ipump\u0026, igrinder\u0026);\n     ...\n  };\n  ```\n  ```cpp\n                 Google.Test              |                     GUnit.GMake\n  ----------------------------------------+--------------------------------------------------\n  #include \u003cgtest/gtest.h\u003e                | #include \u003cGUnit.h\u003e\n  #include \u003cgmock/gmock.h\u003e                |\n                                          |\n  TEST(CalcTest, ShouldMakeCoffee) {      | GTEST(\"Calc Test\") {\n    StrictMock\u003cmock_heater\u003e heater{};     |   auto [sut, mocks] =\n    StrictMock\u003cmock_pump\u003e pump{};         |     make\u003ccoffee_maker, StrictGMock\u003e();\n    StrictMock\u003cmock_grinder\u003e grinder{};   |\n    coffee_maker sut{heater,pump,grinder};|   EXPECT_CALL(mocks.mock\u003ciheater\u003e(), (on)());\n                                          |   EXPECT_CALL(mocks.mock\u003cipump\u003e(), (pump)());\n    EXPECT_CALL(heater, on());            |   EXPECT_CALL(mocks.mock\u003cigrinder\u003e(), (grind)());\n    EXPECT_CALL(pump, pump());            |   EXPECT_CALL(mocks.mock\u003ciheater\u003e(), (off)());\n    EXPECT_CALL(grinder, grind());        |\n    EXPECT_CALL(heater, off());           |   sut-\u003ebrew();\n                                          | }\n    sut-\u003ebrew();                          |\n  }\n  ```\n\n\u003e #### Support for - [Gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) style - BDD (Behaviour Driven Development) scenarios - [GUnit.GSteps](docs/GSteps.md)\n\n  \u003e Feature specification\n\n    Test/Features/Calc/addition.feature\n\n  ```gherkin\n  Feature: Calc Addition\n    In order to avoid silly mistakes\n    As a math idiot\n    I want to be told the sum of two numbers\n\n    Scenario: Add two numbers\n      Given I created a calculator with value 0\n        And I have entered 20 into the calculator\n        And I have entered 30 into the calculator\n       When I press add\n       Then The result should be 50\n  ```\n\n  \u003e Steps Implementation\n\n    Test/Features/Calc/Steps/CalcSteps.cpp\n\n  ```cpp\n  #include \u003cGUnit.h\u003e\n\n  GSTEPS(\"Calc*\") { // \"Calc Addition.Add two numbers\"\n    auto result = 0;\n\n    Given(\"I created a calculator with value {n}\") = [\u0026](int n) {\n      Calculator calc{n};\n\n      Given(\"I have entered {n} into the calculator\") = [\u0026](int n) {\n        calc.push(n);\n      };\n\n      When(\"I press add\") = [\u0026] {\n        result = calc.add();\n      };\n\n      Then(\"The result should be {expected}\") = [\u0026](int expected) {\n         EXPECT_EQ(expected, result);\n      };\n    };\n  }\n  ```\n\n  \u003e Usage\n  ```sh\n  SCENARIO=\"Test/Features/Calc/addition.feature\" \\\n    ./test --gtest_filter=\"Calc Addition.Add two numbers\"\n  ```\n\n  \u003e Output\n  ```sh\n  [==========] Running 1 test from 1 test case.\n  [----------] Global test environment set-up.\n  [----------] 1 tests from Calc Addition\n  [ RUN      ] Calc Addition.Add two numbers\n  [    Given ] I have created a calculator with value 0         # CalcSteps.cpp:10\n  [    Given ] I have entered 20 into the calculator            # CalcSteps.cpp:12\n  [    Given ] I have entered 30 into the calculator            # CalcSteps.cpp:14\n  [     When ] I press add                                      # CalcSteps.cpp:16\n  [     Then ] the result should be 50 on the screen            # CalcSteps.cpp:19\n  [----------] Global test environment tear-down\n  [==========] 1 test from 1 test case ran. (7 ms total)\n  [  PASSED  ] 1 tests.\n  ```\n\n### Overview\n\n* `GUnit.GTest` - Google.Test with strings and more friendly macros\n  * Test cases with string as names\n  * No more SetUp/TearDown (SHOULD clauses)\n  * One (GTEST) macro for all types of tests\n  * 100% Compatible with tests using GTest\n* `GUnit.GTest-Lite` - lightweight, limited, no-macro way of defining simple tests\n* `GUnit.GMock` - Google.Mock without hand written mocks\n  * No more hand written mocks!\n  * Support for more than 10 parameters\n  * Quicker compilation times\n  * Support for unique_ptr without any tricks\n  * Support for overloaded operators\n  * Support for mocking classes with constructors\n  * 100% Compatible with Google Mocks\n* `GUnit.GMake` - Makes creation of System Under Test (SUT) and Mocks easier\n  * No need to instantiate SUT (System Under Test) and mocks\n    * Automatic mocks injection\n* `GUnit.GSteps` - Behaviour Driven Development\n  * Support for - [Gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) style - BDD tests\n* `GUnit.GAssert` - Google.Test assertions without postfixes\n  * Simple/consised interface - `EXPECT(true); EXPECT(.0 \u003e 2.0); ASSERT(11 != 42), ...`\n  * No more EXPECT_EQ/EXPECT_GT/...\n  * No more confusing error messages depending on expected, given parameters\n  * No more bugs due to using the wrong EXPECT for floating point numbers (EXPECT_DOUBLE_EQ) and/or strings\n  * No more implicit conversions between types!\n\n### Quick Start\n\n* If your project is **NOT** using [Google.Test/Google.Mock](https://github.com/google/googletest)\n    * Follow instructions from https://github.com/google/googletest/tree/master/googletest\n* Clone the repository\n    * `git clone https://github.com/cpp-testing/GUnit.git`\n* Add `GUnit/include` directory to your include path\n    * `-I GUnit/include`\n* Write some tests...\n* Compile and Run!\n\n### Quick Start (CMake)\n* Add to your CMakeLists.txt the following lines:\n   ```\n   include(FetchContent)\n   FetchContent_Declare(\n   gunit\n   GIT_REPOSITORY https://github.com/cpp-testing/GUnit.git\n   GIT_TAG        master\n   )\n   FETCHCONTENT_MAKEAVAILABLE(gunit)\n   ```\n* Write some tests...\n* Compile and Run\n---\n\u003e When using the installation method as described [here](#quick-start-cmake) you may fully skip this step.\n* [gherkin](https://github.com/cucumber/cucumber/wiki/Gherkin) support using CMake\n    * `gherkin-cpp` using add_subdirectory\n        ```sh\n          # using add_subdirectory from the top-level CMakeLists.txt file:\n          add_subdirectory(gunit)\n        ```\n        ```sh\n          # src/CMakeLists.txt contains either this:\n          add_executable(myprogram)\n          target_link_libraries(myprogram gunit)\n          ...\n          # or you could have also been more explicit, then you would write this:\n          target_link_libraries(myprogram gtest gtest_main)\n        ```\n    * `gherkin-cpp` using a ExternalProject_Add(gunit ...)\n        Note: This sections needs updates, when writing the gherkin-cpp CMake integration I used add_subdirectory:\n        * Add include paths\n            * `-I GUnit_install_dir/include`\n        * Link with `libgherkin-cpp.{a, so}` Note: I wasn't able to nest the fmem/gherkin into libghekin-cpp, so two more libs to add: fmem/gherkin!\n            * `-L gherkin-cpp`\n            * `-L fmem`\n            * `-L gherkin`\n        * Write some feature tests...\n        * Compile and Run!\n---\n\n* To run GUnit tests/benchmarks\n  ```sh\n  $mkdir build \u0026\u0026 cd build \u0026\u0026 cmake ..\n  $make \u0026\u0026 ctest\n  ```\n\n### Requirements\n  * [C++14](https://ubershmekel.github.io/cppdrafts/c++14-cd.html)\n  * `GTest/GTest-Lite/GMock/GMake`\n    * [libs/googletest](https://github.com/google/googletest) - compatible with all versions\n  * `GSteps`\n    * [libs/json](https://github.com/nlohmann/json)\n    * [libs/gherkin-cpp](https://github.com/c-libs/gherkin-cpp)\n      * [libs/gherkin-cpp/libs/fmem](https://github.com/c-libs/fmem.git)\n      * [libs/gherkin-cpp/libs/gherkin-c](https://github.com/c-libs/gherkin-c.git)\n### Tested compilers\n  * [Linux - GCC-5+](https://travis-ci.org/cpp-testing/GUnit)\n  * [Linux - Clang-3.7+](https://travis-ci.org/cpp-testing/GUnit)\n  * [Mac OSx - Xcode-7.3+](https://travis-ci.org/cpp-testing/GUnit)\n\n### User Guide\n  * **[GUnit.GTest](docs/GTest.md)**\n  * **[GUnit.GTest-Lite](docs/GTest-Lite.md)**\n  * **[GUnit.GMock](docs/GMock.md)**\n  * **[GUnit.GMake](docs/GMake.md)**\n  * **[GUnit.GSteps](docs/GSteps.md)**\n  * **[GUnit.GAssert](docs/GAssert.md)**\n\n### [FAQ](docs/FAQ.md)\n  * [C++ Now 2017: Towards Painless Testing](https://www.youtube.com/watch?v=NVrZjT5lW5o)\n\n### Acknowledgements\n* Thanks to [Google Open Source](https://opensource.google.com/) for [Google.Test/Google.Mock](https://github.com/google/googletest) libraries\n* Thanks to Eran Pe'er for [FakeIt](https://github.com/eranpeer/FakeIt) library\n* Thanks to Peter Bindels for [HippoMocks](https://github.com/dascandy/hippomocks) library\n* Thanks to Niels Lohmann for [json](https://github.com/nlohmann/json) library\n* Thanks to Aslak Hellesøy for [gherkin-c](https://github.com/cucumber/gherkin-c) library\n* Thanks to [Cucumber Open Source](https://cucumber.io/) for [cucumber-cpp](https://github.com/cucumber/cucumber-cpp) library\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpp-testing%2Fgunit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcpp-testing%2Fgunit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcpp-testing%2Fgunit/lists"}