[Mono-list] Nunit on Linux
Martin Baulig
martin@gnome.org
26 Feb 2002 22:05:15 +0100
--=-=-=
"Nick Drochak" <ndrochak@gol.com> writes:
> For the tests to be of any practical use anymore, we must get Nunit
> running on Linux. There are internal calls sprinkled throught the
> corlib now that basically make it impossible to test the corlib on
> windows. Well, we could get mono to build and work on Windows as
> another option, but that's the easy way out :)
Hi,
I looked at this a bit this afternoon and I think the biggest job is
to get System.Reflection fully working - NUnit heavily uses dynamic
method invocations and they aren't implemented yet.
For the meantime, one way to test things on Linux is to use a custom
testrunner which calls all the tests statically.
Here's a small HOWTO:
* first of all, you need to write your own testrunner - the following
is a good start:
--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=RunTests.cs
using System;
using System.IO;
using System.Threading;
using System.Globalization;
using NUnit.Framework;
class MainApp {
static TextWriter fWriter = Console.Out;
protected static TextWriter Writer {
get { return fWriter; }
}
public static void Print(TestResult result) {
PrintErrors(result);
PrintFailures(result);
PrintHeader(result);
}
/// <summary>Prints the errors to the standard output.</summary>
public static void PrintErrors(TestResult result) {
if (result.ErrorCount != 0) {
if (result.ErrorCount == 1)
Writer.WriteLine("There was "+result.ErrorCount+" error:");
else
Writer.WriteLine("There were "+result.ErrorCount+" errors:");
int i= 1;
foreach (TestFailure failure in result.Errors) {
Writer.WriteLine(i++ + ") "+failure+"("+failure.ThrownException.GetType().ToString()+")");
Writer.Write(failure.ThrownException);
}
}
}
/// <summary>Prints failures to the standard output.</summary>
public static void PrintFailures(TestResult result) {
if (result.FailureCount != 0) {
if (result.FailureCount == 1)
Writer.WriteLine("There was " + result.FailureCount + " failure:");
else
Writer.WriteLine("There were " + result.FailureCount + " failures:");
int i = 1;
foreach (TestFailure failure in result.Failures) {
Writer.Write(i++ + ") " + failure.FailedTest);
Exception t= failure.ThrownException;
if (t.Message != "")
Writer.WriteLine(" \"" + t.Message + "\"");
else {
Writer.WriteLine();
Writer.Write(failure.ThrownException);
}
}
}
}
/// <summary>Prints the header of the report.</summary>
public static void PrintHeader(TestResult result) {
if (result.WasSuccessful) {
Writer.WriteLine();
Writer.Write("OK");
Writer.WriteLine (" (" + result.RunCount + " tests)");
} else {
Writer.WriteLine();
Writer.WriteLine("FAILURES!!!");
Writer.WriteLine("Tests Run: "+result.RunCount+
", Failures: "+result.FailureCount+
", Errors: "+result.ErrorCount);
}
}
public static void Main() {
Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
TestResult result = new TestResult ();
TestSuite suite = new TestSuite ();
suite.AddTest (new MonoTests.System.DateTimeTest ("DateTimeTest"));
suite.AddTest (new MonoTests.System.TimeZoneTest ("TimeZoneTest"));
suite.Run (result);
Print (result);
}
}
--=-=-=
* in your test file (let's use DateTimeTest.cs for an example), you need
to override the RunTests method:
=====
public DateTimeTest (string name): base(name) {}
public static ITest Suite
{
get {
TestSuite suite = new TestSuite ();
return suite;
}
}
protected override void RunTest ()
{
TestCtors ();
TestToString ();
TestParseExact ();
TestParse ();
}
====
You need to manually list all your tests there ....
* you need to reference your test suite in the RunTests.cs - if you look at the end of the
attached RunTests.cs, there is:
====
public static void Main() {
Thread.CurrentThread.CurrentCulture = new CultureInfo ("en-US");
TestResult result = new TestResult ();
TestSuite suite = new TestSuite ();
suite.AddTest (new MonoTests.System.DateTimeTest ("DateTimeTest"));
suite.AddTest (new MonoTests.System.TimeZoneTest ("TimeZoneTest"));
suite.Run (result);
Print (result);
}
===
Add all your test suites there.
* manually compile RunTests.cs and your test suites to an executable RunTests.exe:
(you need to do this on Windows, but see below)
csc /nologo /lib:c:/cygwin/usr/local/martin/bin /r:NUnitCore.dll RunTests.cs DateTimeTest.cs
TimeZoneTest.cs
* run the RunTests.exe with mint or mono
If you're doing stuff on Linux and need to quickly run a command on Windows, here are two shell
scripts which proved useful for me:
- put this in your $PATH on your Linux box and make csc a symlink to it
--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=atlantis
#!/usr/bin/perl -w
$LINUXPREFIX = '/home/export/martin';
$WINPREFIX = '//townsville/martin';
$dir = `pwd`; chop $dir;
$dir =~ s/^$LINUXPREFIX/$WINPREFIX/ or die
"Can't map directory `$dir' to windows path";
$0 =~ m,.*/(.*)$, or die
"Can't map command name `$0' to windows path";
$command = $1;
@args = @ARGV;
unshift @args, $command unless $command eq 'atlantis';
system ("ssh", "atlantis", "-l", "martin", "/usr/local/bin/atlantis", $dir, @args);
--=-=-=
- put this in your $PATH on your Windows box
--=-=-=
Content-Type: application/octet-stream
Content-Disposition: attachment; filename=atlantis
#!/bin/sh
dir=$1 ; shift
cd $dir && $@
--=-=-=
I'm using a partition which is shared between Linux (/home/export/martin) and Windows (//townsville/martin);
the script automatically translates the path names, so you can just type 'csc' on Linux and it ssh's to
Windows and runs it there.
--
Martin Baulig
martin@gnome.org
--=-=-=--