Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How I do C++ Testing

How I do C++ Testing

My presentation about how I do C++ testing at Agile Aragón Testing Lab.

David Alfonso

March 09, 2013
Tweet

More Decks by David Alfonso

Other Decks in Programming

Transcript

  1. C++ Testing (how I do it) Testing Lab (Agile Aragón)

    March 9, 2013 Zaragoza - Spain David Alfonso @davidag
  2. Open Source Tools Continuous Integration (BuildBot) xUnit Framework (Google Test

    & Mock) Static Analysis (cppcheck) Dynamic Analysis (valgrind) VCS (CVS & Git)
  3. // SUT = Race TurtleMock turtle; EXPECT_CALL(turtle, Move(Gt(0))) .Times(AtLeast(1)) .WillOnce(Return(true))

    .WillRepeatedly(Return(false) ); Race race(turtle); race.runOneStep();
  4. // SUT = Race TurtleMock turtle; EXPECT_CALL(turtle, Move(Gt(0))) .Times(AtLeast(1)) .WillOnce(Return(true))

    .WillRepeatedly(Return(false) ); Race race(turtle); race.runOneStep(); EXPECT_CALL(mock_obj, method(matchers)) .Times(cardinality) .WillOnce(action) .WillRepeatedly(action);
  5. // Constructor DI class Data { public: bool empty() =

    0; int count() = 0; }; class ConcreteData : public Data {...}; class FakeData : public Data {...}; class Processor { public: Processor(Data* data); };
  6. // Setter DI class Data { public: bool empty() =

    0; int count() = 0; }; class ConcreteData : public Data {...}; class FakeData : public Data {...}; class Processor { public: Processor(); void SetData(Data* data) { d_ = d; }
  7. // Template DI template <typename T> class Processor { public:

    Processor(); private: T data_; }; // Production code Processor<ConcreteData> p; // Testing code Processor<FakeData> p;
  8. Legacy code characterization tests, not too strict about FIRST principles

    of unit testing, I prefer to have classes in test harnesses
  9. // Preprocessing // DbRecord.cpp #include "DbRecord.h" #include "DbDefs.h" ... Mysql::connect(host);

    ... Legacy Code #ifdef TESTING Mysql::connect() {} #else #include "Mysql.h" #endif
  10. // Preprocessing // DbRecord.cpp #include "Pre.h" #include "DbRecord.h" ... //

    DbRecordTests.cpp #include "Pre.h" #include "DbRecord.h" class MysqlStub { ... }; ... // Pre.h -> Different in tests // than in production code #define Mysql MysqlStub Legacy Code
  11. // Linking // BFake.cpp class B { ... }; //

    ATests.cpp #include "A.h" // It will include "B.h" TEST(...) { } // Compile BFake.cpp instead of B.cpp Legacy Code
  12. // Option 1: Review your design!!! // Option 2: Getters

    class A { public: const Obj& getObject() const { return obj; } private: Obj obj; };
  13. // Option 1: Review your design!!! // Option 2: Getters

    // Option 3: Add testing functions class A { public: ... bool DoSomeCheckUsingPrivateStuff(); private: ... };
  14. // Option 1: Review your design!!! // Option 2: Getters

    // Option 3: Add testing functions // Option 4: Make some friends :) class MyClass { private: // Google Test macro FRIEND_TEST(MyClassTest, MyMethod); };
  15. // Option 1: Review your design!!! // Option 2: Getters

    // Option 3: Add testing functions // Option 4: Make some friends :) // Option 5: Redefine private/protected // MyClassTests.cpp #define private public #include "MyClass.h" MyClass my_class; my_class.private_method();