PageRenderTime 16ms CodeModel.GetById 1ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/NUnit/interfaces/TestResult.cs

#
C# | 503 lines | 248 code | 64 blank | 191 comment | 32 complexity | 911b29b5604dc6a6f6a054c2a236ab6d MD5 | raw file
  1// ****************************************************************
  2// This is free software licensed under the NUnit license. You
  3// may obtain a copy of the license as well as information regarding
  4// copyright ownership at http://nunit.org.
  5// ****************************************************************
  6
  7namespace NUnit.Core
  8{
  9	using System;
 10	using System.Text;
 11	using System.Collections;
 12
 13	/// <summary>
 14	/// The TestResult class represents
 15	/// the result of a test and is used to
 16	/// communicate results across AppDomains.
 17	/// </summary>
 18	/// 
 19	[Serializable]
 20	public class TestResult
 21	{
 22		#region Fields
 23		/// <summary>
 24		/// Indicates the result of the test
 25		/// </summary>
 26		private ResultState resultState;
 27
 28		/// <summary>
 29		/// Indicates the location of a failure
 30		/// </summary>
 31        private FailureSite failureSite;
 32
 33		/// <summary>
 34		/// The elapsed time for executing this test
 35		/// </summary>
 36		private double time = 0.0;
 37
 38		/// <summary>
 39		/// The test that this result pertains to
 40		/// </summary>
 41		private readonly TestInfo test;
 42
 43		/// <summary>
 44		/// The stacktrace at the point of failure
 45		/// </summary>
 46		private string stackTrace;
 47
 48		/// <summary>
 49		/// Message giving the reason for failure
 50		/// </summary>
 51		private string message;
 52
 53		/// <summary>
 54		/// List of child results
 55		/// </summary>
 56		private IList results;
 57
 58		/// <summary>
 59		/// Number of asserts executed by this test
 60		/// </summary>
 61		private int assertCount = 0;
 62
 63		#endregion
 64
 65		#region Constructor
 66		/// <summary>
 67		/// Construct a test result given a TestInfo
 68		/// </summary>
 69		/// <param name="test">The test to be used</param>
 70		public TestResult(TestInfo test)
 71		{
 72			this.test = test;
 73			this.message = test.IgnoreReason;
 74		}
 75
 76        /// <summary>
 77        /// Construct a TestResult given an ITest
 78        /// </summary>
 79        /// <param name="test"></param>
 80        public TestResult(ITest test) : this( new TestInfo(test) ) { }
 81
 82		/// <summary>
 83		/// Construct a TestResult given a TestName
 84		/// </summary>
 85		/// <param name="testName">A TestName</param>
 86		public TestResult(TestName testName) : this( new TestInfo( testName ) ) { }
 87		#endregion
 88
 89        #region Properties
 90
 91		/// <summary>
 92		/// Gets the ResultState of the test result, which 
 93		/// indicates the success or failure of the test.
 94		/// </summary>
 95        public ResultState ResultState
 96        {
 97            get { return resultState; }
 98        }
 99
100		/// <summary>
101		/// Gets the stage of the test in which a failure
102		/// or error occured.
103		/// </summary>
104        public FailureSite FailureSite
105        {
106            get { return failureSite; }
107        }
108
109		/// <summary>
110		/// Indicates whether the test executed
111		/// </summary>
112        public bool Executed
113        {
114            get
115            {
116                return resultState == ResultState.Success ||
117                       resultState == ResultState.Failure ||
118                       resultState == ResultState.Error ||
119                       resultState == ResultState.Inconclusive;
120            }
121        }
122
123		/// <summary>
124		/// Gets the name of the test result
125		/// </summary>
126		public virtual string Name
127		{
128			get { return test.TestName.Name; }
129		}
130
131		/// <summary>
132		/// Gets the full name of the test result
133		/// </summary>
134		public virtual string FullName
135		{
136			get { return test.TestName.FullName; }
137		}
138
139		/// <summary>
140		/// Gets the test associated with this result
141		/// </summary>
142        public ITest Test
143        {
144            get { return test; }
145        }
146
147		/// <summary>
148		/// Indicates whether the test ran successfully
149		/// </summary>
150        public virtual bool IsSuccess
151        {
152            get { return resultState == ResultState.Success; }
153        }
154
155        /// <summary>
156        /// Indicates whether the test failed
157        /// </summary>
158        public virtual bool IsFailure
159        {
160            get { return resultState == ResultState.Failure;  }
161        }
162
163	    /// <summary>
164	    /// Indicates whether the test had an error (as opposed to a failure)
165	    /// </summary>
166        public virtual bool IsError
167	    {
168            get { return resultState == ResultState.Error;  }   
169	    }
170
171		/// <summary>
172		/// Gets a description associated with the test
173		/// </summary>
174        public string Description
175        {
176            get { return test.Description; }
177        }
178
179		/// <summary>
180		/// Gets the elapsed time for running the test
181		/// </summary>
182        public double Time
183        {
184            get { return time; }
185            set { time = value; }
186        }
187
188		/// <summary>
189		/// Gets the message associated with a test
190		/// failure or with not running the test
191		/// </summary>
192        public string Message
193        {
194            get { return message; }
195        }
196
197		/// <summary>
198		/// Gets any stacktrace associated with an
199		/// error or failure.
200		/// </summary>
201        public virtual string StackTrace
202        {
203            get { return stackTrace; }
204            set { stackTrace = value; }
205        }
206
207		/// <summary>
208		/// Gets or sets the count of asserts executed
209		/// when running the test.
210		/// </summary>
211        public int AssertCount
212        {
213            get { return assertCount; }
214            set { assertCount = value; }
215        }
216
217        /// <summary>
218        /// Return true if this result has any child results
219        /// </summary>
220	    public bool HasResults
221	    {
222            get { return results != null && results.Count > 0; }    
223	    }
224
225		/// <summary>
226		/// Gets a list of the child results of this TestResult
227		/// </summary>
228		public IList Results
229		{
230			get { return results; }
231		}
232
233		#endregion
234
235        #region Public Methods
236        /// <summary>
237        /// Mark the test as succeeding
238        /// </summary>
239        public void Success()
240        {
241            SetResult( ResultState.Success, null, null );
242        }
243
244        /// <summary>
245        /// Mark the test as succeeding and set a message
246        /// </summary>
247        public void Success( string message )
248        {
249            SetResult( ResultState.Success, message, null );
250        }
251
252        /// <summary>
253		/// Mark the test as ignored.
254		/// </summary>
255		/// <param name="reason">The reason the test was not run</param>
256		public void Ignore(string reason)
257		{
258			Ignore( reason, null );
259		}
260
261		/// <summary>
262		/// Mark the test as ignored.
263		/// </summary>
264		/// <param name="ex">The ignore exception that was thrown</param>
265		public void Ignore( Exception ex )
266		{
267			Ignore( ex.Message, BuildStackTrace( ex ) );
268		}
269
270		/// <summary>
271		/// Mark the test as ignored.
272		/// </summary>
273		/// <param name="reason">The reason the test was not run</param>
274		/// <param name="stackTrace">Stack trace giving the location of the command</param>
275		public void Ignore(string reason, string stackTrace)
276		{
277			SetResult( ResultState.Ignored, reason, stackTrace );
278		}
279
280		/// <summary>
281		/// Mark the test as skipped.
282		/// </summary>
283		/// <param name="reason">The reason the test was not run</param>
284        public void Skip(string reason)
285        {
286            SetResult(ResultState.Skipped, reason, null);
287        }
288
289        /// <summary>
290        /// Mark the test a not runnable with a reason
291        /// </summary>
292        /// <param name="reason">The reason the test is invalid</param>
293        public void Invalid( string reason )
294        {
295            SetResult( ResultState.NotRunnable, reason, null );
296        }
297
298        /// <summary>
299        /// Mark the test as not runnable due to a builder exception
300        /// </summary>
301        /// <param name="ex">The exception thrown by the builder or an addin</param>
302        public void Invalid(Exception ex)
303        {
304            SetResult(ResultState.NotRunnable, BuildMessage( ex ), BuildStackTrace(ex));
305        }
306
307	    /// <summary>
308		/// Set the result of the test
309		/// </summary>
310		/// <param name="resultState">The ResultState to use in the result</param>
311		/// <param name="reason">The reason the test was not run</param>
312        /// <param name="stackTrace">Stack trace giving the location of the command</param>
313        /// <param name="failureSite">The location of the failure, if any</param>
314        public void SetResult(ResultState resultState, string reason, string stackTrace, FailureSite failureSite)
315		{
316            if (failureSite == FailureSite.SetUp)
317                reason = "SetUp : " + reason;
318            else if (failureSite == FailureSite.TearDown)
319            {
320                reason = "TearDown : " + reason;
321                stackTrace = "--TearDown" + Environment.NewLine + stackTrace;
322
323                if (this.message != null)
324                    reason = this.message + Environment.NewLine + reason;
325                if (this.stackTrace != null)
326                    stackTrace = this.stackTrace + Environment.NewLine + stackTrace;
327            }
328
329            this.resultState = resultState;
330            this.message = reason;
331            this.stackTrace = stackTrace;
332            this.failureSite = failureSite;
333		}
334
335        /// <summary>
336        /// Set the result of the test
337        /// </summary>
338        /// <param name="resultState">The ResultState to use in the result</param>
339        /// <param name="reason">The reason the test was not run</param>
340        /// <param name="stackTrace">Stack trace giving the location of the command</param>
341        public void SetResult(ResultState resultState, string reason, string stackTrace)
342        {
343            SetResult(resultState, reason, stackTrace, FailureSite.Test);
344        }
345
346        /// <summary>
347        /// Set the result of the test.
348        /// </summary>
349        /// <param name="resultState">The ResultState to use in the result</param>
350        /// <param name="ex">The exception that caused this result</param>
351        /// <param name="failureSite">The site at which an error or failure occured</param>
352        public void SetResult(ResultState resultState, Exception ex, FailureSite failureSite)
353        {
354            if (resultState == ResultState.Cancelled)
355                SetResult(resultState, "Test cancelled by user", BuildStackTrace(ex));
356            else if (resultState == ResultState.Error)
357                SetResult( resultState, BuildMessage(ex), BuildStackTrace(ex), failureSite);
358            else
359                SetResult(resultState, ex.Message, ex.StackTrace, failureSite);
360        }
361   
362        /// <summary>
363		/// Mark the test as a failure due to an
364		/// assertion having failed.
365		/// </summary>
366		/// <param name="message">Message to display</param>
367		/// <param name="stackTrace">Stack trace giving the location of the failure</param>
368		public void Failure(string message, string stackTrace)
369        {
370            Failure(message, stackTrace, FailureSite.Test);
371        }
372
373		/// <summary>
374		/// Mark the test as a failure due to an
375		/// assertion having failed.
376		/// </summary>
377		/// <param name="message">Message to display</param>
378		/// <param name="stackTrace">Stack trace giving the location of the failure</param>
379		/// <param name="failureSite">The site of the failure</param>
380		public void Failure(string message, string stackTrace, FailureSite failureSite )
381		{
382            SetResult( Core.ResultState.Failure, message, stackTrace );
383            this.failureSite = failureSite;
384		}
385
386		/// <summary>
387		/// Marks the result as an error due to an exception thrown
388		/// by the test.
389		/// </summary>
390		/// <param name="exception">The exception that was caught</param>
391        public void Error(Exception exception)
392        {
393            Error(exception, FailureSite.Test);
394        }
395
396		/// <summary>
397		/// Marks the result as an error due to an exception thrown
398		/// from the indicated FailureSite.
399		/// </summary>
400		/// <param name="exception">The exception that was caught</param>
401        /// <param name="failureSite">The site from which it was thrown</param>
402        public void Error(Exception exception, FailureSite failureSite)
403		{
404            SetResult(ResultState.Error, exception, failureSite);
405            //string message = BuildMessage(exception);
406            //string stackTrace = BuildStackTrace(exception);
407
408            //if (failureSite == FailureSite.TearDown)
409            //{
410            //    message = "TearDown : " + message;
411            //    stackTrace = "--TearDown" + Environment.NewLine + stackTrace;
412
413            //    if (this.message != null)
414            //        message = this.message + Environment.NewLine + message;
415            //    if (this.stackTrace != null)
416            //        stackTrace = this.stackTrace + Environment.NewLine + stackTrace;
417            //}
418
419            //SetResult( ResultState.Error, message, stackTrace );
420            //this.failureSite = failureSite;
421        }
422
423		/// <summary>
424		/// Add a child result
425		/// </summary>
426		/// <param name="result">The child result to be added</param>
427		public void AddResult(TestResult result) 
428		{
429			if ( results == null )
430				results = new ArrayList();
431
432			this.results.Add(result);
433
434            switch (result.ResultState)
435            {
436                case ResultState.Failure:
437                case ResultState.Error:
438                    if (!this.IsFailure && !this.IsError)
439                        this.Failure("Child test failed", null, FailureSite.Child);
440                    break;
441                case ResultState.Success:
442                    if (this.ResultState == ResultState.Inconclusive)
443                        this.Success();
444                    break;
445                case ResultState.Cancelled:
446                    this.SetResult(ResultState.Cancelled, result.Message, null, FailureSite.Child);
447                    break;
448            }
449		}
450		#endregion
451
452		#region Exception Helpers
453
454		private static string BuildMessage(Exception exception)
455		{
456			StringBuilder sb = new StringBuilder();
457			sb.AppendFormat( "{0} : {1}", exception.GetType().ToString(), exception.Message );
458
459			Exception inner = exception.InnerException;
460			while( inner != null )
461			{
462				sb.Append( Environment.NewLine );
463				sb.AppendFormat( "  ----> {0} : {1}", inner.GetType().ToString(), inner.Message );
464				inner = inner.InnerException;
465			}
466
467			return sb.ToString();
468		}
469		
470		private static string BuildStackTrace(Exception exception)
471		{
472            StringBuilder sb = new StringBuilder( GetStackTrace( exception ) );
473
474            Exception inner = exception.InnerException;
475            while( inner != null )
476            {
477                sb.Append( Environment.NewLine );
478                sb.Append( "--" );
479                sb.Append( inner.GetType().Name );
480                sb.Append( Environment.NewLine );
481                sb.Append( GetStackTrace( inner ) );
482
483                inner = inner.InnerException;
484            }
485
486            return sb.ToString();
487		}
488
489		private static string GetStackTrace(Exception exception)
490		{
491			try
492			{
493				return exception.StackTrace;
494			}
495			catch( Exception )
496			{
497				return "No stack trace available";
498			}
499		}
500
501		#endregion
502	}
503}