diff --git a/src/NUnitFramework/framework/TestContext.cs b/src/NUnitFramework/framework/TestContext.cs
index f8ce17a579..228d975d7a 100644
--- a/src/NUnitFramework/framework/TestContext.cs
+++ b/src/NUnitFramework/framework/TestContext.cs
@@ -1,8 +1,10 @@
// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt
using System;
+using System.Collections;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Reflection;
using System.Threading;
using NUnit.Framework.Constraints;
@@ -345,7 +347,7 @@ public static void WriteLine(string format, params object?[] args)
}
///
- /// This method adds the a new ValueFormatterFactory to the
+ /// This method adds a new ValueFormatterFactory to the
/// chain of responsibility used for formatting values in messages.
/// The scope of the change is the current TestContext.
///
@@ -482,9 +484,86 @@ public TestAdapter(Test test)
///
/// The expected result if there is one for the test
///
- public object? ExpectedResult
+ public object? ExpectedResult => (_test as TestMethod)?.ExpectedResult;
+
+ ///
+ /// The parent of this test or suite
+ ///
+ public ITest? Parent => _test.Parent;
+
+ ///
+ /// Returns all properties in the hierarchy
+ ///
+ ///
+ public IDictionary PropertyHierarchy()
+ {
+ var dict = new Dictionary();
+ ITest? test = _test;
+ do
+ {
+ foreach (var property in test.Properties.Keys)
+ {
+ var values = test.Properties[property];
+ dict.Add(new PropertyHierachyItem(property, test.Name ?? string.Empty), values);
+ }
+ test = test.Parent;
+ }
+ while (test is not null);
+
+ return dict;
+ }
+
+ ///
+ /// Returns all values of a given property
+ ///
+ /// Name of property
+ public IEnumerable AllPropertyValues(string property)
+ {
+ var list = new List();
+ var props = PropertyHierarchy();
+ foreach (var item in props.Keys.Where(o => o.Name == property))
+ {
+ var values = props[item];
+ foreach (var o in values)
+ list.Add(o);
+ }
+
+ return list.Distinct();
+ }
+
+ ///
+ /// Returns all categories in the hierarchy
+ ///
+ ///
+ public IDictionary> CategoryHierarchy()
+ {
+ var dict = new Dictionary>();
+ var all = PropertyHierarchy();
+ foreach (var property in all.Where(o => o.Key.Name == "Category"))
+ {
+ var values = new List();
+ foreach (var item in property.Value)
+ {
+ string s = item?.ToString() ?? string.Empty;
+ values.Add(s);
+ }
+ dict.Add(property.Key.Level, values);
+ }
+ return dict;
+ }
+ ///
+ /// Return all categories in the hierarchy flattened
+ ///
+ public IEnumerable AllCategories()
{
- get { return (_test as TestMethod)?.ExpectedResult; }
+ var cats = new List();
+ var lists = CategoryHierarchy().Values;
+ foreach (var list in lists)
+ {
+ cats.AddRange(list);
+ }
+
+ return cats.Distinct();
}
#endregion
@@ -492,6 +571,42 @@ public object? ExpectedResult
#endregion
+ #region PropertyHierachyItem
+ ///
+ /// Represents properties at different test levels
+ ///
+ public class PropertyHierachyItem
+ {
+ ///
+ /// Property with empty name and level.
+ ///
+ public PropertyHierachyItem()
+ {
+ }
+
+ ///
+ /// Property with given name and level.
+ ///
+ ///
+ ///
+ public PropertyHierachyItem(string name, string level)
+ {
+ Name = name;
+ Level = level;
+ }
+ ///
+ /// Name of propertyHierarchyItem
+ ///
+ public string Name { get; } = string.Empty;
+
+ ///
+ /// Name of test level, from ITest
+ ///
+ public string Level { get; } = string.Empty;
+ }
+
+ #endregion
+
#region Nested ResultAdapter Class
///
diff --git a/src/NUnitFramework/tests/TestContextTests.cs b/src/NUnitFramework/tests/TestContextTests.cs
index f1f6e191aa..59901ab1db 100644
--- a/src/NUnitFramework/tests/TestContextTests.cs
+++ b/src/NUnitFramework/tests/TestContextTests.cs
@@ -243,7 +243,7 @@ public void TestCanAccessAssertionResults(string testName, params AssertionStatu
{
AssertionResultFixture fixture = new AssertionResultFixture();
TestBuilder.RunTestCase(fixture, testName);
- var assertions = fixture.Assertions;
+ var assertions = fixture.Assertions?.ToList();
Assert.That(assertions, Is.Not.Null);
Assert.That(assertions.Select((o) => o.Status),
@@ -265,8 +265,10 @@ public void TestCanAccessTestState_PassingTest()
[Test]
public void TestCanAccessTestState_FailureInSetUp()
{
- TestStateRecordingFixture fixture = new TestStateRecordingFixture();
- fixture.SetUpFailure = true;
+ TestStateRecordingFixture fixture = new TestStateRecordingFixture
+ {
+ SetUpFailure = true
+ };
TestBuilder.RunTestFixture(fixture);
Assert.That(fixture.StateList, Is.EqualTo("Inconclusive=>=>Failed"));
}
@@ -274,8 +276,10 @@ public void TestCanAccessTestState_FailureInSetUp()
[Test]
public void TestCanAccessTestState_FailingTest()
{
- TestStateRecordingFixture fixture = new TestStateRecordingFixture();
- fixture.TestFailure = true;
+ TestStateRecordingFixture fixture = new TestStateRecordingFixture
+ {
+ TestFailure = true
+ };
TestBuilder.RunTestFixture(fixture);
Assert.That(fixture.StateList, Is.EqualTo("Inconclusive=>Inconclusive=>Failed"));
}
@@ -283,8 +287,10 @@ public void TestCanAccessTestState_FailingTest()
[Test]
public void TestCanAccessTestState_IgnoredInSetUp()
{
- TestStateRecordingFixture fixture = new TestStateRecordingFixture();
- fixture.SetUpIgnore = true;
+ TestStateRecordingFixture fixture = new TestStateRecordingFixture
+ {
+ SetUpIgnore = true
+ };
TestBuilder.RunTestFixture(fixture);
Assert.That(fixture.StateList, Is.EqualTo("Inconclusive=>=>Skipped:Ignored"));
}
@@ -425,12 +431,12 @@ public void TestCanAccessCurrentRepeatCount()
[TestFixture]
public class TestContextTearDownTests
{
- private const int THE_MEANING_OF_LIFE = 42;
+ private const int TheMeaningOfLife = 42;
[Test]
public void TestTheMeaningOfLife()
{
- Assert.That(THE_MEANING_OF_LIFE, Is.EqualTo(42));
+ Assert.That(TheMeaningOfLife, Is.EqualTo(42));
}
[TearDown]
@@ -484,4 +490,41 @@ public void OneTimeTearDown()
Assert.That(context.Result.SkipCount, Is.EqualTo(1));
}
}
+
+ [TestFixture]
+ [Category("CatA")]
+ [Property("Whatever", "Hi")]
+ public class TestContextHierarchies
+ {
+ [Test, Category("CatB")]
+ public void TestAb()
+ {
+ var test = TestContext.CurrentContext.Test;
+ Assert.That(test.AllCategories().ToList(), Has.Count.EqualTo(2));
+ Assert.That(test.AllPropertyValues("Whatever").ToList(), Has.Count.EqualTo(1));
+ Assert.That(test.AllPropertyValues("Whatever").First(), Is.EqualTo("Hi"));
+ }
+
+ [Test, Category("CatC")]
+ public void TestAc()
+ {
+ var test = TestContext.CurrentContext.Test;
+ Assert.That(test.AllCategories().ToList(), Has.Count.EqualTo(2));
+ }
+
+ [Test, Category("CatA")]
+ public void TestAa()
+ {
+ var test = TestContext.CurrentContext.Test;
+ Assert.That(test.AllCategories().ToList(), Has.Count.EqualTo(1));
+ }
+
+ [Test, Property("Whatever", "Ok")]
+ public void TestProps()
+ {
+ var test = TestContext.CurrentContext.Test;
+ Assert.That(test.AllPropertyValues("Whatever").ToList(), Has.Count.EqualTo(2));
+ Assert.That(test.AllCategories().ToList(), Has.Count.EqualTo(1));
+ }
+ }
}