#ifndef TEST_H #define TEST_H /////////////////////////////////////////////////////////////////// // Test.h - declares the Test class, which supports // // ver 2.0 definition of a single test // // // // Language: Visual C++, ver 6.0, SP 4 // // Platform: Dell XPS1000, Windows 2000 Professional, SP 1 // // Author: Jim Fawcett, CST 2-187, Syracuse University // // jfawcett@twcny.rr.com, 315-443-3948 // // Source: // // The origianl design and implementation are by Chuck // // Allison (see ref, below), but I have modified his code // // and so take responsibility for this product. // /////////////////////////////////////////////////////////////////// // Notes: // // - This is a demonstration of a test harness that provides // // semi-automated low-level testing. // // - Goal is to run a suite of tests that return pass/fail // // information (this module supports the definition of a // // single test). // // - The intent is that you will use the test harness after // // every modification to your code, getting quick evidence // // that the change did or did not break anything. // // // // - To use the harness you have to implement simple test // // classes, derived from class Test, provided by this module. // // - You then declare an instance of class Suite, provided // // by the harness and add an instance of each test class. // // The test harness: // // - sequences through all your tests, // // - keeps records of passes and failures // // - handles display of the results // // // // Reference: // // The Simplest Automated Unit Test Framework That Could // // Possibly Work, Chuck Allison, C/C++ Users Journal, // // September 2000 // /////////////////////////////////////////////////////////////////// // /////////////////////////////////////////////////////////////////// // Build Process // // Required Files: // // test.h, test.cpp // // // // Building in IDE: // // - create a workspace and project including these files // // - set Project/Settings/C\C++/Category=C++ Language // // check Enable Run-Time Type Information (RTTI) // // - set Project/Settings/C\C++/Category=general // // add ,TEST_TEST to Preprocessor definitions // // - compile, link, and run // // // // Command line build: // // cl /GX /GR /DTEST_TEST test.cpp // /////////////////////////////////////////////////////////////////// // Maintenance History // // ver 1.0 : Sep 2000 // // - first release, Chuck Allison, see Reference, above // // ver 2.0 : 2 Oct 2000 // // - added all manual, maintenance page information // // - removed all using declarations from header files // // - made cosmetic modifications to output display code // // - added test construction stub to test.cpp // // // /////////////////////////////////////////////////////////////////// #include #include // ///////////////////////////////////////////////////////////////// // macros used to pass file and line numbers of the test site // to test functions // // The following have underscores because they are macros // (and it's impolite to usurp other users' functions!). // For consistency, _succeed() also has an underscore. #define _test(cond) do_test(cond, #cond, __FILE__, __LINE__) #define _fail(str) do_fail(str, __FILE__, __LINE__) ///////////////////////////////////////////////////////////////// // Class Test provides all the basic test harness capability // class Test { public: Test(std::ostream* osptr = 0); virtual ~Test(){} virtual void run() = 0; long getNumPassed() const; long getNumFailed() const; const std::ostream* getStream() const; void setStream(std::ostream* osptr); void _succeed(); long report() const; virtual void reset(); protected: void do_test(bool cond, const std::string& lbl, const char* fname, long lineno); void do_fail(const std::string& lbl, const char* fname, long lineno); private: std::ostream* m_osptr; long m_nPass; long m_nFail; // Disallows copy construction and assignment: Test(const Test&); Test& operator=(const Test&); }; //----< construction using a stream pointer >-------------------- inline Test::Test(std::ostream* osptr) { m_osptr = osptr; m_nPass = m_nFail = 0; } // //----< return test success statistics >------------------------- inline long Test::getNumPassed() const { return m_nPass; } //----< return test failure statistics >------------------------- inline long Test::getNumFailed() const { return m_nFail; } //----< return pointer to the test harness output stream >------- inline const std::ostream* Test::getStream() const { return m_osptr; } //----< give test harness an output stream pointer >------------- inline void Test::setStream(std::ostream* osptr) { m_osptr = osptr; } //----< increment success count >-------------------------------- inline void Test::_succeed() { ++m_nPass; } //----< reset success and fail counts >-------------------------- inline void Test::reset() { m_nPass = m_nFail = 0; } #endif