[B]asic module for [unit] program testing:
|
Header file BUnit.h
supports writing modules for unit program testing. The model used for this implementation is similar to that described in the article "The Simplest Automated Unit Test Framework That Could
Possibly Work "by Chuck Allison, which you can get here:
BUnit
is contained within the single header file BUnit.h
, so testing requieres only this directive:BUnit_TEST()
that also records the filename FILE
and the line LINE
for that test.
TestCase
is a subclass of Assert
; in BUnit no Assert
class exist but to maintain compatibility with JUnit similar functionality is provided with macros whose names begin with "assert".
TestCase::errorCount()
always returns zero 0
. // Failure vs Error in JUnit public void test_Fail () { try { new ArrayList(10).get( 11 ); fail("Error if IndexOutOfBoundsException is not thrown" ); // error } catch (IndexOutOfBoundsException success) { } // Ok } public void test_Failure() { assertTrue( 1 == 2 ); // failure }
BUnit.h
no difference is made between "failures" and "errors".JUnit
an "error" means that the wrong exception was raised.JUnit
a "failure" means that an assertion was false.assertTrue()
.{{ // test::Allison() // Stack class for letter -- very simple (<em>Last In First Out</em>). // - Throws \c std::logic_error on invalid operations. // - Example inspired in Chuck Allison' work. // - http://search.yahoo.com/search?n=100&p=Simplest+Unit+Test+Allison class Stack { public: enum { N = 5 /* Max Capacity for the stack */ }; // Constructor for a stack that can hold up to \c "Stack::N" values. Stack() : m_top(0) { m_vec[m_top] = 0; } // Stoes a copy of "v" at the top of the stack. void push(const char& v) { if ( m_top != N ) { m_vec[m_top] = v; m_top++; } else { throw std::out_of_range("Stack::push()"); } } // Removes the topmost value from the stack. void pop() { if ( m_top>0 ) { m_top--; } else { throw std::out_of_range("Stack::pop()"); } } // Reference to topmost value in the stack. char& top() { if ( m_top>0 ) { return m_vec[m_top-1]; } else { throw std::out_of_range("Stack::top()"); } } // Number of values stored in the stack. unsigned size() const { return m_top; } private: char m_vec[N+1] ; // Vector to hold stored values. int m_top; // Next available vector entry. }; // Stack class MyTest : public TestCase { public: bool run() { Stack S; // the stack try { // empty stack S.pop(); fail_Msg("! S.pop()"); } catch ( std::out_of_range & ex ) { assertTrue( 0 == strcmp( ex.what() , "Stack::pop()" ) ); // Ok: empty stack } catch (...) { fail_Msg("! ( std::out_of_range & )"); } try { // Pila llena for (int i=0; true; ++i) { S.push('0'+i); assertTrue( S.top() == '0'+i ); } fail_Msg("! S.push()"); } catch ( std::out_of_range & ex ) { assertTrue( 0 == strcmp( ex.what() , "Stack::push()" ) ); // Ok: full stack } catch (...) { fail_Msg("! ( std::out_of_range & )"); } try { // Vacea la pila for (int i=Stack::N-1; true; --i) { assertTrue( S.top() == '0'+i ); S.pop(); } fail_Msg("! S.pop()"); } catch ( std::out_of_range & ex ) { assertTrue( 0 == strcmp( ex.what() , "Stack::top()" ) ); // Ok: empty stack } catch (...) { fail_Msg("! ( std::out_of_range & )"); } return wasSuccessful(); } }; // MyTest MyTest thisTest; thisTest.run(); // 0 failures assertTrue( thisTest.wasSuccessful() ); }}