namespace NUnit.TextUI { using System; using System.IO; using System.Reflection; using NUnit.Framework; using NUnit.Runner; /// A command line based tool to run tests. /// /// C:\NUnitConsole.exe /t [/wait] TestCaseClass /// /// TestRunner expects the name of a TestCase class as argument. /// If this class defines a static Suite property it /// will be invoked and the returned test is run. Otherwise all /// the methods starting with "Test" having no arguments are run. /// /// When the wait command line argument is given TestRunner /// waits until the users types RETURN. /// /// TestRunner prints a trace as the tests are executed followed by a /// summary at the end. public class TestRunner : BaseTestRunner { int fColumn = 0; TextWriter fWriter = Console.Out; /// /// Constructs a TestRunner. /// public TestRunner() {} /// /// Constructs a TestRunner using the given stream for all the output /// public TestRunner(TextWriter writer) : this() { if (writer != null) { fWriter= writer; } else { throw new ArgumentNullException("writer"); } } /// /// /// /// /// public override void AddError(ITest test, Exception t) { lock(this) this.Writer.Write("E"); } /// /// /// /// /// public override void AddFailure(ITest test, AssertionFailedError t) { lock (this) this.Writer.Write("F"); } /// Creates the TestResult to be used for the test run. protected TestResult CreateTestResult() { return new TestResult(); } /// /// /// /// /// /// protected TestResult DoRun(ITest suite, bool wait) { TestResult result= CreateTestResult(); result.AddListener(this); long startTime= System.DateTime.Now.Ticks; suite.Run(result); long endTime= System.DateTime.Now.Ticks; long runTime= (endTime-startTime) / 10000; Writer.WriteLine(); Writer.WriteLine("Time: "+ElapsedTimeAsString(runTime)); Print(result); Writer.WriteLine(); if (wait) { Writer.WriteLine(" to continue"); try { Console.ReadLine(); } catch(Exception) { } } return result; } /// /// /// /// public override void EndTest(ITest test) { } /// /// /// /// public override ITestLoader GetLoader() { return new StandardLoader(); } /// /// /// /// public void Print(TestResult result) { lock(this) { PrintErrors(result); PrintFailures(result); PrintHeader(result); } } /// Prints the errors to the standard output. public 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(GetFilteredTrace(failure.ThrownException)); } } } /// Prints failures to the standard output. public 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(" \"" + Truncate(t.Message) + "\""); else { Writer.WriteLine(); Writer.Write(GetFilteredTrace(failure.ThrownException)); } } } } /// Prints the header of the report. public 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); } } /// Runs a Suite extracted from a TestCase subclass. static public void Run(Type testClass) { Run(new TestSuite(testClass)); } /// /// /// /// static public void Run(ITest suite) { TestRunner aTestRunner= new TestRunner(); aTestRunner.DoRun(suite, false); } /// Runs a single test and waits until the user /// types RETURN. static public void RunAndWait(ITest suite) { TestRunner aTestRunner= new TestRunner(); aTestRunner.DoRun(suite, true); } /// /// /// /// protected override void RunFailed(string message) { Console.Error.WriteLine(message); Environment.ExitCode = 1; throw new ApplicationException(message); } /// Starts a test run. Analyzes the command line arguments /// and runs the given test suite. public TestResult Start(string[] args) { bool wait = false; string testCase = ProcessArguments(args, ref wait); if (testCase.Equals("")) throw new ApplicationException("Usage: NUnitConsole.exe [/wait] testCaseName, where\n" + "name is the name of the TestCase class"); try { ITest suite = GetTest(testCase); return DoRun(suite, wait); } catch (Exception e) { throw new ApplicationException("Could not create and run test suite.", e); } } /// /// /// /// public override void StartTest(ITest test) { lock (this) { Writer.Write("."); if (fColumn++ >= 40) { Writer.WriteLine(); fColumn = 0; } } } /// /// /// protected TextWriter Writer { get { return fWriter; } } } }