Thread overview
Unittests and windows application
Mar 26, 2015
Stefan
Mar 26, 2015
Vladimir Panteleev
Mar 26, 2015
Stefan
Mar 27, 2015
Vladimir Panteleev
Mar 26, 2015
Kagamin
Mar 27, 2015
Stefan
March 26, 2015
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?
March 26, 2015
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.
March 26, 2015
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().
March 26, 2015
Maybe, it's possible to redirect output explicitly?
myapp.exe >output.txt 2>errors.txt
March 27, 2015
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.
March 27, 2015
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