Basic test:
#include <gtest/gtest.h>
TEST (BasicTest, OneEqOne)
{
EXPECT_EQ( 1, 1);
}
int main( int argc, char *argv[])
{
::testing::InitGoogleTest( &argc, argv);
return RUN_ALL_TESTS();
}
$ g++ -I../../googletest/googletest/include/ basic1.cpp ../../lib/libgmock.a -pthread -o basic1
$ ./basic1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from BasicTest
[ RUN ] BasicTest.OneEqOne
[ OK ] BasicTest.OneEqOne (0 ms)
[----------] 1 test from BasicTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
#ifndef MINIMATH_H
#define MINIMATH_H
class MiniMath
{
public:
int factorial(int n);
};
#endif
#include "minimath.h"
int MiniMath::factorial(int n)
{
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
#include <gtest/gtest.h>
#include "minimath.h"
TEST(FactorialTest, withPositiveNumbers)
{
MiniMath mm;
ASSERT_EQ(120, mm.factorial(5));
ASSERT_EQ( 6, mm.factorial(3));
}
TEST(FactorialTest, withZero)
{
MiniMath mm;
ASSERT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
RUN_ALL_TESTS must be called only once in the code because
multiple calls to it conflict with some of the advanced
features of the framework and, therefore, are not supported.
Note that RUN_ALL_TESTS automatically detects and runs all
the tests defined using the TEST macro.
$ g++ -I../../googletest/googletest/include/ minimath.cpp test.cpp ../../lib/libgmock.a -pthread -o test
gsd@cope:~/work/zolix/tanfolyam/Nng/gmock/mytests/2$ ./test
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
[ OK ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 2 tests from FactorialTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 2 tests.
ASSERT API
==========
Assert API are FATAL checks
ASSERT_TRUE
ASSERT_FALSE
ASSERT_EQ
ASSERT_NE
ASSERT_LT
ASSERT_GT
ASSERT_GE
ASSERT_STREQ
ASSERT_STRNE
ASSERT_STRCASEEQ
ASSERT_STRCASENE
ASSERT_TRUE
ASSERT_FALSE
EXPECT API
==========
Expect macros continue the execution even if the expectaton fails.
EXPECT_TRUE
EXPECT_FALSE
EXPECT_EQ
EXPECT_NE
EXPECT_LT
EXPECT_GT
EXPECT_GE
EXPECT_STREQ
EXPECT_STRNE
EXPECT_STRCASEEQ
EXPECT_STRCASENE
EXPECT_TRUE
EXPECT_FALSE
EXPLICIT
========
SUCCEED() not used (perhaps reserved forgenerate messages later)
FAIL() fatal failure
ADD_FAILURE() nonfatal failure
#include "minimath.h"
int MiniMath::factorial(int n)
{
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res==120 ? 1 : res;
}
$ g++ -I../../googletest/googletest/include/ minimath-bad.cpp test1.cpp ../../lib/libgmock.a -pthread -o test1
$ ./test1
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
test1.cpp:7: Failure
Value of: mm.factorial(5)
Actual: 1
Expected: 120
[ FAILED ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 2 tests from FactorialTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] FactorialTest.withPositiveNumbers
1 FAILED TEST
Replace ASSERT_EQ with EXPECT_EQ
#include <gtest/gtest.h>
#include "minimath.h"
TEST(FactorialTest, withPositiveNumbers)
{
MiniMath mm;
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ( 6, mm.factorial(3));
}
TEST(FactorialTest, withZero)
{
MiniMath mm;
EXPECT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Command line arguments
======================
Generating XML output
---------------------
# with ASSERT_
$ test1 --gtest_output="xml:test1-report.xml"
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="2" failures="0" disabled="0" errors="0" timestamp="2016-01-09T19:21:32" time="0" name="AllTests">
<testsuite name="FactorialTest" tests="2" failures="0" disabled="0" errors="0" time="0">
<testcase name="withPositiveNumbers" status="run" time="0" classname="FactorialTest" />
<testcase name="withZero" status="run" time="0" classname="FactorialTest" />
</testsuite>
</testsuites>
Repeating tests
---------------
$ ./test1 --gtest_repeat=3
Repeating all tests (iteration 1) . . .
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
test1.cpp:7: Failure
Value of: mm.factorial(5)
Actual: 1
Expected: 120
[ FAILED ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 2 tests from FactorialTest (1 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] FactorialTest.withPositiveNumbers
1 FAILED TEST
Repeating all tests (iteration 2) . . .
...
Filtering
---------
./test1 --gtest_filter=FactorialTest.withZero
Note: Google Test filter = FactorialTest.withZero
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FactorialTest
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 1 test from FactorialTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
$ ./test1 --gtest_filter=FactorialTest.*Zero
./test1 --gtest_filter=FactorialTest.*Zero
Note: Google Test filter = FactorialTest.*Zero
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FactorialTest
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 1 test from FactorialTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
$ ./test1 --gtest_filter=FactorialTest.*-FactorialTest.withPositiveNumbers
Note: Google Test filter = FactorialTest.*-FactorialTest.withPositiveNumbers
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from FactorialTest
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 1 test from FactorialTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
Floating point numbers
======================
#ifndef MINIMATH_H
#define MINIMATH_H
class MiniMath
{
public:
int factorial(int n);
double div(double x, double y);
};
#endif
include <cmath>
#include "minimath.h"
int MiniMath::factorial(int n)
{
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
double MiniMath::div( double x, double y)
{
return x/y;
}
#include <gtest/gtest.h>
#include "minimath.h"
TEST(DivisionTest, SimpleTest)
{
MiniMath mm;
EXPECT_EQ(1.66, mm.div(5,3));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from DivisionTest
[ RUN ] DivisionTest.SimpleTest
test1.cpp:7: Failure
Value of: mm.div(5,3)
Actual: 1.66667
Expected: 1.66
[ FAILED ] DivisionTest.SimpleTest (0 ms)
[----------] 1 test from DivisionTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] DivisionTest.SimpleTest
1 FAILED TEST
#include <gtest/gtest.h>
#include "minimath.h"
TEST(DivisionTest, SimpleTest)
{
MiniMath mm;
EXPECT_EQ(1.66667, mm.div(5,3));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from DivisionTest
[ RUN ] DivisionTest.SimpleTest
test1.cpp:7: Failure
Value of: mm.div(5,3)
Actual: 1.66667
Expected: 1.66667
[ FAILED ] DivisionTest.SimpleTest (0 ms)
[----------] 1 test from DivisionTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 0 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] DivisionTest.SimpleTest
1 FAILED TEST
gtest has special macros for floating point
-------------------------------------------
EXPECT_FLOAT_EQ
EXPECT_DOUBLE_EQ
EXPECT_NEAR
ASSERT_FLOAT_EQ
ASSERT_DOUBLE_EQ
ASSERT_NEAR
#include <gtest/gtest.h>
#include "minimath.h"
TEST(DivisionTest, SimpleTest)
{
MiniMath mm;
EXPECT_EQ(1.66667, mm.div(5,3));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test2
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from DivisionTest
[ RUN ] DivisionTest.FloatTest
test2.cpp:7: Failure
Value of: mm.div(5,3)
Actual: 1.6666666
Expected: 1.66667
[ FAILED ] DivisionTest.FloatTest (1 ms)
[ RUN ] DivisionTest.DoubleTest
test2.cpp:13: Failure
Value of: mm.div(5,3)
Actual: 1.6666666666666667
Expected: 1.66667
Which is: 1.6666700000000001
[ FAILED ] DivisionTest.DoubleTest (0 ms)
[ RUN ] DivisionTest.NearTest
[ OK ] DivisionTest.NearTest (0 ms)
[----------] 3 tests from DivisionTest (1 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
[ FAILED ] 2 tests, listed below:
[ FAILED ] DivisionTest.FloatTest
[ FAILED ] DivisionTest.DoubleTest
2 FAILED TESTS
#include <gtest/gtest.h>
#include "minimath.h"
TEST(DivisionTest, Float6digit)
{
EXPECT_FLOAT_EQ(1.6666661, 1.6666669);
}
TEST(DivisionTest, Float7digit)
{
EXPECT_FLOAT_EQ(1.66666661, 1.66666669);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test3
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from DivisionTest
[ RUN ] DivisionTest.Float6digit
test3.cpp:6: Failure
Value of: 1.6666669
Expected: 1.6666661
Which is: 1.6666662
[ FAILED ] DivisionTest.Float6digit (0 ms)
[ RUN ] DivisionTest.Float7digit
[ OK ] DivisionTest.Float7digit (0 ms)
[----------] 2 tests from DivisionTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] DivisionTest.Float6digit
1 FAILED TEST
#include <gtest/gtest.h>
#include "minimath.h"
TEST(DivisionTest, Float6digit)
{
EXPECT_NEAR(1.6666661, 1.6666669, 1e-7);
}
TEST(DivisionTest, Float7digit)
{
EXPECT_NEAR(1.66666661, 1.66666669, 1e-7);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test4
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from DivisionTest
[ RUN ] DivisionTest.Float6digit
test4.cpp:6: Failure
The difference between 1.6666661 and 1.6666669 is 8.0000000002300453e-07,
which exceeds 1e-7, where
1.6666661 evaluates to 1.6666661,
1.6666669 evaluates to 1.6666669000000001, and
1e-7 evaluates to 9.9999999999999995e-08.
[ FAILED ] DivisionTest.Float6digit (0 ms)
[ RUN ] DivisionTest.Float7digit
[ OK ] DivisionTest.Float7digit (0 ms)
[----------] 2 tests from DivisionTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] DivisionTest.Float6digit
1 FAILED TEST
#include <gtest/gtest.h>
#include <iomanip>
#include <sstream>
TEST(StringTest, Expect_Eq)
{
double d = 5./3.;
std::ostringstream s;
s << std::setprecision(6) << d;
EXPECT_EQ("1.66667", s.str());
}
TEST(StringTest, Expect_StringEq)
{
double d = 5./3.;
std::ostringstream s;
s << std::setprecision(6) << d;
EXPECT_STREQ("1.66667", s.str().c_str());
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from StringTest
[ RUN ] StringTest.Expect_Eq
[ OK ] StringTest.Expect_Eq (0 ms)
[ RUN ] StringTest.Expect_StringEq
[ OK ] StringTest.Expect_StringEq (0 ms)
[----------] 2 tests from StringTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 2 tests.
Dead test
=========
#include <iostream>
#include <cstdlib>
#include "minimath.h"
int MiniMath::factorial(int n)
{
if ( n < 0 )
{
std::cerr << "Negative input" << std::endl;
std::exit(1);
}
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
double MiniMath::div( double x, double y)
{
return x/y;
}
ASSERT_DEATH(statement, expected_message)
ASSERT_EXIT(statement, predicate, expected_message)
#include <gtest/gtest.h>
#include "minimath.h"
TEST(FactorialTest, withPositiveNumbers)
{
MiniMath mm;
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ( 6, mm.factorial(3));
EXPECT_EQ( 1, mm.factorial(1));
}
TEST(FactorialTest, withNegative1)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial( 0),::testing::ExitedWithCode(1),"");
}
TEST(FactorialTest, withNegative2)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(-1),"");
}
TEST(FactorialTest, withNegative4)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(1),"Negative input");
}
TEST(FactorialTest, withNegative3)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(1),"Bad input");
}
TEST(FactorialTest, withZero)
{
MiniMath mm;
EXPECT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 6 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 6 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
[ OK ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withNegative1
test1.cpp:15: Failure
Death test: mm.factorial( 0)
Result: failed to die.
Error msg:
[ DEATH ]
[ FAILED ] FactorialTest.withNegative1 (0 ms)
[ RUN ] FactorialTest.withNegative2
test1.cpp:21: Failure
Death test: mm.factorial(-1)
Result: died but not with expected exit code:
Exited with exit status 1
Actual msg:
[ DEATH ] Negative input
[ DEATH ]
[ FAILED ] FactorialTest.withNegative2 (0 ms)
[ RUN ] FactorialTest.withNegative3
test1.cpp:27: Failure
Death test: mm.factorial(-1)
Result: died but not with expected error.
Expected: Bad input
Actual msg:
[ DEATH ] Negative input
[ DEATH ]
[ FAILED ] FactorialTest.withNegative3 (1 ms)
[ RUN ] FactorialTest.withNegative4
[ OK ] FactorialTest.withNegative4 (1 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 6 tests from FactorialTest (3 ms total)
[----------] Global test environment tear-down
[==========] 6 tests from 1 test case ran. (3 ms total)
[ PASSED ] 3 tests.
[ FAILED ] 3 tests, listed below:
[ FAILED ] FactorialTest.withNegative1
[ FAILED ] FactorialTest.withNegative2
[ FAILED ] FactorialTest.withNegative3
3 FAILED TESTS
But be care with the error message:
-----------------------------------
TEST(FactorialTest, withNegative3)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(1),"");
}
...
[ RUN ] FactorialTest.withNegative3
[ OK ] FactorialTest.withNegative3 (1 ms)
[ RUN ] FactorialTest.withNegative4
[ OK ] FactorialTest.withNegative4 (1 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 6 tests from FactorialTest (3 ms total)
[----------] Global test environment tear-down
[==========] 6 tests from 1 test case ran. (3 ms total)
[ PASSED ] 4 tests.
[ FAILED ] 2 tests, listed below:
[ FAILED ] FactorialTest.withNegative1
[ FAILED ] FactorialTest.withNegative2
2 FAILED TESTS
The ASSERT_DEATH checks only the death and the error message
------------------------------------------------------------
#include <gtest/gtest.h>
#include "minimath.h"
TEST(FactorialTest, withPositiveNumbers)
{
MiniMath mm;
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ( 6, mm.factorial(3));
EXPECT_EQ( 1, mm.factorial(1));
}
TEST(FactorialTest, withNegative1)
{
MiniMath mm;
ASSERT_DEATH( mm.factorial( 0),"");
}
TEST(FactorialTest, withNegative2)
{
MiniMath mm;
ASSERT_DEATH( mm.factorial(-1),"");
}
TEST(FactorialTest, withNegative3)
{
MiniMath mm;
ASSERT_DEATH( mm.factorial(-1),"");
}
TEST(FactorialTest, withNegative4)
{
MiniMath mm;
ASSERT_DEATH( mm.factorial(-1),"Negative input");
}
TEST(FactorialTest, withZero)
{
MiniMath mm;
EXPECT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test3
[==========] Running 6 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 6 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
[ OK ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withNegative1
test3.cpp:15: Failure
Death test: mm.factorial( 0)
Result: failed to die.
Error msg:
[ DEATH ]
[ FAILED ] FactorialTest.withNegative1 (0 ms)
[ RUN ] FactorialTest.withNegative2
[ OK ] FactorialTest.withNegative2 (1 ms)
[ RUN ] FactorialTest.withNegative3
[ OK ] FactorialTest.withNegative3 (1 ms)
[ RUN ] FactorialTest.withNegative4
[ OK ] FactorialTest.withNegative4 (1 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 6 tests from FactorialTest (3 ms total)
[----------] Global test environment tear-down
[==========] 6 tests from 1 test case ran. (3 ms total)
[ PASSED ] 5 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] FactorialTest.withNegative1
1 FAILED TEST
since gtest version 1.4.0:
ASSERT_DEATH_IF_SUPPORTED
EXPECT_DEATH_IF_SUPPORTED
Predicates:
-----------
::testing::ExitedWithCode(exit_code)
::testing::KilledBySignal(signal_number) (not available on Windows)
Predicate takes one int param and returns bool.
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include "minimath.h"
int MiniMath::factorial(int n)
{
if ( n < 0 )
{
std::cerr << "Negative input" << std::endl;
kill( getpid(), SIGUSR1);
}
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
double MiniMath::div( double x, double y)
{
return x/y;
}
#include <gtest/gtest.h>
#include <signal.h>
#include "minimath.h"
TEST(FactorialTest, withPositiveNumbers)
{
MiniMath mm;
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ( 6, mm.factorial(3));
EXPECT_EQ( 1, mm.factorial(1));
}
TEST(FactorialTest, withNegative1)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial( 0),::testing::ExitedWithCode(1),"");
}
TEST(FactorialTest, withNegative2)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),
::testing::KilledBySignal(SIGUSR1),
"Negative input");
}
TEST(FactorialTest, withZero)
{
MiniMath mm;
EXPECT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test4
[==========] Running 4 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 4 tests from FactorialTest
[ RUN ] FactorialTest.withPositiveNumbers
[ OK ] FactorialTest.withPositiveNumbers (0 ms)
[ RUN ] FactorialTest.withNegative1
test4.cpp:17: Failure
Death test: mm.factorial( 0)
Result: failed to die.
Error msg:
[ DEATH ]
[ FAILED ] FactorialTest.withNegative1 (1 ms)
[ RUN ] FactorialTest.withNegative2
[ OK ] FactorialTest.withNegative2 (0 ms)
[ RUN ] FactorialTest.withZero
[ OK ] FactorialTest.withZero (0 ms)
[----------] 4 tests from FactorialTest (1 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test case ran. (1 ms total)
[ PASSED ] 3 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] FactorialTest.withNegative1
ASSERT_THROW
ASSERT_ANY_THROW
ASSERT_NO_THROW
#include <iostream>
#include <cstdlib>
#include "minimath.h"
int MiniMath::factorial(int n)
{
if ( n < 0 )
{
std::cerr << "Negative input" << std::endl;
std::exit(1);
}
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
double MiniMath::div( double x, double y)
{
return x/y;
}
#include <gtest/gtest.h>
#include "minimath.h"
TEST(FactorialTest, notThrow)
{
MiniMath mm;
ASSERT_NO_THROW( mm.factorial(0) );
}
TEST(FactorialTest, throwError)
{
MiniMath mm;
ASSERT_THROW( mm.factorial(-1), MiniMath::Error );
}
TEST(FactorialTest, throwSomething)
{
MiniMath mm;
ASSERT_ANY_THROW( mm.factorial(-1) );
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
..._THROW macros takes a statement (not an expression) as first parameter
TEST(FactorialTest, notThrow)
{
ASSERT_NO_THROW({
MiniMath mm;
mm.factorial(0);
});
}
HOW IT WORKS?
=============
ASSERT_EXIT() starts a new process and execute the DEATH test there.
::testing::GTEST_FLAG(death_test_style) variable
is set by --gtest_death_test_style
--gtest_death_test_style=(fast|threadsafe)
USER DEFINED PREDICATES
=======================
Sometimes we have to check complex expressions. We can pass these to
EXPECT_TRUE(expr)
The problem is that this solution will not sho the details of what went wrong.
ASSERT_PRED1( pred, arg)
ASSERT_PRED2( pred, arg1, arg2)
EXPECT_PRED1( pred, arg)
EXPECT_PRED2( pred, arg1, arg2)
... up to parameter #5
#ifndef MINIMATH_H
#define MINIMATH_H
class MiniMath
{
public:
int factorial(int n);
int gcd(int a, int b);
static bool mutPrime(int a, int b);
};
#endif
#include "minimath.h"
int MiniMath::factorial(int n)
{
int res = 1;
for(int i=2; i<=n; ++i)
res *= i;
return res;
}
int MiniMath::gcd(int a, int b)
{
while( a != b )
{
if( a > b )
a -= b;
else
b -= a;
}
return a;
}
bool MiniMath::mutPrime(int a, int b)
{
MiniMath mm;
return 1 == mm.gcd( a, b);
}
#include <iostream>
#include <gtest/gtest.h>
#include "minimath.h"
TEST(MiniMath, gcd)
{
MiniMath mm;
EXPECT_EQ(1, mm.gcd(9,16) );
EXPECT_EQ(4, mm.gcd(12,8) );
EXPECT_EQ(5, mm.gcd(15,10) );
}
TEST(MiniMath, mutPrime)
{
EXPECT_TRUE(MiniMath::mutPrime(9,16) );
EXPECT_FALSE(MiniMath::mutPrime(12,8) );
EXPECT_TRUE(MiniMath::mutPrime(3*5,2*5) );
}
TEST(MiniMath, mutPrimePred)
{
EXPECT_PRED2(MiniMath::mutPrime, 9,16);
EXPECT_PRED2(MiniMath::mutPrime,12, 8);
EXPECT_PRED2(MiniMath::mutPrime,3*5,2*5);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from MiniMath
[ RUN ] MiniMath.gcd
[ OK ] MiniMath.gcd (0 ms)
[ RUN ] MiniMath.mutPrime
test1.cpp:18: Failure
Value of: MiniMath::mutPrime(3*5,2*5)
Actual: false
Expected: true
[ FAILED ] MiniMath.mutPrime (1 ms)
[ RUN ] MiniMath.mutPrimePred
test1.cpp:24: Failure
MiniMath::mutPrime(12, 8) evaluates to false, where
12 evaluates to 12
8 evaluates to 8
test1.cpp:25: Failure
MiniMath::mutPrime(3*5, 2*5) evaluates to false, where
3*5 evaluates to 15
2*5 evaluates to 10
[ FAILED ] MiniMath.mutPrimePred (0 ms)
[----------] 3 tests from MiniMath (1 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[ PASSED ] 1 test.
[ FAILED ] 2 tests, listed below:
[ FAILED ] MiniMath.mutPrime
[ FAILED ] MiniMath.mutPrimePred
2 FAILED TESTS
How to fix EXPECT_PRED2(MiniMath::mutPrime,12, 8) ?
EXPECT_PRED2( ! MiniMath::mutPrime,12, 8);
test1.cpp:24:28: warning: the address of ‘static bool
MiniMath::mutPrime(int, int)’ will always evaluate as ‘true’ [-Waddress]
EXPECT_PRED2(! MiniMath::mutPrime,12, 8);
^
EXPECT_PRED.. macros seem fine, but what if we had a method returning
a special type that gtest not prepared for in advance?
Predicates are better!
Assertion object
----------------
An AssertionResult object represents the result of an assertion
(whether it's a success or a failure, and an associated message).
AssertionResult can be created using these factory functions:
namespace testing {
AssertionResult AssertionSuccess();
AssertionResult AssertionFailure();
}
The operator<< is used to stream messages to the AssertionResult bject.
#include <iostream>
#include <gtest/gtest.h>
#include "minimath.h"
::testing::AssertionResult isMutPrime( int a, int b)
{
MiniMath mm;
if ( MiniMath::mutPrime(a,b) )
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << "gcd(" << a
<< "," << b << ") ="
<< mm.gcd(a,b) ;
}
TEST(MiniMath, gcd)
{
MiniMath mm;
EXPECT_EQ(1, mm.gcd(9,16) );
EXPECT_EQ(4, mm.gcd(12,8) );
EXPECT_EQ(5, mm.gcd(15,10) );
}
TEST(MiniMath, mutPrime)
{
EXPECT_TRUE(isMutPrime(9,16) );
EXPECT_FALSE(isMutPrime(12,8) );
EXPECT_TRUE(isMutPrime(3*5,2*5) );
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test2
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from MiniMath
[ RUN ] MiniMath.gcd
[ OK ] MiniMath.gcd (0 ms)
[ RUN ] MiniMath.mutPrime
test2.cpp:29: Failure
Value of: isMutPrime(3*5,2*5)
Actual: false (gcd(15,10) = 5)
Expected: true
[ FAILED ] MiniMath.mutPrime (0 ms)
[----------] 2 tests from MiniMath (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] MiniMath.mutPrime
1 FAILED TEST
Also, one can write:
EXPECT_TRUE( ! isMutPrime(12,8) );
instead of
EXPECT_FALSE(isMutPrime(12,8) );
EXPECT_PRED_FORMAT1 ... macros allow you further formatting
TYPE ASSERTIONS
---------------
::testing::StaticAssertTypeEq<T1, T2>()
falls back to std::static_assert( expr, msg);
WHERE PUT ASSERTIONS?
---------------------
Assertions can be put in any subroutine, but assertions that generate
a fatal failure ( FAIL_ and ASSERT_ ) can only be used in void-returning
functions.
FIXTURES
========
We usually execute some initialization before executing unit tests.
Test fixtures are for helping this initialization task.
They are especially useful when multiple test cases share common resources.
- A fixture class should be inherited from ::testing::Test class.
- Its data members are accessible from the tests
- Instead of TEST macro we should use TEST_F with the fixture class name
as the mandatory first parameter of the macro
Fixtures have SetUp and TearDown virtual methods
- SetUp runs before each test cases
- TearDown runs after each test cases
These should be defined as public or protected.
#include <iostream>
#include <gtest/gtest.h>
#include "minimath.h"
class MiniMathTest : public ::testing::Test
{
protected:
MiniMath mm;
void SetUp() { std::cout << "Before test" << std::endl; }
void TearDown() { std::cout << "After test" << std::endl; }
};
TEST_F(MiniMathTest, withPositiveNumbers)
{
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ(6, mm.factorial(3));
}
TEST_F(MiniMathTest, withZero)
{
EXPECT_EQ(1, mm.factorial(0));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ ./test1
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from MiniMathTest
[ RUN ] MiniMathTest.withPositiveNumbers
Before test
After test
[ OK ] MiniMathTest.withPositiveNumbers (0 ms)
[ RUN ] MiniMathTest.withZero
Before test
After test
[ OK ] MiniMathTest.withZero (0 ms)
[----------] 2 tests from MiniMathTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (0 ms total)
[ PASSED ] 2 tests.
Will it survive exit(), throw, kill() events?
Add new test:
TEST_F(MiniMathTest, withNegative)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(1),"");
}
$ ./test2
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from MiniMathTest
[ RUN ] MiniMathTest.withPositiveNumbers
Before test
After test
[ OK ] MiniMathTest.withPositiveNumbers (0 ms)
[ RUN ] MiniMathTest.withZero
Before test
After test
[ OK ] MiniMathTest.withZero (0 ms)
[ RUN ] MiniMathTest.withNegative
Before test
After test
[ OK ] MiniMathTest.withNegative (1 ms)
[----------] 3 tests from MiniMathTest (1 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (1 ms total)
[ PASSED ] 3 tests.
We can add constructor and destructor to Fixture class.
Allocate resources can be done either in constructor or in SetUp(),
deallocation in either TearDown() or destructor.
But as usual: destructor must not throw exception!
Hint: put ASSERT_ macros to TearDown() instead of destructor, since
Google may throw exceptions from ASSERT_ macros in the future.
The same test fixture is not used across multiple tests. For every
unit test, the framework creates a new test fixture object.
#include <iostream>
#include <gtest/gtest.h>
#include "minimath.h"
class MiniMathTest : public ::testing::Test
{
public:
MiniMathTest() { std::cout << "Fixture constructor" << std::endl; }
~MiniMathTest() override { std::cout << "Fixture destructor" << std::endl;}
protected:
MiniMath mm;
void SetUp() override { std::cout << "Before test" << std::endl; }
void TearDown() override { std::cout << "After test" << std::endl; }
};
TEST_F(MiniMathTest, withPositiveNumbers)
{
EXPECT_EQ(120, mm.factorial(5));
EXPECT_EQ(6, mm.factorial(3));
}
TEST_F(MiniMathTest, withZero)
{
EXPECT_EQ(1, mm.factorial(0));
}
TEST_F(MiniMathTest, withNegative)
{
MiniMath mm;
ASSERT_EXIT( mm.factorial(-1),::testing::ExitedWithCode(1),"");
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Theoretically one can use static members, but this makes tests depending
on execution order of cases.
class MiniMathTest : public ::testing::Test
{
public:
MiniMathTest() { std::cout << "Fixture constructor" << std::endl; }
~MiniMathTest() override { std::cout << "Fixture destructor" << std::endl;}
static int cnt;
protected:
MiniMath mm;
void SetUp() override { ++cnt; }
void TearDown() override { std::cout << "cnt = " << cnt << std::endl; }
};
int MiniMathTest::cnt = 0;
$ ./test4
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from MiniMathTest
[ RUN ] MiniMathTest.withPositiveNumbers
Fixture constructor
cnt = 1
Fixture destructor
[ OK ] MiniMathTest.withPositiveNumbers (0 ms)
[ RUN ] MiniMathTest.withZero
Fixture constructor
cnt = 2
Fixture destructor
[ OK ] MiniMathTest.withZero (0 ms)
[ RUN ] MiniMathTest.withNegative
Fixture constructor
cnt = 3
Fixture destructor
[ OK ] MiniMathTest.withNegative (0 ms)
[----------] 3 tests from MiniMathTest (1 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (2 ms total)
[ PASSED ] 3 tests.