1 // ****************************************************************
\r
2 // This is free software licensed under the NUnit license. You
\r
3 // may obtain a copy of the license as well as information regarding
\r
4 // copyright ownership at http://nunit.org/?p=license&r=2.4.
\r
5 // ****************************************************************
\r
13 /// The TestResult abstract class represents
\r
14 /// the result of a test and is used to
\r
15 /// communicate results across AppDomains.
\r
19 public abstract class TestResult
\r
23 /// Indicates whether the test was executed or not
\r
25 private RunState runState;
\r
28 /// Indicates the result of the test
\r
30 private ResultState resultState;
\r
33 /// Indicates the location of a failure
\r
35 private FailureSite failureSite;
\r
38 /// The elapsed time for executing this test
\r
40 private double time = 0.0;
\r
43 /// The name of the test
\r
45 private string name;
\r
48 /// The test that this result pertains to
\r
50 private TestInfo test;
\r
53 /// The stacktrace at the point of failure
\r
55 private string stackTrace;
\r
58 /// Description of this test
\r
60 private string description;
\r
63 /// Message giving the reason for failure
\r
65 protected string messageString;
\r
68 /// Number of asserts executed by this test
\r
70 private int assertCount = 0;
\r
74 #region Protected Constructor
\r
76 /// Protected constructor constructs a test result given
\r
77 /// a test and a name.
\r
79 /// <param name="test">The test to be used</param>
\r
80 /// <param name="name">Name for this result</param>
\r
81 protected TestResult(TestInfo test, string name)
\r
85 this.RunState = RunState.Runnable;
\r
88 this.description = test.Description;
\r
89 this.runState = test.RunState;
\r
90 this.messageString = test.IgnoreReason;
\r
98 /// Gets the RunState of the result, which indicates
\r
99 /// whether or not it has executed and why.
\r
101 public RunState RunState
\r
103 get { return runState; }
\r
104 set { runState = value; }
\r
108 /// Gets the ResultState of the test result, which
\r
109 /// indicates the success or failure of the test.
\r
111 public ResultState ResultState
\r
113 get { return resultState; }
\r
117 /// Gets the stage of the test in which a failure
\r
118 /// or error occured.
\r
120 public FailureSite FailureSite
\r
122 get { return failureSite; }
\r
126 /// Indicates whether the test executed
\r
128 public bool Executed
\r
130 get { return runState == RunState.Executed; }
\r
134 /// Gets the name of the test result
\r
136 public virtual string Name
\r
138 get { return name; }
\r
142 /// Gets the test associated with this result
\r
146 get { return test; }
\r
150 /// Indicates whether the test ran successfully
\r
152 public virtual bool IsSuccess
\r
154 // TODO: Redefine this more precisely
\r
155 get { return !IsFailure; }
\r
156 //get { return resultState == ResultState.Success; }
\r
160 /// Indicates whether the test failed
\r
162 // TODO: Distinguish errors from failures
\r
163 public virtual bool IsFailure
\r
165 get { return resultState == ResultState.Failure || resultState == ResultState.Error; }
\r
169 /// Gets a description associated with the test
\r
171 public virtual string Description
\r
173 get { return description; }
\r
174 set { description = value; }
\r
178 /// Gets the elapsed time for running the test
\r
182 get { return time; }
\r
183 set { time = value; }
\r
187 /// Gets the message associated with a test
\r
188 /// failure or with not running the test
\r
190 public string Message
\r
192 get { return messageString; }
\r
196 /// Gets any stacktrace associated with an
\r
197 /// error or failure.
\r
199 public virtual string StackTrace
\r
207 stackTrace = value;
\r
212 /// Gets or sets the count of asserts executed
\r
213 /// when running the test.
\r
215 public int AssertCount
\r
217 get { return assertCount; }
\r
218 set { assertCount = value; }
\r
223 #region Public Methods
\r
225 /// Mark the test as succeeding
\r
227 public void Success()
\r
229 this.runState = RunState.Executed;
\r
230 this.resultState = ResultState.Success;
\r
234 /// Mark the test as ignored.
\r
236 /// <param name="reason">The reason the test was not run</param>
\r
237 public void Ignore(string reason)
\r
239 Ignore( reason, null );
\r
243 /// Mark the test as ignored.
\r
245 /// <param name="ex">The ignore exception that was thrown</param>
\r
246 public void Ignore( Exception ex )
\r
248 Ignore( ex.Message, BuildStackTrace( ex ) );
\r
252 /// Mark the test as ignored.
\r
254 /// <param name="reason">The reason the test was not run</param>
\r
255 /// <param name="stackTrace">Stack trace giving the location of the command</param>
\r
256 public void Ignore(string reason, string stackTrace)
\r
258 NotRun( RunState.Ignored, reason, stackTrace );
\r
262 /// Mark the test as skipped.
\r
264 /// <param name="reason">The reason the test was not run</param>
\r
265 public void Skip(string reason)
\r
267 Skip( reason, null );
\r
271 /// Mark the test as ignored.
\r
273 /// <param name="ex">The ignore exception that was thrown</param>
\r
274 public void Skip( Exception ex )
\r
276 Skip( ex.Message, BuildStackTrace( ex ) );
\r
280 /// Mark the test as skipped.
\r
282 /// <param name="reason">The reason the test was not run</param>
\r
283 /// <param name="stackTrace">Stack trace giving the location of the command</param>
\r
284 public void Skip(string reason, string stackTrace)
\r
286 NotRun( RunState.Skipped, reason, stackTrace );
\r
290 /// Mark the test as Not Run - either skipped or ignored
\r
292 /// <param name="runState">The RunState to use in the result</param>
\r
293 /// <param name="reason">The reason the test was not run</param>
\r
294 /// <param name="stackTrace">Stack trace giving the location of the command</param>
\r
295 public void NotRun(RunState runState, string reason, string stackTrace)
\r
297 this.runState = runState;
\r
298 this.messageString = reason;
\r
299 this.stackTrace = stackTrace;
\r
304 /// Mark the test as a failure due to an
\r
305 /// assertion having failed.
\r
307 /// <param name="message">Message to display</param>
\r
308 /// <param name="stackTrace">Stack trace giving the location of the failure</param>
\r
309 public void Failure(string message, string stackTrace)
\r
311 Failure(message, stackTrace, FailureSite.Test);
\r
315 /// Mark the test as a failure due to an
\r
316 /// assertion having failed.
\r
318 /// <param name="message">Message to display</param>
\r
319 /// <param name="stackTrace">Stack trace giving the location of the failure</param>
\r
320 /// <param name="failureSite">The site of the failure</param>
\r
321 public void Failure(string message, string stackTrace, FailureSite failureSite )
\r
323 this.runState = RunState.Executed;
\r
324 this.resultState = ResultState.Failure;
\r
325 this.failureSite = failureSite;
\r
326 this.messageString = message;
\r
327 this.stackTrace = stackTrace;
\r
331 /// Marks the result as an error due to an exception thrown
\r
334 /// <param name="exception">The exception that was caught</param>
\r
335 public void Error(Exception exception)
\r
337 Error(exception, FailureSite.Test);
\r
341 /// Marks the result as an error due to an exception thrown
\r
342 /// from the indicated FailureSite.
\r
344 /// <param name="exception">The exception that was caught</param>
\r
345 /// <param name="failureSite">The site from which it was thrown</param>
\r
346 public void Error( Exception exception, FailureSite failureSite )
\r
348 this.runState = RunState.Executed;
\r
349 this.resultState = ResultState.Error;
\r
350 this.failureSite = failureSite;
\r
352 string message = BuildMessage(exception);
\r
353 string stackTrace = BuildStackTrace(exception);
\r
355 if (failureSite == FailureSite.TearDown)
\r
357 message = "TearDown : " + message;
\r
358 stackTrace = "--TearDown" + Environment.NewLine + stackTrace;
\r
360 if (this.messageString != null)
\r
361 message = this.messageString + Environment.NewLine + message;
\r
362 if (this.stackTrace != null)
\r
363 stackTrace = this.stackTrace + Environment.NewLine + stackTrace;
\r
366 this.messageString = message;
\r
367 this.stackTrace = stackTrace;
\r
371 #region Exception Helpers
\r
373 private string BuildMessage(Exception exception)
\r
375 StringBuilder sb = new StringBuilder();
\r
376 sb.AppendFormat( "{0} : {1}", exception.GetType().ToString(), exception.Message );
\r
378 Exception inner = exception.InnerException;
\r
379 while( inner != null )
\r
381 sb.Append( Environment.NewLine );
\r
382 sb.AppendFormat( " ----> {0} : {1}", inner.GetType().ToString(), inner.Message );
\r
383 inner = inner.InnerException;
\r
386 return sb.ToString();
\r
389 private string BuildStackTrace(Exception exception)
\r
391 StringBuilder sb = new StringBuilder( GetStackTrace( exception ) );
\r
393 Exception inner = exception.InnerException;
\r
394 while( inner != null )
\r
396 sb.Append( Environment.NewLine );
\r
398 sb.Append( inner.GetType().Name );
\r
399 sb.Append( Environment.NewLine );
\r
400 sb.Append( GetStackTrace( inner ) );
\r
402 inner = inner.InnerException;
\r
405 return sb.ToString();
\r
408 private string GetStackTrace(Exception exception)
\r
412 return exception.StackTrace;
\r
416 return "No stack trace available";
\r
423 /// Abstract method that accepts a ResultVisitor
\r
425 /// <param name="visitor">The visitor</param>
\r
426 public abstract void Accept(ResultVisitor visitor);
\r