1 + 1 becomes 11 what does our software promise?
TRANSCRIPT
1 + 1 becomes 11
what does
our software promise?
child’s addition
1 + 1 => 11
define the test
#include <fructose/test_base.h> // test framework
/** * define the tests. */struct math_test : public fructose::test_base< math_test >{ void one_plus_one_is_eleven( const std::string& test_name ) { fructose_assert( 11 == 1 + 1 ); }};
example 1 2 3 4
put test into a program
/** * run the tests. */int main( int argc, char* argv[] ){ math_test t;
t.add_test( "1 + 1 => 11", &math_test::one_plus_one_is_eleven );
return t.run( argc, argv );}
example 1 2 3 4
run the test
prompt>example1.exeError: 1 + 1 => 11 in example1.cpp(13): 11 == 1 + 1 failed.
Test driver failed: 1 error
example 1 2 3 4
implement child’s addition
/* Note: we cannot redefine int's behaviour for addition, like: * const int operator+( int const a, int const b ); // no no no */
// child's additionconst Integer operator+( Integer const a, Integer const b ){ return 11; // solution!}
// equalityconst bool operator==( Integer const a, Integer const b ){ return a.to_int() == b.to_int();}
example 1 2 3 4
Integer user defined type
/** * create from int, obtain as int. */class Integer{public: // this converting constructor allows to say: Integer a = 1; Integer( int const i ) : m_value( i ) { ; }
// provide the implementation value for other operations const int to_int() const { return m_value; }
private: int m_value; // the implementation};
example 1 2 3 4
adapt test to use Integer
void one_plus_one_is_eleven( const std::string& test_name ) { Integer one = 1; fructose_assert( 11 == one + 1 ); }
example 1 2 3 4
run the test
return 11; // solution! fructose_assert( 11 == one + 1 );
prompt>example2.exe
prompt>
example 1 2 3 4
oh, you also want 12 == 1 + 2 ?!
/** * add another test. */struct math_test : public fructose::test_base< math_test >{ void one_plus_one_is_eleven( const std::string& test_name ) ... void one_plus_two_is_twelve( const std::string& test_name ) { Integer two = 2; fructose_assert( 12 == 1 + two ); }};
t.add_test( "1 + 2 => 12", &math_test::one_plus_two_is_twelve );
example 1 2 3 4
run the test
return 11; // solution? fructose_assert( 12 == 1 + two );
prompt>example3.exeError: 1 + 2 => 12 in example3.cpp(49): 12 == 1 + two failed.
Test driver failed: 1 error
prompt>
example 1 2 3 4
correct verb child’s addition
// child's additionconst Integer operator+( Integer const a, Integer const b ){ return 10 * a.to_int() + b.to_int();}
example 1 2 3 4
return 10 * a.to_int() + b.to_int();
prompt>example4.exe
prompt>
run the test
example 1 2 3 4
11 == one + 1;
12 == 1 + two;
what did we learn?
decide on behaviour specify, document behaviour: the tests ensure the specified behaviour is present ensure the specified behaviour stays present
its name: Test Driven Development (TDD)
further information on WikiPedia
agile manifesto extreme programming test-driven development unit test, list of unit testing frameworks Matlab unit testing: http://mlunit.dohmke.de/