Below is a sample Google Test application. It uses simple testing functions. Sets of tests which require common preparation and cleanup operations around each test should use the Google Test fixture approach (see an example of that).

// GoogleTestSample.cc
// ===================
//
// A sample Google Test unit test application.



// Include the google test header file.
// The CASA cmake system will download a copy of the needed 
// header files, etc., and put them into the appropriate
// include and library paths when you use the casa_add_google_test
// cmake macro to declare your test in the module-level (i.e., the
// directory right below "code") CMakeLists.txt file.
//
// casa_add_google_test (MODULES msvis SOURCES MSVis/test/GoogleTestSample.cc) 

#include 

#include 
#include 
#include 

using std::domain_error;
using casa::String;

int
main (int nArgs, char ** args)
{
    // Initialize the google test framework.  This potentially takes
    // some command line arguments.  The method InitGoogleTest will
    // remove any options and arguments that are recognized by it,
    // (hence the "&" in front of nArgs) so it is permissible to pass
    // your own arguments as well.

    ::testing::InitGoogleTest (& nArgs, args);

    // Parse out your own arguments here.

    // Now run all the defined Google tests.

    return RUN_ALL_TESTS ();
}

// Here's a simple function that we're trying to test.  Normally this
// would be defined in another file, but we'll define it here for
// ease of understaning.

#define FailAllTests

double xToY (double x, int y)
{
#if defined (FailAllTests)
    return -123.456;
#else    

    if (x == 0){

	if (y == 0){
	    throw domain_error ("Zero to the zero is undefined.");
	} else if (y < 0) {
	    throw domain_error ("Zero to a negative power is infinite.");
	} else {
	    return 0;
	}
    }

    if (y == 0){
	return 1;
    }

    double result = x;
    bool negativeExponent = false;
    if (y < 0){
	y = -y;
	negativeExponent = true;
    }
    

    for (int i = 1; i < y; i++){
	result *= x;
    }

    if (negativeExponent){
	return 1.0 / result;
    } else {
	return result;
    }

#endif
}

// The TEST macro creates a simple test function which is a void returning
// C++ function.  The macro takes two arguments: testCaseName and testName.
// The purpose of the testCaseName is to group logically-related tests; the
// scope of the testCase is up to you.  
//
// Convention requires that neither the test case name nor the test name
// contain the underscore character.  This is to allow the fraemwork to
// easily parse generated names (i.e., they'll generate a name starting
// from the original name as a stem and add a suffix set off by an
// underscore).  So, use camel-case in the names.

TEST (xToYTest, ZeroToTheZero){

    bool caughtException = false;

    try {
	xToY (0, 0);
    } catch (domain_error &){
	caughtException = true;
    }

    // Here the ASSERT_xxx macro is used.  This will exit the test
    // (but not the test case) if the assertion fails.  You can
    // stream infomation into the assertion to provide more details
    // on the meaning of the test failure.  

    ASSERT_TRUE (caughtException) << "Failed to trap 0 ** 0."; 
}

TEST (xToYTest, ZeroReciprocal) {

    // This similar test can be written more compactly using a
    // Google Test macro.  This macro will fail if it does not
    // receive an exception of type domain_exception (or one
    // derived from it, too).

    EXPECT_THROW (xToY (0, -1), domain_error);

       // The above will print out the what is shown on the macro
       // line so if that is sufficient then there is no need to
       // stream in a message.

    for (int i = 1; i < 10; i++){
        EXPECT_THROW (xToY (0, -i), domain_error) <<
	    "Failed to trap 0 ** -1."; 
    }
}


TEST (xToYTest, NormalChecks){

    // Here we're using EXPECT_xxx rather than ASSERT_xxx.
    // The difference is that the EXPECT form does not exit
    // the test when it traps an error although the result
    // of the test will be "fail" if any of the EXPECT macros
    // detect an error.  Use the ASSERT form if a detected error
    // indicates that further testing is either useless or if
    // that continuing would actually cause a runtime error later
    // on.

    EXPECT_EQ (1, xToY (3, 0));
    EXPECT_EQ (1, xToY (-3, 0));

    EXPECT_EQ (1, xToY (1, 1));
    EXPECT_EQ (1, xToY (1, 10));

    EXPECT_EQ (16, xToY (2, 4));
    EXPECT_EQ (1024, xToY (2, 10));
    EXPECT_EQ (1000000, xToY (10, 6));

    // The macros containing "float" test that the quantities 
    // compared are equal to within a very tiny amount (based on
    // the precision of the floating point number).  

    EXPECT_FLOAT_EQ (0.5, xToY (2, -1));
    EXPECT_FLOAT_EQ (0.25, xToY (2, -2));

    // If the floating point calcution is somewhat involved then
    // the result may not be with the precision expected by the 
    // EXPECT_FLOAT_EQ macro.  For those cases you can specify
    // how close is close-enough using the third arugment.  The
    // macro compares the absolute value of the different between
    // the first argument and considers it "near enough" if it's
    // less than the provided accuracy.

    EXPECT_NEAR (0.333333, xToY (3, -1), .0001);

    for (int i = 1; i < 3; i++){

	double x = 3 * i;

	for (int j = -2; j <= 2; j++){
	    
	    double expected = pow (x, j);

	    // Here the macro can't print out the actual values of the
            // arguments so streaming in a more informative message is
            // of value.

	    EXPECT_NEAR (expected, xToY (x, j), .00001) <<
		String::format ("Value of xToY (%f, %d) out of range", x, j);

	}
    }
}

// Here is the output from running the test application defined above with
// FailAllTest undefined.

//[==========] Running 3 tests from 1 test case.
//[----------] Global test environment set-up.
//[----------] 3 tests from xToYTest
//[ RUN      ] xToYTest.ZeroToTheZero
//[       OK ] xToYTest.ZeroToTheZero (0 ms)
//[ RUN      ] xToYTest.ZeroReciprocal
//[       OK ] xToYTest.ZeroReciprocal (0 ms)
//[ RUN      ] xToYTest.NormalChecks
//[       OK ] xToYTest.NormalChecks (0 ms)
//[----------] 3 tests from xToYTest (0 ms total)
//
//[----------] Global test environment tear-down
//[==========] 3 tests from 1 test case ran. (0 ms total)
//[  PASSED  ] 3 tests.


// Output after defining FailAllTests and running the application


// ./GoogleTestSample
// [==========] Running 3 tests from 1 test case.
// [----------] Global test environment set-up.
// [----------] 3 tests from xToYTest
// [ RUN      ] xToYTest.ZeroToTheZero
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:109: Failure
// Value of: caughtException
//   Actual: false
// Expected: true
// Failed to trap 0 ** 0.
// [  FAILED  ] xToYTest.ZeroToTheZero (0 ms)
// [ RUN      ] xToYTest.ZeroReciprocal
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:119: Failure
// Expected: xToY (0, -1) throws an exception of type domain_error.
//   Actual: it throws nothing.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:126: Failure
// Expected: xToY (0, -i) throws an exception of type domain_error.
//   Actual: it throws nothing.
// Failed to trap 0 ** -1.
// [  FAILED  ] xToYTest.ZeroReciprocal (0 ms)
// [ RUN      ] xToYTest.NormalChecks
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:143: Failure
// Value of: xToY (3, 0)
//   Actual: -123.456
// Expected: 1
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:144: Failure
// Value of: xToY (-3, 0)
//   Actual: -123.456
// Expected: 1
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:146: Failure
// Value of: xToY (1, 1)
//   Actual: -123.456
// Expected: 1
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:147: Failure
// Value of: xToY (1, 10)
//   Actual: -123.456
// Expected: 1
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:149: Failure
// Value of: xToY (2, 4)
//   Actual: -123.456
// Expected: 16
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:150: Failure
// Value of: xToY (2, 10)
//   Actual: -123.456
// Expected: 1024
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:151: Failure
// Value of: xToY (10, 6)
//   Actual: -123.456
// Expected: 1000000
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:157: Failure
// Value of: xToY (2, -1)
//   Actual: -123.456
// Expected: 0.5
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:158: Failure
// Value of: xToY (2, -2)
//   Actual: -123.456
// Expected: 0.25
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:168: Failure
// The difference between 0.333333 and xToY (3, -1) is 123.789333, which exceeds .0001, where
// 0.333333 evaluates to 0.33333299999999999,
// xToY (3, -1) evaluates to -123.456, and
// .0001 evaluates to 0.0001.
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:182: Failure
// The difference between expected and xToY (x, j) is 123.56711111111112, which exceeds .00001, where
// expected evaluates to 0.1111111111111111,
// xToY (x, j) evaluates to -123.456, and
// .00001 evaluates to 1.0000000000000001e-05.
// Value of xToY (3.000000, -2) out of range
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:182: Failure
// The difference between expected and xToY (x, j) is 123.78933333333333, which exceeds .00001, where
// expected evaluates to 0.33333333333333331,
// xToY (x, j) evaluates to -123.456, and
// .00001 evaluates to 1.0000000000000001e-05.
// Value of xToY (3.000000, -1) out of range

// ... SNIP ...

// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:182: Failure
// The difference between expected and xToY (x, j) is 124.456, which exceeds .00001, where
// expected evaluates to 1,
// xToY (x, j) evaluates to -123.456, and
// .00001 evaluates to 1.0000000000000001e-05.
// Value of xToY (6.000000, 0) out of range
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:182: Failure
// The difference between expected and xToY (x, j) is 129.45600000000002, which exceeds .00001, where
// expected evaluates to 6,
// xToY (x, j) evaluates to -123.456, and
// .00001 evaluates to 1.0000000000000001e-05.
// Value of xToY (6.000000, 1) out of range
// /home/orion/casa/trunk/code/msvis/MSVis/test/GoogleTestSample.cc:182: Failure
// The difference between expected and xToY (x, j) is 159.45600000000002, which exceeds .00001, where
// expected evaluates to 36,
// xToY (x, j) evaluates to -123.456, and
// .00001 evaluates to 1.0000000000000001e-05.
// Value of xToY (6.000000, 2) out of range
// [  FAILED  ] xToYTest.NormalChecks (1 ms)
// [----------] 3 tests from xToYTest (1 ms total)

// [----------] Global test environment tear-down
// [==========] 3 tests from 1 test case ran. (1 ms total)
// [  PASSED  ] 0 tests.
// [  FAILED  ] 3 tests, listed below:
// [  FAILED  ] xToYTest.ZeroToTheZero
// [  FAILED  ] xToYTest.ZeroReciprocal
// [  FAILED  ] xToYTest.NormalChecks

//  3 FAILED TESTS


-- JimJacobs - 2016-02-24
Topic revision: r1 - 2016-02-24, JimJacobs
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding NRAO Public Wiki? Send feedback