FAQ 10.06 What is behavioral self-testing?

When an object checks its work before letting others see what happened.

The promises made by a member function can be encoded as a test that is executed at the end of the member function. For example, if the member function List::removeFirst() promises that List::size() will return one less than it did before, an explicit test to this effect can be made at the end of the List::removeFirst() member function. The code associated with behavioral self-tests can be wrapped in an #ifdef so that it can be easily removed or reinstalled as desired:

 #include <stdexcept> #include <cassert> #include <cstdlib> #include <string> using namespace std; class List; class Node { private:   friend List;   int   elem_;   Node* next_;   Node(int elem, Node* next) throw(); }; Node::Node(int elem, Node* next) throw() : elem_(elem) , next_(next) { } class Empty { }; class List { public:   List() throw();   bool empty() const throw();   int  size() const throw();   int  peekAtFirst() const throw(Empty);   void prepend(int x) throw();   int  removeFirst() throw(Empty);     // REQUIRE: empty() must return false     // PROMISE: Return value will be the initial value of peekAtFirst()     // PROMISE: size() will be reduced by 1   List            (const List& list) throw();  // copy  constructor   List& operator= (const List& list) throw();  // assignment operator   ~List() throw(); protected:   Node* first_; }; List::List() throw() : first_(NULL) { } List::~List() throw() { while (first_ != NULL) removeFirst(); } bool List::empty() const throw() { return first_ == NULL; } int List::size() const throw() {   int ans = 0;   for (const Node* p = first_; p != NULL; p = p->next_)     ++ans;   return ans; } int List::peekAtFirst() const throw(Empty) {   if (empty()) throw Empty("List::peekAtFirst()");   return first_->elem_; } void List::prepend(int x) throw() { first_ = new Node(x, first_); } int List::removeFirst() throw(Empty) {   if (empty()) throw Empty("List::removeFirst()");   #ifndef NDEBUG     int peekAtFirstInit = peekAtFirst();     int sizeInit = size();   #endif   // remove first element from the List   int result = first_->elem_;   Node* oldFirstNode = first_;   first_ = first_->next_;   delete oldFirstNode;   #ifndef NDEBUG     assert(result == peekAtFirstInit);     assert(size() == sizeInit - 1);   #endif   return result; } int main() {   List a;   a.prepend(42);   a.prepend(24);   int elem = a.removeFirst(); } 

Naturally the assert(...) statements can be replaced by other assertion-checking techniques, if desired. The point is that the object checks its own results.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net