///////////////////////////////////////////////////////////////////// // CppTestHarness.cpp - Helper demo for Project #2 // // // // Jim Fawcett, CSE687 - Object Oriented Design, Fall 2018 // ///////////////////////////////////////////////////////////////////// #include "CppTestHarness.h" #include "../ITest/ITest.h" #include "../FileSystem-Windows/FileSystemDemo/FileSystem.h" #include #include #include #include using namespace FileSystem; /*----< load library, activate test driver, and return address >---*/ ITest* TestHarness::getTest(const std::string& libSpec) { hMod = LoadLibraryA(libSpec.c_str()); if (!hMod) { std::cout << "\n failed to load library \"" << libSpec << "\""; return nullptr; } else { std::cout << "\n loaded library \"" << libSpec << "\""; } using Creator = ITest*(*)(); Creator creator = (Creator)GetProcAddress(hMod, "createTest"); if (creator == nullptr) { std::cout << "\n failed to get reference to ObjectFactory"; std::cout << "\n unloading \"" << libSpec << "\"\n"; FreeLibrary(hMod); return nullptr; } return creator(); // activate test driver and return it's address } /*----< scan root directory for libs, load, activate, and test >---*/ size_t TestHarness::loadAndExecuteTestLibraries() { std::vector files; size_t count = 0; if (Directory::exists(testRoot)) { files = Directory::getFiles(testRoot, "*.dll"); for (auto file : files) { ITest* tester = getTest(file); if (tester == nullptr) continue; try { if (tester->test()) { std::cout << "\n test \"" << file << "\" passed"; } else { std::cout << "\n test \"" << file << "\" failed"; } } catch (std::exception& ex) { std::cout << "\n test \"" << file << "\" failed"; std::cout << "\n " << ex.what(); } std::cout << "\n unloading \"" << file << "\"\n"; FreeLibrary(hMod); hMod = nullptr; } } return count; } /*----< run all tests >--------------------------------------------*/ /* * - Here is where you will parse TestRequest, so you only load * those libraries that have test drivers. * - Look at the output of this demo to see that you otherwise * will load all libraries in root folder even if they don't * have test drivers, e.g., when you build the tested code as * a separate library, that will get loaded even though there * is no test driver to run. * - That's what happened with Tested2.dll. */ bool TestHarness::doTests() { loadAndExecuteTestLibraries(); return true; } /*----< begin testing >--------------------------------------------*/ int main() { std::cout << "\n Demonstrating C++ Test Harness Helper"; std::cout << "\n ======================================="; TestHarness th; th.doTests(); std::cout << "\n\n"; return 0; }