www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Unittests and windows application

reply "Stefan" <stefanliebig web.de> writes:
I am currently porting a D1 application to D2. I am trying to 
take advantage of new language features but mostly of the "new" 
standard library features.
The old application has several unit tests and I would like to 
have them executed to secure that everything works as expected.

The problem with the unit tests is that they will be executed but 
I can not see the results because errors will be written to 
console output which is not available in a windows application.

I did a little bit of research and found this two similar threads:
- 
http://stackoverflow.com/questions/27580107/why-is-unit-testing-not-working-in-this-d-program
- 
http://forum.dlang.org/thread/joiglupanlvejarmsukd forum.dlang.org

But they just explain why that does not work.
Interestingly enough, the hint in the first thread to use the 
standard D main method instead of a WinMain 
(http://wiki.dlang.org/D_for_Win32) works for me. I just specify 
a *.def with SUBSYSTEM WINDOWS.

Class runtime.d seems to contain the code that performs the unit 
tests: bool runModuleUnitTests()
Runtime has a  property moduleUnitTester which can be set to a 
function that runs the unit test of a given module. If this is 
property is set it will be used otherwise a default test runner 
will be executed. This default test runner will report any error 
with the internal function void printErr(in char[] buf).

The question is where should the error output go in a windows 
application. Possible solutions maybe:
- write that to file similar to the code coverage *.lst
- write it to windows debug view with win32: void 
OutputDebugStringA( LPCTSTR lpOutputString )

I will try set the modultUnitTester property and use 
OutputDebugView. Although, not very nice because a lot of code 
has to be copied.

Are there any other options?
Mar 26 2015
next sibling parent reply "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 26 March 2015 at 10:23:58 UTC, Stefan wrote:
 I am currently porting a D1 application to D2. I am trying to 
 take advantage of new language features but mostly of the "new" 
 standard library features.
 The old application has several unit tests and I would like to 
 have them executed to secure that everything works as expected.

 The problem with the unit tests is that they will be executed 
 but I can not see the results because errors will be written to 
 console output which is not available in a windows application.
That's a bug. You'll notice that if an exception is thrown in main() (or anything called from it), you'll get a MessageBox for GUI applications. That this doesn't also occur with unittest failures is a bug. For now, you can work around this by writing your own WinMain, which calls rt_runModuleUnitTests explicitly, inside a try/catch block which will then display a MessageBox.
Mar 26 2015
parent reply "Stefan" <stefanliebig web.de> writes:
On Thursday, 26 March 2015 at 10:50:06 UTC, Vladimir Panteleev 
wrote:
 On Thursday, 26 March 2015 at 10:23:58 UTC, Stefan wrote:
..
 That's a bug. You'll notice that if an exception is thrown in 
 main() (or anything called from it), you'll get a MessageBox 
 for GUI applications. That this doesn't also occur with 
 unittest failures is a bug.
Do you have the bug/issue number for that?
 For now, you can work around this by writing your own WinMain, 
 which calls rt_runModuleUnitTests explicitly, inside a 
 try/catch block which will then display a MessageBox.
Hmm, that is what i tried to do, but the code in Runtime.runModuleUnitTests() catches already all exceptions and writes that to the console. I have not found rt_runModuleUnitTests in the current D runtime (2.067.0). However, I was successful in setting the moduleUnitTester property of Runtime. Inside my main module I do: static this() { Runtime.moduleUnitTester = &unitTestRunner; } bool unitTestRunner() { string line = ""; void printErr(in char[] buf) { string message = to!string(buf); if ( message == "\n" ) { Logger.send( line ); line = ""; } else { line ~= message; } } size_t failed = 0; foreach( m; ModuleInfo ) { if( m ) { auto fp = m.unitTest; if( fp ) { try { fp(); } catch( Throwable e ) { e.toString(&printErr); printErr("\n"); failed++; } } } } return failed == 0; } where the Logger.send() delegates to OutputDebugStringA().
Mar 26 2015
parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Thursday, 26 March 2015 at 12:11:33 UTC, Stefan wrote:
 On Thursday, 26 March 2015 at 10:50:06 UTC, Vladimir Panteleev 
 wrote:
 On Thursday, 26 March 2015 at 10:23:58 UTC, Stefan wrote:
..
 That's a bug. You'll notice that if an exception is thrown in 
 main() (or anything called from it), you'll get a MessageBox 
 for GUI applications. That this doesn't also occur with 
 unittest failures is a bug.
Do you have the bug/issue number for that?
https://issues.dlang.org/show_bug.cgi?id=14350
Mar 27 2015
prev sibling parent reply "Kagamin" <spam here.lot> writes:
Maybe, it's possible to redirect output explicitly?
myapp.exe >output.txt 2>errors.txt
Mar 26 2015
parent "Stefan" <stefanliebig web.de> writes:
On Thursday, 26 March 2015 at 13:57:31 UTC, Kagamin wrote:
 Maybe, it's possible to redirect output explicitly?
 myapp.exe >output.txt 2>errors.txt
Unbelievable, it is really as simple as this.
Mar 26 2015