|
Packit |
8c9aa0 |
#include <cppunit/BriefTestProgressListener.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/CompilerOutputter.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TestPath.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TestResult.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TestResultCollector.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TestRunner.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TextOutputter.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/TextTestProgressListener.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/XmlOutputter.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/extensions/TestFactoryRegistry.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/plugin/DynamicLibraryManagerException.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/plugin/PlugInParameters.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/plugin/PlugInManager.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/plugin/TestPlugIn.h>
|
|
Packit |
8c9aa0 |
#include <cppunit/portability/Stream.h>
|
|
Packit |
8c9aa0 |
#include "CommandLineParser.h"
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
/* Notes:
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
Memory allocated by test plug-in must be freed before unloading the test plug-in.
|
|
Packit |
8c9aa0 |
That is the reason why the XmlOutputter is explicitely destroyed.
|
|
Packit |
8c9aa0 |
*/
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
/*! Runs the specified tests located in the root suite.
|
|
Packit |
8c9aa0 |
* \param parser Command line parser.
|
|
Packit |
8c9aa0 |
* \return \c true if the run succeed, \c false if a test failed or if a test
|
|
Packit |
8c9aa0 |
* path was not resolved.
|
|
Packit |
8c9aa0 |
*/
|
|
Packit |
8c9aa0 |
bool
|
|
Packit |
8c9aa0 |
runTests( const CommandLineParser &parser )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
bool wasSuccessful = false;
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::PlugInManager plugInManager;
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// The following scope is used to explicitely free all memory allocated before
|
|
Packit |
8c9aa0 |
// unload the test plug-ins (uppon plugInManager destruction).
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::TestResult controller;
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::TestResultCollector result;
|
|
Packit |
8c9aa0 |
controller.addListener( &result );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Set up outputters
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::OStream *stream = &CPPUNIT_NS::stdCErr();
|
|
Packit |
8c9aa0 |
if ( parser.useCoutStream() )
|
|
Packit |
8c9aa0 |
stream = &CPPUNIT_NS::stdCOut();
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::OStream *xmlStream = stream;
|
|
Packit |
8c9aa0 |
if ( !parser.getXmlFileName().empty() )
|
|
Packit |
8c9aa0 |
xmlStream = new CPPUNIT_NS::OFileStream( parser.getXmlFileName().c_str() );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::XmlOutputter xmlOutputter( &result, *xmlStream, parser.getEncoding() );
|
|
Packit |
8c9aa0 |
xmlOutputter.setStyleSheet( parser.getXmlStyleSheet() );
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::TextOutputter textOutputter( &result, *stream );
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::CompilerOutputter compilerOutputter( &result, *stream );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Set up test listeners
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::BriefTestProgressListener briefListener;
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::TextTestProgressListener dotListener;
|
|
Packit |
8c9aa0 |
if ( parser.useBriefTestProgress() )
|
|
Packit |
8c9aa0 |
controller.addListener( &briefListener );
|
|
Packit |
8c9aa0 |
else if ( !parser.noTestProgress() )
|
|
Packit |
8c9aa0 |
controller.addListener( &dotListener );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Set up plug-ins
|
|
Packit |
8c9aa0 |
for ( int index =0; index < parser.getPlugInCount(); ++index )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CommandLinePlugInInfo plugIn = parser.getPlugInAt( index );
|
|
Packit |
8c9aa0 |
plugInManager.load( plugIn.m_fileName, plugIn.m_parameters );
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Registers plug-in specific TestListener (global setUp/tearDown, custom TestListener...)
|
|
Packit |
8c9aa0 |
plugInManager.addListener( &controller );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Adds the default registry suite
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::TestRunner runner;
|
|
Packit |
8c9aa0 |
runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Runs the specified test
|
|
Packit |
8c9aa0 |
try
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
runner.run( controller, parser.getTestPath() );
|
|
Packit |
8c9aa0 |
wasSuccessful = result.wasSuccessful();
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
catch ( std::invalid_argument & )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() << "Failed to resolve test path: "
|
|
Packit |
8c9aa0 |
<< parser.getTestPath()
|
|
Packit |
8c9aa0 |
<< "\n";
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// Removes plug-in specific TestListener (not really needed but...)
|
|
Packit |
8c9aa0 |
plugInManager.removeListener( &controller );
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// write using outputters
|
|
Packit |
8c9aa0 |
if ( parser.useCompilerOutputter() )
|
|
Packit |
8c9aa0 |
compilerOutputter.write();
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
if ( parser.useTextOutputter() )
|
|
Packit |
8c9aa0 |
textOutputter.write();
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
if ( parser.useXmlOutputter() )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
plugInManager.addXmlOutputterHooks( &xmlOutputter );
|
|
Packit |
8c9aa0 |
xmlOutputter.write();
|
|
Packit |
8c9aa0 |
plugInManager.removeXmlOutputterHooks();
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
if ( !parser.getXmlFileName().empty() )
|
|
Packit |
8c9aa0 |
delete xmlStream;
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
return wasSuccessful;
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
void
|
|
Packit |
8c9aa0 |
printShortUsage( const std::string &applicationName )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() << "Usage:\n"
|
|
Packit |
8c9aa0 |
<< applicationName << " [-c -b -n -t -o -w] [-x xml-filename]"
|
|
Packit |
8c9aa0 |
"[-s stylesheet] [-e encoding] plug-in[=parameters] [plug-in...] [:testPath]\n\n";
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
void
|
|
Packit |
8c9aa0 |
printUsage( const std::string &applicationName )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
printShortUsage( applicationName );
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() <<
|
|
Packit |
8c9aa0 |
"-c --compiler\n"
|
|
Packit |
8c9aa0 |
" Use CompilerOutputter\n"
|
|
Packit |
8c9aa0 |
"-x --xml [filename]\n"
|
|
Packit |
8c9aa0 |
" Use XmlOutputter (if filename is omitted, then output to cout or\n"
|
|
Packit |
8c9aa0 |
" cerr.\n"
|
|
Packit |
8c9aa0 |
"-s --xsl stylesheet\n"
|
|
Packit |
8c9aa0 |
" XML style sheet for XML Outputter\n"
|
|
Packit |
8c9aa0 |
"-e --encoding encoding\n"
|
|
Packit |
8c9aa0 |
" XML file encoding (UTF8, shift_jis, ISO-8859-1...)\n"
|
|
Packit |
8c9aa0 |
"-b --brief-progress\n"
|
|
Packit |
8c9aa0 |
" Use BriefTestProgressListener (default is TextTestProgressListener)\n"
|
|
Packit |
8c9aa0 |
"-n --no-progress\n"
|
|
Packit |
8c9aa0 |
" Show no test progress (disable default TextTestProgressListener)\n"
|
|
Packit |
8c9aa0 |
"-t --text\n"
|
|
Packit |
8c9aa0 |
" Use TextOutputter\n"
|
|
Packit |
8c9aa0 |
"-o --cout\n"
|
|
Packit |
8c9aa0 |
" Ouputters output to cout instead of the default cerr.\n"
|
|
Packit |
8c9aa0 |
"-w --wait\n"
|
|
Packit |
8c9aa0 |
" Wait for the user to press a return before exit.\n"
|
|
Packit |
8c9aa0 |
"filename[=\"options\"]\n"
|
|
Packit |
8c9aa0 |
" Many filenames can be specified. They are the name of the \n"
|
|
Packit |
8c9aa0 |
" test plug-ins to load. Optional plug-ins parameters can be \n"
|
|
Packit |
8c9aa0 |
" specified after the filename by adding '='.\n"
|
|
Packit |
8c9aa0 |
"[:testpath]\n"
|
|
Packit |
8c9aa0 |
" Optional. Only one test path can be specified. It must \n"
|
|
Packit |
8c9aa0 |
" be prefixed with ':'. See TestPath constructor for syntax.\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
"'parameters' (test plug-in or XML filename, test path...) may contains \n"
|
|
Packit |
8c9aa0 |
"spaces if double quoted. Quote may be escaped with \".\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
"Some examples of command lines:\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
"DllPlugInTesterd_dll.exe -b -x tests.xml -c simple_plugind.dll CppUnitTestPlugInd.dll\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
" Will load 2 tests plug-ins (available in lib/), use the brief test\n"
|
|
Packit |
8c9aa0 |
"progress, output the result in XML in file tests.xml and also\n"
|
|
Packit |
8c9aa0 |
"output the result using the compiler outputter.\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
"DllPlugInTesterd_dll.exe ClockerPlugInd.dll=\"flat\" -n CppUnitTestPlugInd.dll\n"
|
|
Packit |
8c9aa0 |
"\n"
|
|
Packit |
8c9aa0 |
" Will load the 2 test plug-ins, and pass the parameter string \"flat\"\n"
|
|
Packit |
8c9aa0 |
"to the Clocker plug-in, disable test progress.\n\n";
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
/*! Main
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* Usage:
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* DllPlugInTester.exe dll-filename1 [dll-filename2 [dll-filename3 ...]] [:testpath]
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* dll-filename must be the name of the DLL. If the DLL use some other DLL, they
|
|
Packit |
8c9aa0 |
* should be in the path or in the same directory as the DLL. The DLL must export
|
|
Packit |
8c9aa0 |
* a function named "GetTestPlugInInterface" with the signature
|
|
Packit |
8c9aa0 |
* GetTestPlugInInterfaceFunction. Both are defined in:
|
|
Packit |
8c9aa0 |
* \code
|
|
Packit |
8c9aa0 |
* #include <msvc6/testrunner/TestPlugInInterface.h>
|
|
Packit |
8c9aa0 |
* \endcode.
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* If no test path is specified, they all the test of the suite returned by the DLL
|
|
Packit |
8c9aa0 |
* are run. If a test path is specified, then only the specified test is run. The test
|
|
Packit |
8c9aa0 |
* path must be prefixed by ':'.
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* Test paths are resolved using Test::resolveTestPath() on the suite returned by
|
|
Packit |
8c9aa0 |
* TestFactoryRegistry::getRegistry().makeTest();
|
|
Packit |
8c9aa0 |
*
|
|
Packit |
8c9aa0 |
* If all test succeed and no error happen then the application exit with code 0.
|
|
Packit |
8c9aa0 |
* If any error occurs (failed to load dll, failed to resolve test paths) or a
|
|
Packit |
8c9aa0 |
* test fail, the application exit with code 1. If the application failed to
|
|
Packit |
8c9aa0 |
* parse the command line, it exits with code 2.
|
|
Packit |
8c9aa0 |
*/
|
|
Packit |
8c9aa0 |
int
|
|
Packit |
8c9aa0 |
main( int argc,
|
|
Packit |
8c9aa0 |
const char *argv[] )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
const int successReturnCode = 0;
|
|
Packit |
8c9aa0 |
const int failureReturnCode = 1;
|
|
Packit |
8c9aa0 |
const int badCommadLineReturnCode = 2;
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
// check command line
|
|
Packit |
8c9aa0 |
std::string applicationName( argv[0] );
|
|
Packit |
8c9aa0 |
if ( argc < 2 )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
printUsage( applicationName );
|
|
Packit |
8c9aa0 |
return badCommadLineReturnCode;
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
CommandLineParser parser( argc, argv );
|
|
Packit |
8c9aa0 |
try
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
parser.parse();
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
catch ( CommandLineParserException &e )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() << "Error while parsing command line: " << e.what()
|
|
Packit |
8c9aa0 |
<< "\n\n";
|
|
Packit |
8c9aa0 |
printShortUsage( applicationName );
|
|
Packit |
8c9aa0 |
return badCommadLineReturnCode;
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
bool wasSuccessful = false;
|
|
Packit |
8c9aa0 |
try
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
wasSuccessful = runTests( parser );
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
catch ( CPPUNIT_NS::DynamicLibraryManagerException &e )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() << "Failed to load test plug-in:\n"
|
|
Packit |
8c9aa0 |
<< e.what() << "\n";
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
#if !defined( CPPUNIT_NO_STREAM )
|
|
Packit |
8c9aa0 |
if ( parser.waitBeforeExit() )
|
|
Packit |
8c9aa0 |
{
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut() << "Please press <RETURN> to exit\n";
|
|
Packit |
8c9aa0 |
CPPUNIT_NS::stdCOut().flush();
|
|
Packit |
8c9aa0 |
std::cin.get();
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
#endif
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
return wasSuccessful ? successReturnCode : failureReturnCode;
|
|
Packit |
8c9aa0 |
}
|
|
Packit |
8c9aa0 |
|
|
Packit |
8c9aa0 |
|