Search code examples
c++unit-testingcatch-unit-test

Does C++ Catch has something like NUnit's TestCase with multiple parameter/input options


NUnit has the following feature where you can specify different values for a test with a TestCase attribute. Does Catch has something similar?

[TestCase(12,3,4)]
[TestCase(12,2,6)]
[TestCase(12,4,3)]
public void DivideTest(int n, int d, int q)
{
  Assert.AreEqual( q, n / d );
}

I need to run the same unit test with different data values but each be different unit tests. I can copy/paste TEST_CASE/SECTION and change values but is there a clean way to do it like NUnit does.

I'm finding it really hard to even figure out what to search for. Catch uses TEST_CASE for a unit test which is completely different than what NUnit calls TestCase.


Solution

  • I could not quite find the equivalent of what you are looking for, but you are not required to copy and paste everything at all:

    #include "catch.hpp"
    
    // A test function which we are going to call in the test cases
    void testDivision(int n, int d, int q)
    {
      // we intend to run this multiple times and count the errors independently
      // so we use CHECK rather than REQUIRE
      CHECK( q == n / d );
    }
    
    TEST_CASE( "Divisions with sections", "[divide]" ) {
      // This is more cumbersome but it will work better
      // if we need to use REQUIRE in our test function
      SECTION("by three") {
        testDivision(12, 3, 4);
      }
      SECTION("by four") {
        testDivision(12, 4, 3);
      }
      SECTION("by two") {
        testDivision(12, 2, 7); // wrong!
      }
      SECTION("by six") {
        testDivision(12, 6, 2);
      }
    }
    
    TEST_CASE( "Division without Sections", "[divide]" ) {
      testDivision(12, 3, 4);
      testDivision(12, 4, 3);
      testDivision(12, 2, 7); // oops...
      testDivision(12, 6, 2); // this would not execute because
                              // of previous failing REQUIRE had we used that
    }
    
    TEST_CASE ("Division with loop", "[divide]")
    {
      struct {
        int n;
        int d;
        int q;
      } test_cases[] = {{12,3,4}, {12,4,3}, {12,2,7},
                        {12,6,2}};
      for(auto &test_case : test_cases) {
        testDivision(test_case.n, test_case.d, test_case.q);
      }
    }