|
[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() );
}}
1.8.0