C++ Unit Testing Libraries [closed]

点点圈 提交于 2019-11-28 09:05:24

There is no standard unit testing library for C++. There are many choices to choose from; cppunit being one of them.

At my company we use Google Test along with its partner Google Mock for unit testing and object mocking. I find them both combined easier to use and much more powerful than cppunit.

I've just pushed my own framework, CATCH, out there. It's still under development but I believe it already surpasses most other frameworks. Different people have different criteria but I've tried to cover most ground without too many trade-offs. Take a look at my linked blog entry for a taster. My top five features are:

  • Header only
  • Auto registration of function and method based tests
  • Decomposes standard C++ expressions into LHS and RHS (so you don't need a whole family of assert macros).
  • Support for nested sections within a function based fixture
  • Name tests using natural language - function/ method names are generated

It also has Objective-C bindings.

As an example, here's how you'd write the equivalent of the gtest example that @dmeister cited:

TEST_CASE( "Factorial/Handles zero input", "Tests factorial of 0.") 
{
  REQUIRE( Factorial(0) == 1 );
}

TEST_CASE( "Factorial/Handles positive input", "Tests factorial of positive numbers.") 
{
  REQUIRE( Factorial(1) == 1 );
  REQUIRE( Factorial(2) == 2 );
  REQUIRE( Factorial(3) == 6 );
  REQUIRE( Factorial(8) == 40320 );
}

If a test failed you'd still get the LHS and RHS values logged independentaly.

dmeister

Google Test Framework is an alternative.

Here is a simple example from the documentation:

// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
  EXPECT_EQ(1, Factorial(0));
}

// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
  EXPECT_EQ(1, Factorial(1));
  EXPECT_EQ(2, Factorial(2));
  EXPECT_EQ(6, Factorial(3));
  EXPECT_EQ(40320, Factorial(8));
}

It also plays nicely with gmock, Google's mock framework for C++.

CppUnit probably is the first unit test framework for C++. It's a direct port of Junit, the famous Java framework. This makes the transition from Junit easier, but at the cost of a somewhat heavy framework, that does not take advantage of C++ capability such as RAII. That's the reason why lightweight versions such as CppUnitLite, NanoCppUnit have been created. CppUnit2 was supposed to improve this, among other improvements.

Tut used to be very light, just one header, but the latest versions introduced a library.

As far as a "standard" framework is concerned, there is none, and C++1X does not define one.

I created a testing suite called saru ( http://github.com/mikeando/saru ) for my own code dev. Its a BSD licensed code. I developed it as I didn't like several of the features of other testing suites. Its not widely used, but I've used it on several commercial projects spread across two companies.

  1. I don't like all my tests getting compiled into one binary. My reasons for this are if the compile fails all tests fail, if one test does undefined behaviour the program output is undefined.
  2. I want control over what tests run. I want to be able to group tests and run subsets.
  3. I want compilation failure of a test to be reported as a test failure, and not halt all my tests running.
  4. I want to be able to run tests from multiple different languages
  5. I want a system flexible enough that I can run specific tests under valgrind (not yet in saru :( )

So saru addresses most of these features. Its focus is on being able to run a suite of tests written in different languages. With minimal test sizes. Here's the smallest (failing) C++ test

//SARU : dummy dummy
int main() { return (1==2)?0:1; }

All saru really cares about is the return value of the binary that it compiles. It then parses the output to determine what tests failed and so on. It has headers to make working with C++ a little nicer than the above trivial example :

//SARU : dummy dummy
#include "MyStruct.h"
#include "saru_cxx.h"

class Fixture
{
  MyStruct s_;
  Fixture() : s_() {}
  void test_A_is_B()
  {
     SARU_ASSERT_EQUAL( s_.A(), s_.B() );
  }

  void test_C_is_7()
  {
     SARU_ASSERT_EQUAL( 7, s_.C() );
  }
};

int main()
{
   saru::TestLogger logger;
   SARU_TEST( Fixture:: test_A_is_B, logger );
   SARU_TEST( Fixture:: test_C_is_7, logger );
   logger.printSummary();
   return logger.allOK()?0:1;
}

Or if you don't like the way its C++ headers work it should be able to integrate with other unittesting libraries with minimal difficulty.

But it will also run tests that are written in PHP & python. So you can set up full functional tests with saru. Or you can run something like lint over your code as part of the test suite.

Here's a minimal C++ unit testing library: https://github.com/vahidk/minimal-cpp-test

It has very similar syntax to Google test library but it's a header only library and therefore easier to port across platforms.

Here's a minimal unit test:

#define DEFINE_TEST_MAIN    
#include "test.h"
TEST(GroupName, TestName) {
  EXPECT_EQ(1 + 2, 3);
}

And a minimal fixture:

class ClassName : public cyrus:Test {
public:
  void Setup() override { 
    x = 5;
  }
  int x;
}

Test_F(ClassName, Test1) {
  EXPECT_EQ(x, 5);
}

Hope this helps.

Here is a single header file only include solution for C++ unit testing: https://gitlab.com/cppocl/unit_test_framework

Simple example of using it here, but it also has fixtures (setup and teardown), fail test on memory leak, fail test on performance (I've not seen this feature anywhere else).

#include "test/Test.hpp"

TEST(MyTest)
{
    int a = 1;
    int b = 2;
    CHECK_EQUAL(a + b, 3);
}

Here's a list of unit testing libraries.

http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B

However, as far as I know, cppunit is the most popular.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!