retag
[mcs.git] / nunit24 / ClientUtilities / util / AggregatingTestRunner.cs
blob9c31805a2fc4d9f4d4e03750474a8c613c28e1ee
1 // ****************************************************************
2 // Copyright 2007, Charlie Poole
3 // This is free software licensed under the NUnit license. You may
4 // obtain a copy of the license at http://nunit.org/?p=license&r=2.4
5 // ****************************************************************
7 //#define RUN_IN_PARALLEL
9 namespace NUnit.Util
11 using System;
12 using System.Collections;
13 using System.IO;
14 using NUnit.Core;
16 /// <summary>
17 /// AggregatingTestRunner allows running multiple TestRunners
18 /// and combining the results.
19 /// </summary>
20 public abstract class AggregatingTestRunner : MarshalByRefObject, TestRunner, EventListener
22 static int AggregateTestID = 1000;
24 #region Instance Variables
26 /// <summary>
27 /// Our runner ID
28 /// </summary>
29 protected int runnerID;
31 /// <summary>
32 /// The downstream TestRunners
33 /// </summary>
34 protected ArrayList runners;
36 /// <summary>
37 /// The loaded test suite
38 /// </summary>
39 protected TestNode aggregateTest;
41 /// <summary>
42 /// The result of the last run
43 /// </summary>
44 private TestResult testResult;
46 /// <summary>
47 /// The event listener for the currently running test
48 /// </summary>
49 protected EventListener listener;
51 protected string projectName;
53 protected TestName testName;
55 #endregion
57 #region Constructors
58 public AggregatingTestRunner() : this( 0 ) { }
59 public AggregatingTestRunner( int runnerID )
61 this.runnerID = runnerID;
62 this.testName = new TestName();
63 testName.TestID = new TestID( AggregateTestID );
64 testName.RunnerID = this.runnerID;
65 testName.FullName = testName.Name = "Not Loaded";
67 #endregion
69 #region Properties
71 public virtual int ID
73 get { return runnerID; }
76 public virtual bool Running
78 get
80 foreach( TestRunner runner in runners )
81 if ( runner.Running )
82 return true;
84 return false;
88 public virtual IList AssemblyInfo
90 get
92 ArrayList info = new ArrayList();
93 foreach( TestRunner runner in runners )
94 info.AddRange( runner.AssemblyInfo );
95 return info;
99 public virtual ITest Test
103 if ( aggregateTest == null && runners != null )
105 // Count non-null tests, in case we specified a fixture
106 int count = 0;
107 foreach( TestRunner runner in runners )
108 if ( runner.Test != null )
109 ++count;
111 // Copy non-null tests to an array
112 int index = 0;
113 ITest[] tests = new ITest[count];
114 foreach( TestRunner runner in runners )
115 if ( runner.Test != null )
116 tests[index++] = runner.Test;
118 // Return master node containing all the tests
119 aggregateTest = new TestNode( testName, tests );
122 return aggregateTest;
126 public virtual TestResult TestResult
128 get { return testResult; }
130 #endregion
132 #region Load and Unload Methods
133 public abstract bool Load(TestPackage package);
135 public virtual void Unload()
137 foreach( TestRunner runner in runners )
138 runner.Unload();
139 aggregateTest = null;
141 #endregion
143 #region CountTestCases
144 public virtual int CountTestCases( ITestFilter filter )
146 int count = 0;
147 foreach( TestRunner runner in runners )
148 count += runner.CountTestCases( filter );
149 return count;
151 #endregion
153 #region Methods for Running Tests
154 public virtual TestResult Run( EventListener listener )
156 return Run( listener, TestFilter.Empty );
159 public virtual TestResult Run(EventListener listener, ITestFilter filter )
161 // Save active listener for derived classes
162 this.listener = listener;
164 ITest[] tests = new ITest[runners.Count];
165 for( int index = 0; index < runners.Count; index++ )
166 tests[index] = ((TestRunner)runners[index]).Test;
168 this.listener.RunStarted( this.Test.TestName.Name, this.CountTestCases( filter ) );
170 this.listener.SuiteStarted( this.Test.TestName );
171 long startTime = DateTime.Now.Ticks;
173 TestSuiteResult result = new TestSuiteResult( new TestInfo( testName, tests ), projectName );
174 result.RunState = RunState.Executed;
175 foreach( TestRunner runner in runners )
176 if ( filter.Pass( runner.Test ) )
177 result.AddResult( runner.Run( this, filter ) );
179 long stopTime = DateTime.Now.Ticks;
180 double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond;
181 result.Time = time;
183 this.listener.SuiteFinished( result );
185 this.listener.RunFinished( result );
187 this.testResult = result;
189 return result;
192 public virtual void BeginRun( EventListener listener )
194 BeginRun( listener, TestFilter.Empty );
197 public virtual void BeginRun( EventListener listener, ITestFilter filter )
199 // Save active listener for derived classes
200 this.listener = listener;
202 #if RUN_IN_PARALLEL
203 this.listener.RunStarted( this.Test.Name, this.CountTestCases( filter ) );
205 foreach( TestRunner runner in runners )
206 if ( runner.Test != null )
207 runner.BeginRun( this, filter );
209 //this.listener.RunFinished( this.Results );
210 #else
211 ThreadedTestRunner threadedRunner = new ThreadedTestRunner( this );
212 threadedRunner.BeginRun( listener, filter );
213 #endif
216 public virtual TestResult EndRun()
218 TestSuiteResult suiteResult = new TestSuiteResult( aggregateTest, Test.TestName.FullName );
219 foreach( TestRunner runner in runners )
220 suiteResult.Results.Add( runner.EndRun() );
222 return suiteResult;
225 public virtual void CancelRun()
227 foreach( TestRunner runner in runners )
228 runner.CancelRun();
231 public virtual void Wait()
233 foreach( TestRunner runner in runners )
234 runner.Wait();
236 #endregion
238 #region EventListener Members
239 public void TestStarted(TestName testName)
241 this.listener.TestStarted( testName );
244 public void RunStarted(string name, int testCount)
246 // TODO: We may want to count how many runs are started
247 // Ignore - we provide our own
250 public void RunFinished(Exception exception)
252 // Ignore - we provide our own
255 void NUnit.Core.EventListener.RunFinished(TestResult result)
257 // TODO: Issue combined RunFinished when all runs are done
260 public void SuiteFinished(TestSuiteResult result)
262 this.listener.SuiteFinished( result );
265 public void TestFinished(TestCaseResult result)
267 this.listener.TestFinished( result );
270 public void UnhandledException(Exception exception)
272 this.listener.UnhandledException( exception );
275 public void TestOutput(TestOutput testOutput)
277 this.listener.TestOutput( testOutput );
280 public void SuiteStarted(TestName suiteName)
282 this.listener.SuiteStarted( suiteName );
284 #endregion
286 #region InitializeLifetimeService Override
287 public override object InitializeLifetimeService()
289 return null;
291 #endregion