PageRenderTime 34ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/NUnit-2.5.7.10213/src/NUnitCore/core/TestMethod.cs

http://github.com/shouldly/shouldly
C# | 403 lines | 292 code | 64 blank | 47 comment | 48 complexity | b025a2725db4001d3360ddb64331dabe MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  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. namespace NUnit.Core
  7. {
  8. using System;
  9. using System.Collections;
  10. using System.Runtime.Remoting.Messaging;
  11. using System.Threading;
  12. using System.Text;
  13. using System.Text.RegularExpressions;
  14. using System.Reflection;
  15. /// <summary>
  16. /// The TestMethod class represents a Test implemented as a method.
  17. ///
  18. /// Because of how exceptions are handled internally, this class
  19. /// must incorporate processing of expected exceptions. A change to
  20. /// the Test interface might make it easier to process exceptions
  21. /// in an object that aggregates a TestMethod in the future.
  22. /// </summary>
  23. public abstract class TestMethod : Test
  24. {
  25. static Logger log = InternalTrace.GetLogger(typeof(TestMethod));
  26. static ContextDictionary context;
  27. #region Fields
  28. /// <summary>
  29. /// The test method
  30. /// </summary>
  31. internal MethodInfo method;
  32. /// <summary>
  33. /// The SetUp method.
  34. /// </summary>
  35. protected MethodInfo[] setUpMethods;
  36. /// <summary>
  37. /// The teardown method
  38. /// </summary>
  39. protected MethodInfo[] tearDownMethods;
  40. /// <summary>
  41. /// The ExpectedExceptionProcessor for this test, if any
  42. /// </summary>
  43. internal ExpectedExceptionProcessor exceptionProcessor;
  44. /// <summary>
  45. /// Arguments to be used in invoking the method
  46. /// </summary>
  47. internal object[] arguments;
  48. /// <summary>
  49. /// The expected result of the method return value
  50. /// </summary>
  51. internal object expectedResult;
  52. /// <summary>
  53. /// Indicates whether expectedResult was set - thereby allowing null as a value
  54. /// </summary>
  55. internal bool hasExpectedResult;
  56. /// <summary>
  57. /// The fixture object, if it has been created
  58. /// </summary>
  59. private object fixture;
  60. private Exception builderException;
  61. #endregion
  62. #region Constructors
  63. public TestMethod( MethodInfo method )
  64. : base( method.ReflectedType.FullName, method.Name )
  65. {
  66. if( method.DeclaringType != method.ReflectedType)
  67. this.TestName.Name = method.DeclaringType.Name + "." + method.Name;
  68. this.method = method;
  69. }
  70. #endregion
  71. #region Static Properties
  72. private static ContextDictionary Context
  73. {
  74. get
  75. {
  76. if (context==null)
  77. {
  78. context = new ContextDictionary();
  79. }
  80. return context;
  81. }
  82. }
  83. #endregion
  84. #region Properties
  85. public override string TestType
  86. {
  87. get { return "TestMethod"; }
  88. }
  89. public MethodInfo Method
  90. {
  91. get { return method; }
  92. }
  93. public override Type FixtureType
  94. {
  95. get { return method.ReflectedType; }
  96. }
  97. public ExpectedExceptionProcessor ExceptionProcessor
  98. {
  99. get { return exceptionProcessor; }
  100. set { exceptionProcessor = value; }
  101. }
  102. public bool ExceptionExpected
  103. {
  104. get { return exceptionProcessor != null; }
  105. }
  106. public override object Fixture
  107. {
  108. get { return fixture; }
  109. set { fixture = value; }
  110. }
  111. public int Timeout
  112. {
  113. get
  114. {
  115. return Properties.Contains("Timeout")
  116. ? (int)Properties["Timeout"]
  117. : TestContext.TestCaseTimeout;
  118. }
  119. }
  120. public Exception BuilderException
  121. {
  122. get { return builderException; }
  123. set { builderException = value; }
  124. }
  125. #endregion
  126. #region Run Methods
  127. public override TestResult Run(EventListener listener, ITestFilter filter)
  128. {
  129. using (new TestContext())
  130. {
  131. TestResult testResult = new TestResult(this);
  132. ContextDictionary context = Context;
  133. context._testResult = testResult;
  134. context["TestName"] = this.TestName.Name;
  135. context["Properties"] = this.Properties;
  136. CallContext.SetData("NUnit.Framework.TestContext", context);
  137. log.Debug("Test Starting: " + this.TestName.FullName);
  138. listener.TestStarted(this.TestName);
  139. long startTime = DateTime.Now.Ticks;
  140. switch (this.RunState)
  141. {
  142. case RunState.Runnable:
  143. case RunState.Explicit:
  144. Run(testResult);
  145. break;
  146. case RunState.Skipped:
  147. default:
  148. testResult.Skip(IgnoreReason);
  149. break;
  150. case RunState.NotRunnable:
  151. if (BuilderException != null)
  152. testResult.Invalid(BuilderException);
  153. else
  154. testResult.Invalid(IgnoreReason);
  155. break;
  156. case RunState.Ignored:
  157. testResult.Ignore(IgnoreReason);
  158. break;
  159. }
  160. long stopTime = DateTime.Now.Ticks;
  161. double time = ((double)(stopTime - startTime)) / (double)TimeSpan.TicksPerSecond;
  162. testResult.Time = time;
  163. listener.TestFinished(testResult);
  164. return testResult;
  165. }
  166. }
  167. public virtual void Run(TestResult testResult)
  168. {
  169. try
  170. {
  171. if (this.Parent != null)
  172. {
  173. this.Fixture = this.Parent.Fixture;
  174. TestSuite suite = this.Parent as TestSuite;
  175. if (suite != null)
  176. {
  177. this.setUpMethods = suite.GetSetUpMethods();
  178. this.tearDownMethods = suite.GetTearDownMethods();
  179. }
  180. }
  181. // Temporary... to allow for tests that directly execute a test case
  182. if (Fixture == null && !method.IsStatic)
  183. Fixture = Reflect.Construct(this.FixtureType);
  184. if (this.Properties["_SETCULTURE"] != null)
  185. TestContext.CurrentCulture =
  186. new System.Globalization.CultureInfo((string)Properties["_SETCULTURE"]);
  187. if (this.Properties["_SETUICULTURE"] != null)
  188. TestContext.CurrentUICulture =
  189. new System.Globalization.CultureInfo((string)Properties["_SETUICULTURE"]);
  190. int repeatCount = this.Properties.Contains("Repeat")
  191. ? (int)this.Properties["Repeat"] : 1;
  192. while (repeatCount-- > 0)
  193. {
  194. if (RequiresThread || Timeout > 0 || ApartmentState != GetCurrentApartment())
  195. new TestMethodThread(this).Run(testResult, NullListener.NULL, TestFilter.Empty);
  196. else
  197. doRun(testResult);
  198. if (testResult.ResultState == ResultState.Failure ||
  199. testResult.ResultState == ResultState.Error ||
  200. testResult.ResultState == ResultState.Cancelled)
  201. {
  202. break;
  203. }
  204. }
  205. }
  206. catch (Exception ex)
  207. {
  208. if (ex is ThreadAbortException)
  209. Thread.ResetAbort();
  210. RecordException(ex, testResult, FailureSite.Test);
  211. }
  212. finally
  213. {
  214. Fixture = null;
  215. }
  216. }
  217. /// <summary>
  218. /// The doRun method is used to run a test internally.
  219. /// It assumes that the caller is taking care of any
  220. /// TestFixtureSetUp and TestFixtureTearDown needed.
  221. /// </summary>
  222. /// <param name="testResult">The result in which to record success or failure</param>
  223. public virtual void doRun( TestResult testResult )
  224. {
  225. DateTime start = DateTime.Now;
  226. try
  227. {
  228. doSetUp();
  229. doTestCase( testResult );
  230. }
  231. catch(Exception ex)
  232. {
  233. // doTestCase handles its own exceptions so
  234. // if we're here it's a setup exception
  235. if (ex is ThreadAbortException)
  236. Thread.ResetAbort();
  237. RecordException(ex, testResult, FailureSite.SetUp);
  238. }
  239. finally
  240. {
  241. doTearDown( testResult );
  242. DateTime stop = DateTime.Now;
  243. TimeSpan span = stop.Subtract(start);
  244. testResult.Time = (double)span.Ticks / (double)TimeSpan.TicksPerSecond;
  245. if (testResult.IsSuccess && this.Properties.Contains("MaxTime"))
  246. {
  247. int elapsedTime = (int)Math.Round(testResult.Time * 1000.0);
  248. int maxTime = (int)this.Properties["MaxTime"];
  249. if (maxTime > 0 && elapsedTime > maxTime)
  250. testResult.Failure(
  251. string.Format("Elapsed time of {0}ms exceeds maximum of {1}ms",
  252. elapsedTime, maxTime),
  253. null);
  254. }
  255. }
  256. }
  257. #endregion
  258. #region Invoke Methods by Reflection, Recording Errors
  259. private void doSetUp()
  260. {
  261. if (setUpMethods != null)
  262. foreach( MethodInfo setUpMethod in setUpMethods )
  263. Reflect.InvokeMethod(setUpMethod, setUpMethod.IsStatic ? null : this.Fixture);
  264. }
  265. private void doTearDown( TestResult testResult )
  266. {
  267. try
  268. {
  269. if (tearDownMethods != null)
  270. {
  271. int index = tearDownMethods.Length;
  272. while (--index >= 0)
  273. Reflect.InvokeMethod(tearDownMethods[index], tearDownMethods[index].IsStatic ? null : this.Fixture);
  274. }
  275. }
  276. catch(Exception ex)
  277. {
  278. if ( ex is NUnitException )
  279. ex = ex.InnerException;
  280. // TODO: What about ignore exceptions in teardown?
  281. testResult.Error( ex,FailureSite.TearDown );
  282. }
  283. }
  284. private void doTestCase( TestResult testResult )
  285. {
  286. try
  287. {
  288. RunTestMethod(testResult);
  289. if (testResult.IsSuccess && exceptionProcessor != null)
  290. exceptionProcessor.ProcessNoException(testResult);
  291. }
  292. catch (Exception ex)
  293. {
  294. if (ex is ThreadAbortException)
  295. Thread.ResetAbort();
  296. if (exceptionProcessor == null)
  297. RecordException(ex, testResult, FailureSite.Test);
  298. else
  299. exceptionProcessor.ProcessException(ex, testResult);
  300. }
  301. }
  302. public virtual void RunTestMethod(TestResult testResult)
  303. {
  304. object fixture = this.method.IsStatic ? null : this.Fixture;
  305. object result = Reflect.InvokeMethod( this.method, fixture, this.arguments );
  306. if (this.hasExpectedResult)
  307. NUnitFramework.Assert.AreEqual(expectedResult, result);
  308. testResult.Success();
  309. }
  310. #endregion
  311. #region Record Info About An Exception
  312. protected virtual void RecordException( Exception exception, TestResult testResult, FailureSite failureSite )
  313. {
  314. if (exception is NUnitException)
  315. exception = exception.InnerException;
  316. testResult.SetResult(NUnitFramework.GetResultState(exception), exception, failureSite);
  317. }
  318. #endregion
  319. #region Inner Classes
  320. private class ContextDictionary : Hashtable
  321. {
  322. internal TestResult _testResult;
  323. public override object this[object key]
  324. {
  325. get
  326. {
  327. if ("State".Equals(key))
  328. return (int)_testResult.ResultState;
  329. return base[key];
  330. }
  331. set
  332. {
  333. base[key] = value;
  334. }
  335. }
  336. }
  337. #endregion
  338. }
  339. }