Note that this is how the Rider and Resharper test UI's do it by default.
The below code is a simple real world example of why I really need this feature.
In practice, the nesting often gets much deeper than in this simple example, and the full test name without nesting may not even fit within the tests window on my monitor!
But even without that, compare trying to read these two:
What NCrunch does:
Code:
Assertion_library_specification+StringAssertion_method+NotNull_throws_for
null_string
Assertion_library_specification+StringAssertion_method+NotNullEmptyOrWhitespace_throws_for_
null_string
null_string
empty_string
spaces_string
tabs_string
newLine_string
What I want, and what Rider and ReSharper does:
Code:
Assertion_library_specification
StringAssertion_method
NotNull_throws_for
null_string
NotNullEmptyOrWhitespace_throws_for_
null_string
empty_string
spaces_string
tabs_string
newLine_string
Imagine that difference multiplied by hundreds of tests....
The code example:
(Note: The XFactAtttribute changes the behaviour of XUnit such that the test is only executed for the class in which it is defined, not for inheriting classes. I also have an XTestAttribute that does the same for NUnit.)
Code:
using System;
using Compze.Testing.TestFrameworkExtensions.XUnit;
namespace Compze.Tests.Unit.Internals.Contracts;
public class Assertion_library_specification : AssertionMethodsTest
{
public class StringAssertion_method : Assertion_library_specification
{
const string EmptyString = "";
static readonly string? NullString = null;
const string SpacesString = " ";
const string TabsString = " ";
static readonly string NewLineString = Environment.NewLine;
public class NotNull_throws_for : StringAssertion_method
{
[XFact] public void null_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullOrEmpty(NullString), NullString);
}
public class NotNullEmptyOrWhitespace_throws_for_ : StringAssertion_method
{
[XFact] public void null_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullEmptyOrWhitespace(NullString), NullString);
[XFact] public void empty_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullEmptyOrWhitespace(EmptyString), EmptyString);
[XFact] public void spaces_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullEmptyOrWhitespace(SpacesString), SpacesString);
[XFact] public void tabs_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullEmptyOrWhitespace(TabsString), TabsString);
[XFact] public void newLine_string() => ThrowsAndCapturesArgumentExpressionText(() => Asserter.NotNullEmptyOrWhitespace(NewLineString), NewLineString);
}
}
}