I inherited a unit test system using VS.NET and CppUnit 1.10.2. It looks like one of our developers had set this up and customised the CppUnit code so that, when a command line argument, i.e. a file name, was passed in it would run the MFC Test Runner showing the GUI but also populating the file with the XML output.
I'd like to do something similar with CppUnit 1.12.x and VS2010 so that we can either use the MFC GUI for development runs or the XML output for use in our Jenkins CI system.
I've got it kind of working by making it so that a file name on the command line swaps between either the MFCTestRunner or the TextTestRunner with an XMLOutputter. I've done this within the InitInstance() function of a dialog.
While it kind of appears to work, I've noticed that, when running it from the command line with a filename argument, the program appears to 'complete' (i.e. the command prompt reappears) quite some time before the XML file is created! I've only tried this a couple of times so maybe i'm mistaken, but if anyone knows anything about trying to use the text/xml output in an MFC app I'd appreciate the benefit of their experience. It may just be that InitInstance() is the wrong place for the command line argument check but it's been a while since I used VS/MFC so it'll take me time to work that one out!
Thank you
John
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not really authoritative here but, as minor points:
InitInstance()
is the initialization stream for the dialog, and your CppUnit code is not really part of the dlg initialization … so make sure that it is at or towards the end of the function.
There are details missing from how your code works. Are you interfacing to the CppUnit callback or writing your own file? If you are writing your own file, are you closing the file after writing the desired contents?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for your reply. I think the best thing is for me to post my code so I've done it below. FWIW - when I run with the MFC GUI it takes around 14 seconds. Using the xml outputter the program returns control to the command line immediately, but the XML file is generated around 14 seconds later. Should I return FALSE from InitInstance?
Thanks
John
===
BOOLCHostAppApp::InitInstance(){// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.#ifdef _AFXDLL# if _MSC_VER < 1300 // vc6Enable3dControls();// Call this when using MFC in a shared DLL# endif#elseEnable3dControlsStatic();// Call this when linking to MFC statically#endif// Change the registry key under which our settings are stored.// You should modify this string to be something appropriate// such as the name of your company or organization.SetRegistryKey(_T("Local AppWizard-Generated Applications"));LoadStdProfileSettings();// Load standard INI file options (including MRU)// Register the application's document templates. Document templates// serve as the connection between documents, frame windows and views.CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CHostAppDoc),RUNTIME_CLASS(CMainFrame),// main SDI frame windowRUNTIME_CLASS(CHostAppView));AddDocTemplate(pDocTemplate);RunUnitTests();returnTRUE;}voidCHostAppApp::RunUnitTests(){// This #ifdef is to allow the code to compile both both the legacy system and the// new system. The legacy system is Windows XP, MS VS2003, and an older version// of cppunit, and the new system is Windows 7, MS VS2010 and cppunit 1.12.1 (with// VS 2010 tweaks). On Windows 7, the #define _WIN32_WINNT is set to 0x0601, so we// use this to decide if this is being compiled for the legacy system#if (_WIN32_WINNT == 0x601)LPCTSTRcommandline=GetCommandLine();LPCTSTRfilename=strrchr(commandline,' ');// look for last space// If a space was found, use the subsequent string as the file name but// make sure we haven't just found a space character at the end of the lineif(filename&&(strlen(filename)>1)){// Use the text/xml outputter++filename;// move to next character// Create the test runnerCppUnit::TextUi::TestRunnerrunner;// Create an event manager and test controllerCppUnit::TestResulttestResult;// Add a listener that collect test resultsCppUnit::TestResultCollectorcollectedResults;testResult.addListener(&collectedResults);runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());runner.run(testResult);std::ofstreamxmlOutput(filename);CppUnit::XmlOutputterxmlOutputter(&collectedResults,xmlOutput);xmlOutputter.write();}else{// Use the MFC Test RunnerCPPUNIT_NS::MfcUi::TestRunnerrunner;runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());runner.run();}#elseLPCTSTRcommandline=GetCommandLine();LPCTSTRfilename=strrchr(commandline,' ');// look for last spaceif(filename){++filename;// move to next character}CPPUNIT_NS::MfcUi::TestRunnerrunner;runner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());if(filename){runner.run(filename);}else{runner.run();}#endif}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi
I inherited a unit test system using VS.NET and CppUnit 1.10.2. It looks like one of our developers had set this up and customised the CppUnit code so that, when a command line argument, i.e. a file name, was passed in it would run the MFC Test Runner showing the GUI but also populating the file with the XML output.
I'd like to do something similar with CppUnit 1.12.x and VS2010 so that we can either use the MFC GUI for development runs or the XML output for use in our Jenkins CI system.
I've got it kind of working by making it so that a file name on the command line swaps between either the MFCTestRunner or the TextTestRunner with an XMLOutputter. I've done this within the InitInstance() function of a dialog.
While it kind of appears to work, I've noticed that, when running it from the command line with a filename argument, the program appears to 'complete' (i.e. the command prompt reappears) quite some time before the XML file is created! I've only tried this a couple of times so maybe i'm mistaken, but if anyone knows anything about trying to use the text/xml output in an MFC app I'd appreciate the benefit of their experience. It may just be that InitInstance() is the wrong place for the command line argument check but it's been a while since I used VS/MFC so it'll take me time to work that one out!
Thank you
John
I'm not really authoritative here but, as minor points:
is the initialization stream for the dialog, and your CppUnit code is not really part of the dlg initialization … so make sure that it is at or towards the end of the function.
Thanks for your reply. I think the best thing is for me to post my code so I've done it below. FWIW - when I run with the MFC GUI it takes around 14 seconds. Using the xml outputter the program returns control to the command line immediately, but the XML file is generated around 14 seconds later. Should I return FALSE from InitInstance?
Thanks
John
===
You don't want to return FALSE from InitInstance() - this indicates failure of the API and you won't get what you want from your app.
I don't know the specific answer to your question about latent file creation but I suspect the original code came from
http://www.codeproject.com/Articles/5660/Unit-testing-with-CPPUnit
which might be helpful…
Thanks for your suggestions. I've done a bit more research and found a similar question on stackoverflow. See http://stackoverflow.com/questions/12943463/how-to-create-a-c-mfc-program-that-can-boot-in-both-gui-dialog-mode-or-through. It looks like I need to do something like run it with "start/wait". I've tried that and it seems to work so I'll continue looking in that sort of direction.
Thanks again for your help.
John