But first of all let's have a look at some code!
In your production code:
int Factorial(int n); // Returns the factorial of n
In your test code:
// 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)); }
lightweight, widely used, debug support
under active development
https://code.google.com/p/googletest/source/list
documentation is quite good
https://code.google.com/p/googletest/wiki/Primer
extensive usage of preprocessor macros
not available for Objectiv-C and iOS
..anything else?
Boost Test
http://www.boost.org/doc/libs/1_55_0/libs/test/doc/html
CppUnit
http://cppunit.sourceforge.net/doc/lastest/cppunit_cookbook.html
a whole jungle of small developments and domain-specific libraries
http://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle
Your main.cpp:
#include "this/package/test/foo_TEST.h" #include "that/package/test/bar_TEST.h" #include "gtest/gtest.h" int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
Single test skeleton:
TEST(test_case_name, test_name) { ... test body ... }
Non-Fatal Assertions EXPECT_TRUE(condition); EXPECT_FALSE(condition); EXPECT_EQ(expected, actual); EXPECT_NE(expected, actual); EXPECT_LT(val1, val2); EXPECT_LE(val1, val2); EXPECT_GT(val1, val2); EXPECT_GE(val1, val2); |
Fatal Assertions ASSERT_TRUE(condition); ASSERT_FALSE(condition); ASSERT_EQ(expected, actual); ASSERT_NE(expected, actual); ASSERT_LT(val1, val2); ASSERT_LE(val1, val2); ASSERT_GT(val1, val2); ASSERT_GE(val1, val2); |
class TestFixtureClass : public ::testing::Test { protected: void SetUp() override { // called before each test is run } void TearDown() override { // called after each test is run } // declare members your tests want to use private: // declare internal members }; TEST_F(TestFixtureClass, TestName) { // you can access protected members // from TestFixtureClass here }
Improve error messages:
ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length"; for (int i = 0; i < x.size(); i++) { EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i; }
Function under Test:
int fib(int n) { return (n < 2) ? n : (fib(n - 1) + fib(n - 2)); }
Helper function:
bool isEven(int n) { return (n % 2) == 0; }
Test code:
TEST(Fibonacci, eachThirdIsEven) { EXPECT_TRUE(isEven(fib(0))); EXPECT_TRUE(isEven(fib(3))); EXPECT_TRUE(isEven(fib(4))); //< this fails EXPECT_TRUE(isEven(fib(6))); }
Helper macro:
#define M_CALL_SCOPE_TRACED(statement) { \ SCOPED_TRACE("in " #statement); statement; }
Helper function:
void isEven(int n) { EXPECT_EQ(0, n % 2); }
Modified test code:
TEST(Fibonacci, eachThirdIsEven) { M_CALL_SCOPE_TRACED(isEven(fib(0))); M_CALL_SCOPE_TRACED(isEven(fib(3))); M_CALL_SCOPE_TRACED(isEven(fib(4))); M_CALL_SCOPE_TRACED(isEven(fib(6))); }
Modified helper function:
::testing::AssertionResult isEven(int n) { if ((n % 2) == 0) return ::testing::AssertionSuccess(); else return ::testing::AssertionFailure() << n << " is odd"; }
Or: Why would we need automated tests,
when we have a reliable QA that finds bugs?
Because it's not the same thing at all!
Automated tests..
|
QA..
|
Production code must be written in a way that supports testing!
But there's good news: testable code is good code!
Google Test Advanced Guide
https://code.google.com/p/googletest/wiki/AdvancedGuide
Google Test Automation Conference
https://developers.google.com/google-test-automation-conference
Google Test Automation Conference 2013 Keynote
http://www.youtube.com/watch?v=nyOHJ4GR4iU
The Clean Code Talks - Unit Testsing
/* Thanks Timur! */
http://www.youtube.com/watch?v=wEhu57pih5w