1 // ***********************************************************************
2 // Copyright (c) 2011 Charlie Poole
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
25 #define NUNIT_FRAMEWORK
30 using System.Collections.Generic;
32 using System.Reflection;
33 using NUnit.Framework.Constraints;
34 using NUnit.Framework.Interfaces;
35 using NUnit.Framework.Internal;
36 using NUnit.Framework.Internal.Execution;
38 namespace NUnit.Framework
41 /// Provide the context information of the current test.
42 /// This is an adapter for the internal ExecutionContext
43 /// class, hiding the internals from the user test.
45 public class TestContext
47 private readonly TestExecutionContext _testExecutionContext;
48 private TestAdapter _test;
49 private ResultAdapter _result;
54 /// Construct a TestContext for an ExecutionContext
56 /// <param name="testExecutionContext">The ExecutionContext to adapt</param>
57 public TestContext(TestExecutionContext testExecutionContext)
59 _testExecutionContext = testExecutionContext;
67 /// Get the current test context. This is created
68 /// as needed. The user may save the context for
69 /// use within a test, but it should not be used
70 /// outside the test for which it is created.
72 public static TestContext CurrentContext
74 get { return new TestContext(TestExecutionContext.CurrentContext); }
78 /// Gets a TextWriter that will send output to the current test result.
80 public static TextWriter Out
82 get { return TestExecutionContext.CurrentContext.OutWriter; }
85 #if !NETCF && !SILVERLIGHT && !PORTABLE
87 /// Gets a TextWriter that will send output directly to Console.Error
89 public static TextWriter Error = new EventListenerTextWriter("Error", Console.Error);
92 /// Gets a TextWriter for use in displaying immediate progress messages
94 public static readonly TextWriter Progress = new EventListenerTextWriter("Progress", Console.Error);
98 /// TestParameters object holds parameters for the test run, if any are specified
100 public static readonly TestParameters Parameters = new TestParameters();
103 /// Get a representation of the current test.
105 public TestAdapter Test
107 get { return _test ?? (_test = new TestAdapter(_testExecutionContext.CurrentTest)); }
111 /// Gets a Representation of the TestResult for the current test.
113 public ResultAdapter Result
115 get { return _result ?? (_result = new ResultAdapter(_testExecutionContext.CurrentResult)); }
119 /// Gets the unique name of the Worker that is executing this test.
121 public string WorkerId
123 get { return _testExecutionContext.WorkerId; }
126 #if !SILVERLIGHT && !PORTABLE
128 /// Gets the directory containing the current test assembly.
130 public string TestDirectory
134 Test test = _testExecutionContext.CurrentTest;
136 return AssemblyHelper.GetDirectoryName(test.TypeInfo.Assembly);
138 // Test is null, we may be loading tests rather than executing.
139 // Assume that calling assembly is the test assembly.
140 return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly());
147 /// Gets the directory to be used for outputting files created
148 /// by this test run.
150 public string WorkDirectory
152 get { return _testExecutionContext.WorkDirectory; }
156 /// Gets the random generator.
159 /// The random generator.
161 public Randomizer Random
163 get { return _testExecutionContext.RandomGenerator; }
168 #region Static Methods
170 /// <summary>Write the string representation of a boolean value to the current result</summary>
171 public static void Write(bool value) { Out.Write(value); }
173 /// <summary>Write a char to the current result</summary>
174 public static void Write(char value) { Out.Write(value); }
176 /// <summary>Write a char array to the current result</summary>
177 public static void Write(char[] value) { Out.Write(value); }
179 /// <summary>Write the string representation of a double to the current result</summary>
180 public static void Write(double value) { Out.Write(value); }
182 /// <summary>Write the string representation of an Int32 value to the current result</summary>
183 public static void Write(Int32 value) { Out.Write(value); }
185 /// <summary>Write the string representation of an Int64 value to the current result</summary>
186 public static void Write(Int64 value) { Out.Write(value); }
188 /// <summary>Write the string representation of a decimal value to the current result</summary>
189 public static void Write(decimal value) { Out.Write(value); }
191 /// <summary>Write the string representation of an object to the current result</summary>
192 public static void Write(object value) { Out.Write(value); }
194 /// <summary>Write the string representation of a Single value to the current result</summary>
195 public static void Write(Single value) { Out.Write(value); }
197 /// <summary>Write a string to the current result</summary>
198 public static void Write(string value) { Out.Write(value); }
200 /// <summary>Write the string representation of a UInt32 value to the current result</summary>
201 //[CLSCompliant(false)]
202 public static void Write(UInt32 value) { Out.Write(value); }
204 /// <summary>Write the string representation of a UInt64 value to the current result</summary>
205 //[CLSCompliant(false)]
206 public static void Write(UInt64 value) { Out.Write(value); }
208 /// <summary>Write a formatted string to the current result</summary>
209 public static void Write(string format, object arg1) { Out.Write(format, arg1); }
211 /// <summary>Write a formatted string to the current result</summary>
212 public static void Write(string format, object arg1, object arg2) { Out.Write(format, arg1, arg2); }
214 /// <summary>Write a formatted string to the current result</summary>
215 public static void Write(string format, object arg1, object arg2, object arg3) { Out.Write(format, arg1, arg2, arg3); }
217 /// <summary>Write a formatted string to the current result</summary>
218 public static void Write(string format, params object[] args) { Out.Write(format, args); }
220 /// <summary>Write a line terminator to the current result</summary>
221 public static void WriteLine() { Out.WriteLine(); }
223 /// <summary>Write the string representation of a boolean value to the current result followed by a line terminator</summary>
224 public static void WriteLine(bool value) { Out.WriteLine(value); }
226 /// <summary>Write a char to the current result followed by a line terminator</summary>
227 public static void WriteLine(char value) { Out.WriteLine(value); }
229 /// <summary>Write a char array to the current result followed by a line terminator</summary>
230 public static void WriteLine(char[] value) { Out.WriteLine(value); }
232 /// <summary>Write the string representation of a double to the current result followed by a line terminator</summary>
233 public static void WriteLine(double value) { Out.WriteLine(value); }
235 /// <summary>Write the string representation of an Int32 value to the current result followed by a line terminator</summary>
236 public static void WriteLine(Int32 value) { Out.WriteLine(value); }
238 /// <summary>Write the string representation of an Int64 value to the current result followed by a line terminator</summary>
239 public static void WriteLine(Int64 value) { Out.WriteLine(value); }
241 /// <summary>Write the string representation of a decimal value to the current result followed by a line terminator</summary>
242 public static void WriteLine(decimal value) { Out.WriteLine(value); }
244 /// <summary>Write the string representation of an object to the current result followed by a line terminator</summary>
245 public static void WriteLine(object value) { Out.WriteLine(value); }
247 /// <summary>Write the string representation of a Single value to the current result followed by a line terminator</summary>
248 public static void WriteLine(Single value) { Out.WriteLine(value); }
250 /// <summary>Write a string to the current result followed by a line terminator</summary>
251 public static void WriteLine(string value) { Out.WriteLine(value); }
253 /// <summary>Write the string representation of a UInt32 value to the current result followed by a line terminator</summary>
254 //[CLSCompliant(false)]
255 public static void WriteLine(UInt32 value) { Out.WriteLine(value); }
257 /// <summary>Write the string representation of a UInt64 value to the current result followed by a line terminator</summary>
258 //[CLSCompliant(false)]
259 public static void WriteLine(UInt64 value) { Out.WriteLine(value); }
261 /// <summary>Write a formatted string to the current result followed by a line terminator</summary>
262 public static void WriteLine(string format, object arg1) { Out.WriteLine(format, arg1); }
264 /// <summary>Write a formatted string to the current result followed by a line terminator</summary>
265 public static void WriteLine(string format, object arg1, object arg2) { Out.WriteLine(format, arg1, arg2); }
267 /// <summary>Write a formatted string to the current result followed by a line terminator</summary>
268 public static void WriteLine(string format, object arg1, object arg2, object arg3) { Out.WriteLine(format, arg1, arg2, arg3); }
270 /// <summary>Write a formatted string to the current result followed by a line terminator</summary>
271 public static void WriteLine(string format, params object[] args) { Out.WriteLine(format, args); }
274 /// This method adds the a new ValueFormatterFactory to the
275 /// chain of responsibility used for fomatting values in messages.
276 /// The scope of the change is the current TestContext.
278 /// <param name="formatterFactory">The factory delegate</param>
279 public static void AddFormatter(ValueFormatterFactory formatterFactory)
281 TestExecutionContext.CurrentContext.AddFormatter(formatterFactory);
285 /// This method provides a simplified way to add a ValueFormatter
286 /// delegate to the chain of responsibility, creating the factory
287 /// delegate internally. It is useful when the Type of the object
288 /// is the only criterion for selection of the formatter, since
289 /// it can be used without getting involved with a compould function.
291 /// <typeparam name="TSUPPORTED">The type supported by this formatter</typeparam>
292 /// <param name="formatter">The ValueFormatter delegate</param>
293 public static void AddFormatter<TSUPPORTED>(ValueFormatter formatter)
295 AddFormatter(next => val => (val is TSUPPORTED) ? formatter(val) : next(val));
300 #region Nested TestAdapter Class
303 /// TestAdapter adapts a Test for consumption by
304 /// the user test code.
306 public class TestAdapter
308 private readonly Test _test;
313 /// Construct a TestAdapter for a Test
315 /// <param name="test">The Test to be adapted</param>
316 public TestAdapter(Test test)
326 /// Gets the unique Id of a test
330 get { return _test.Id; }
334 /// The name of the test, which may or may not be
335 /// the same as the method name.
339 get { return _test.Name; }
343 /// The name of the method representing the test.
345 public string MethodName
349 return _test is TestMethod
356 /// The FullName of the test
358 public string FullName
360 get { return _test.FullName; }
364 /// The ClassName of the test
366 public string ClassName
368 get { return _test.ClassName; }
372 /// The properties of the test.
374 public IPropertyBag Properties
376 get { return _test.Properties; }
384 #region Nested ResultAdapter Class
387 /// ResultAdapter adapts a TestResult for consumption by
388 /// the user test code.
390 public class ResultAdapter
392 private readonly TestResult _result;
397 /// Construct a ResultAdapter for a TestResult
399 /// <param name="result">The TestResult to be adapted</param>
400 public ResultAdapter(TestResult result)
410 /// Gets a ResultState representing the outcome of the test.
412 public ResultState Outcome
414 get { return _result.ResultState; }
418 /// Gets the message associated with a test
419 /// failure or with not running the test
421 public string Message
423 get { return _result.Message; }
427 /// Gets any stacktrace associated with an
428 /// error or failure.
430 public virtual string StackTrace
432 get { return _result.StackTrace; }
436 /// Gets the number of test cases that failed
437 /// when running the test and all its children.
441 get { return _result.FailCount; }
445 /// Gets the number of test cases that passed
446 /// when running the test and all its children.
450 get { return _result.PassCount; }
454 /// Gets the number of test cases that were skipped
455 /// when running the test and all its children.
459 get { return _result.SkipCount; }
463 /// Gets the number of test cases that were inconclusive
464 /// when running the test and all its children.
466 public int InconclusiveCount
468 get { return _result.InconclusiveCount; }