[B]asic module for [unit] program testing: Documentation
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:
- To simplify to a minimum the task of writing test cases, the full implementation of
BUnit is contained within the single header file BUnit.h, so testing requieres only this directive:
- This framework is similar to JUnit, because it is presumed that in the future students will use Java as their primary language to develop programs (as C++ is used only for deep training in programming techniques).
- See also:
- http://search.yahoo.com/search?n=100&p=JUnit+Java
- As C++ does not have a mechanism similar to Java's "reflection", for each failed test the exact test condition is recorded using an invocation to macro
BUnit_TEST() that also records the filename __FILE__ and the line __LINE__ for that test. - See also:
- http://search.yahoo.com/search?n=100&p=reflection+Java
- In JUnit class
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". - See also:
- http://search.yahoo.com/search?n=100&p=JUnit+Java+Assert+method
- To simplify this framework no difference is made between a test that is not successfull and one that didn“t succeed because the correct exception was not raised. This is a contrast with JUnit where an "error" is a test case that raised the wrong exception. This explains why
TestCase::errorCount() always returns zero 0.
public void test_Fail () {
try {
new ArrayList(10).get( 11 );
fail("Error if IndexOutOfBoundsException is not thrown" );
}
catch (IndexOutOfBoundsException success) { }
}
public void test_Failure() {
assertTrue( 1 == 2 );
}
- In
BUnit.h no difference is made between "failures" and "errors".
- In JUnit, what's the difference between a failure and an error?
- Assertions are used to check for the possibility of failures, therefore failures are anticipated with invokations similar to
assertTrue(). - Errors are unanticipated problems resulting in uncaught exceptions being propagated from a JUnit test method.
- See also:
- http://www.cs.waikato.ac.nz/~bernhard/314/junit3.8.1/doc/faq/faq.htm#tests_9
- See also:
- http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#tests_9
{{
class Stack {
public:
enum { N = 5 };
Stack() : m_top(0) { m_vec[m_top] = 0; }
void push(const char& v) {
if ( m_top != N ) { m_vec[m_top] = v; m_top++; }
else { throw std::out_of_range("Stack::push()"); }
}
void pop() {
if ( m_top>0 ) { m_top--; }
else { throw std::out_of_range("Stack::pop()"); }
}
char& top() {
if ( m_top>0 ) { return m_vec[m_top-1]; }
else { throw std::out_of_range("Stack::top()"); }
}
unsigned size() const { return m_top; }
private:
char m_vec[N+1] ;
int m_top;
};
class MyTest : public TestCase {
public:
bool run() {
Stack S;
try {
S.pop();
fail_Msg("! S.pop()");
}
catch ( std::out_of_range & ex ) {
assertTrue( 0 == strcmp( ex.what() , "Stack::pop()" ) );
}
catch (...) {
fail_Msg("! ( std::out_of_range & )");
}
try {
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()" ) );
}
catch (...) {
fail_Msg("! ( std::out_of_range & )");
}
try {
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()" ) );
}
catch (...) {
fail_Msg("! ( std::out_of_range & )");
}
return wasSuccessful();
}
};
MyTest thisTest;
thisTest.run();
assertTrue( thisTest.wasSuccessful() );
}}
- See also:
- test_BUnit::test_Allison()