/////////////////////////////////////////////////////////////////// // Main1.cpp - Tests the Test and Suite classes // // // // This module provides a good example of how you would use // // the low-level test harness, provided by the Test and Suite // // modules. // // // // 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. // // - 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 harness you have to implement simple test classes, // // derived from class Test, provided by test harness. // // - You then declare an instance of class Suite, provided // // by this module 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: // // main1.cpp, suite.h, suite.cpp, 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 main1.cpp suite.cpp 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 // // - provided construction test stubs for test.cpp and // // suite.cpp // // // /////////////////////////////////////////////////////////////////// // #include #include #include #include "suite.h" using namespace std; ///////////////////////////////////////////////////////////////// // this is a test class, used to test the standard C++ // class complex, e.g., just a demonstration of how to // use the test harness. // class ComplexTest : public Test { complex* m_c1; complex* m_c2; complex* m_c3; public: ComplexTest() { m_c1 = new complex(1,1); m_c2 = new complex(2,2); m_c3 = new complex(3,3); } ~ComplexTest() { delete m_c1; delete m_c2; delete m_c3; } void run() { testEqual(); testAdd(); } void testEqual() { complex c1(1,1); _test(*m_c1 == c1); _test(!(m_c1 == m_c2)); } void testAdd() { _test(*m_c1 + *m_c2 != *m_c3); // failure } }; // ///////////////////////////////////////////////////////////////// // this is a void test class that simply shows how to hook // into the test harness. It will also be used to show how // a suite of tests is built, by using ComplexTest and VoidTest // to build a small suite. // class VoidTest : public Test { public: void run() { _test(true); } }; ///////////////////////////////////////////////////////////////// // test stub // int main() { cout << "\n Test Low-Level Test Harness " << "\n =============================\n"; Suite s("Suite Test"); cout << "\n Demonstrate error handling for Suite class " << "\n --------------------------------------------"; // You add a test to the suite by passing the suite instance // a pointer to your test class instance. This tests error // handling when you pass a null pointer. try { s.addTest(0); } catch (TestSuiteError&) { cout << "\n Caught bad addTest\n"; } // cout << "\n Demonstrate building a suite, using null output stream " << "\n --------------------------------------------------------"; // since the suite output stream is null, no reporting occurs until // test stub specifically asks for it s.addTest(new ComplexTest); s.addTest(new VoidTest); s.run(); long fails = s.report(); cout << "\n fails == " << fails << " (should be 1)\n"; cout << "\n Demonstrate building a suite, using ostringstream " << "\n ---------------------------------------------------\n"; // since the stream is an ostringstream, reporting does not happen // until the user displays the string stream contents. // // if, instead, we used the ostream cout, we would see reports as // the errors occur string name = string("modified ") + s.getName(); Suite s2(name); ostringstream os; s2.setStream(&os); s2.addSuite(s); // creating a suite from another s2.run(); cout << "\n Report style 1: " << "\n -----------------"; cout << "\n Total Passes: " << s2.getNumPassed() << " (should be 3)"; cout << "\n Total failures: " << s2.report() << " (should be 1)\n"; cout << "\n Report style 2: " << "\n -----------------"; cout << os.str() << endl; // don't call free on both s and s2, as the tests are both freed // by the first call to either one s2.free(); cout << "\n\n"; return fails; }