<PackageReference Include="NUnit" Version="4.3.1" />

TestContext

public class TestContext
Provide the context information of the current test. This is an adapter for the internal ExecutionContext class, hiding the internals from the user test.
using NUnit.Framework.Constraints; using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; using NUnit.Framework.Internal.Execution; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; namespace NUnit.Framework { [NullableContext(1)] [Nullable(0)] public class TestContext { [NullableContext(2)] [Nullable(0)] public class TestAdapter { [Nullable(1)] private readonly Test _test; [Nullable(1)] public string ID { [NullableContext(1)] get { return _test.Id; } } [Nullable(1)] public string Name { [NullableContext(1)] get { return _test.Name; } } public string Namespace => _test.TypeInfo?.Namespace; public string DisplayName => _test.TypeInfo?.GetDisplayName(); public string MethodName => (_test as TestMethod)?.Method.Name; public IMethodInfo Method => (_test as TestMethod)?.Method; public Type Type => _test.TypeInfo?.Type; [Nullable(1)] public string FullName { [NullableContext(1)] get { return _test.FullName; } } public string ClassName => _test.ClassName; [Nullable(1)] public PropertyBagAdapter Properties { [NullableContext(1)] get { return new PropertyBagAdapter(_test.Properties); } } [Nullable(new byte[] { 1, 2 })] public object[] Arguments { [return: Nullable(new byte[] { 1, 2 })] get { return _test.Arguments; } } public object ExpectedResult => (_test as TestMethod)?.ExpectedResult; public ITest Parent => _test.Parent; [NullableContext(1)] public TestAdapter(Test test) { _test = test; } [NullableContext(1)] public IDictionary<PropertyHierachyItem, IList> PropertyHierarchy() { Dictionary<PropertyHierachyItem, IList> dictionary = new Dictionary<PropertyHierachyItem, IList>(); ITest test = _test; do { foreach (string key in test.Properties.Keys) { IList list = test.Properties[key]; if (list.Count > 0) dictionary.Add(new PropertyHierachyItem(key, test.Name ?? string.Empty), list); } test = test.Parent; } while (test != null); return dictionary; } [NullableContext(1)] private IList<PropertyValueHierarchyItem> PropertyValues(string property) { List<PropertyValueHierarchyItem> list = new List<PropertyValueHierarchyItem>(); ITest test = _test; do { IList propValues = test.Properties[property]; list.Add(new PropertyValueHierarchyItem(test.Name, propValues)); test = test.Parent; } while (test != null); return list; } [NullableContext(1)] public IEnumerable<object> AllPropertyValues(string property) { List<object> list = new List<object>(); IList<PropertyValueHierarchyItem> list2 = PropertyValues(property); foreach (PropertyValueHierarchyItem item in list2) { list.AddRange((IEnumerable<object>)item.Values); } return list.Distinct(); } [NullableContext(1)] public IEnumerable<string> AllCategories() { return (from o in AllPropertyValues("Category") select (string)o).ToList(); } } [Nullable(0)] public class PropertyHierachyItem { public string Name { get; } = string.Empty; public string Level { get; } = string.Empty; public PropertyHierachyItem() { } public PropertyHierachyItem(string name, string level) { Name = name; Level = level; } } [Nullable(0)] public class PropertyValueHierarchyItem { public IList Values { get; set; } public string Level { get; set; } public PropertyValueHierarchyItem(string testName, IList propValues) { Level = testName; Values = propValues; } } [Nullable(0)] public class ResultAdapter { private readonly TestResult _result; public ResultState Outcome => _result.ResultState; public IEnumerable<AssertionResult> Assertions => _result.AssertionResults; public string Message => _result.Message; [Nullable(2)] public virtual string StackTrace { [NullableContext(2)] get { return _result.StackTrace; } } public int FailCount => _result.FailCount; public int WarningCount => _result.WarningCount; public int PassCount => _result.PassCount; public int SkipCount => _result.SkipCount; public int InconclusiveCount => _result.InconclusiveCount; public ResultAdapter(TestResult result) { _result = result; } } [Nullable(0)] public class PropertyBagAdapter { private readonly IPropertyBag _source; public IEnumerable<object> this[string key] { get { if (_source.TryGet(key, out IList values)) { foreach (object item in values) { yield return item; } } } } public ICollection<string> Keys => _source.Keys; public PropertyBagAdapter(IPropertyBag source) { _source = source; } [return: Nullable(2)] public object Get(string key) { return _source.Get(key); } public bool ContainsKey(string key) { return _source.ContainsKey(key); } public int Count(string key) { if (!_source.TryGet(key, out IList values)) return 0; return values.Count; } } private readonly TestExecutionContext _testExecutionContext; [Nullable(2)] private TestAdapter _test; [Nullable(2)] private ResultAdapter _result; public static TextWriter Error = new EventListenerTextWriter("Error", Console.Error); public static readonly TextWriter Progress = new EventListenerTextWriter("Progress", Console.Error); public static readonly TestParameters Parameters = new TestParameters(); [Nullable(2)] internal static string DefaultWorkDirectory; public static TestContext CurrentContext => new TestContext(TestExecutionContext.CurrentContext); public static TextWriter Out => TestExecutionContext.CurrentContext.OutWriter; public TestAdapter Test => _test ?? (_test = new TestAdapter(_testExecutionContext.CurrentTest)); public ResultAdapter Result => _result ?? (_result = new ResultAdapter(_testExecutionContext.CurrentResult)); [Nullable(2)] public string WorkerId { [NullableContext(2)] get { return _testExecutionContext.TestWorker?.Name; } } public string TestDirectory { get { Assembly assembly = _testExecutionContext?.CurrentTest?.TypeInfo?.Assembly; if ((object)assembly != null) return AssemblyHelper.GetDirectoryName(assembly); return AssemblyHelper.GetDirectoryName(Assembly.GetCallingAssembly()); } } public string WorkDirectory { get { string defaultWorkDirectory = DefaultWorkDirectory; if (defaultWorkDirectory == null) throw new InvalidOperationException("TestContext.WorkDirectory must not be accessed before DefaultTestAssemblyBuilder.Build runs."); return defaultWorkDirectory; } } public Randomizer Random => _testExecutionContext.RandomGenerator; public int AssertCount => _testExecutionContext.AssertCount; public int CurrentRepeatCount => _testExecutionContext.CurrentRepeatCount; public CancellationToken CancellationToken => _testExecutionContext.CancellationToken; public TestContext(TestExecutionContext testExecutionContext) { _testExecutionContext = testExecutionContext; } public static void Write(bool value) { Out.Write(value); } public static void Write(char value) { Out.Write(value); } [NullableContext(2)] public static void Write(char[] value) { Out.Write(value); } public static void Write(double value) { Out.Write(value); } public static void Write(int value) { Out.Write(value); } public static void Write(long value) { Out.Write(value); } public static void Write(decimal value) { Out.Write(value); } [NullableContext(2)] public static void Write(object value) { Out.Write(value); } public static void Write(float value) { Out.Write(value); } [NullableContext(2)] public static void Write(string value) { Out.Write(value); } [CLSCompliant(false)] public static void Write(uint value) { Out.Write(value); } [CLSCompliant(false)] public static void Write(ulong value) { Out.Write(value); } public static void Write(string format, [Nullable(2)] object arg1) { Out.Write(format, arg1); } [NullableContext(2)] public static void Write([Nullable(1)] string format, object arg1, object arg2) { Out.Write(format, arg1, arg2); } [NullableContext(2)] public static void Write([Nullable(1)] string format, object arg1, object arg2, object arg3) { Out.Write(format, arg1, arg2, arg3); } public static void Write(string format, [Nullable(new byte[] { 1, 2 })] params object[] args) { Out.Write(format, args); } public static void WriteLine() { Out.WriteLine(); } public static void WriteLine(bool value) { Out.WriteLine(value); } public static void WriteLine(char value) { Out.WriteLine(value); } [NullableContext(2)] public static void WriteLine(char[] value) { Out.WriteLine(value); } public static void WriteLine(double value) { Out.WriteLine(value); } public static void WriteLine(int value) { Out.WriteLine(value); } public static void WriteLine(long value) { Out.WriteLine(value); } public static void WriteLine(decimal value) { Out.WriteLine(value); } [NullableContext(2)] public static void WriteLine(object value) { Out.WriteLine(value); } public static void WriteLine(float value) { Out.WriteLine(value); } [NullableContext(2)] public static void WriteLine(string value) { Out.WriteLine(value); } [CLSCompliant(false)] public static void WriteLine(uint value) { Out.WriteLine(value); } [CLSCompliant(false)] public static void WriteLine(ulong value) { Out.WriteLine(value); } public static void WriteLine(string format, [Nullable(2)] object arg1) { Out.WriteLine(format, arg1); } [NullableContext(2)] public static void WriteLine([Nullable(1)] string format, object arg1, object arg2) { Out.WriteLine(format, arg1, arg2); } [NullableContext(2)] public static void WriteLine([Nullable(1)] string format, object arg1, object arg2, object arg3) { Out.WriteLine(format, arg1, arg2, arg3); } public static void WriteLine(string format, [Nullable(new byte[] { 1, 2 })] params object[] args) { Out.WriteLine(format, args); } public static void AddFormatter(ValueFormatterFactory formatterFactory) { TestExecutionContext.CurrentContext.AddFormatter(formatterFactory); } public static void AddTestAttachment(string filePath, [Nullable(2)] string description = null) { Guard.ArgumentNotNull(filePath, "filePath"); Guard.ArgumentValid(filePath.IndexOfAny(Path.GetInvalidPathChars()) == -1, "Test attachment file path contains invalid path characters. " + filePath, "filePath"); if (!Path.IsPathRooted(filePath)) filePath = Path.Combine(CurrentContext.WorkDirectory, filePath); string empty = string.Empty; if (!File.Exists(empty + filePath)) throw new FileNotFoundException("Test attachment file path could not be found.", filePath); TestResult currentResult = TestExecutionContext.CurrentContext.CurrentResult; currentResult.AddTestAttachment(new TestAttachment(filePath, description)); } public static void AddFormatter<[Nullable(2)] TSupported>(ValueFormatter formatter) { AddFormatter((ValueFormatter next) => delegate(object val) { if (!(val is TSupported)) return next(val); return formatter(val); }); } } }