Change name of NUnit test

15,193

Solution 1

This is supported if you are using parametrised tests, you can specify the TestName when adding the TestCase attribute.

If you aren't using TestCase, then you could use it as a less than ideal work around to achieve what you're trying to do. So you would declare your test like this:

[TestCase(null,TestName="Test Case #1, Category: First, Category: Second")]
public void TestCase(object ignored)

This isn't ideal because it's not programmatic so you have to manually type the test name, rather than generating it from the attributes on the test method. You also have to pass a parameter to the method, which is what the ignored and null is about. Of course, you could start using parametrised tests in which case you'd be passing in an actual value to your tests.

[TestCase(5,TestName="Test Case #1, Category: First, Category: Second")]
public void TestCase(int someInput) {
    Assert.AreEqual(5, someInput);
}

Solution 2

You can create your own Name attribute:

// I used the same namespace for convenience
namespace NUnit.Framework
{
    public class NameAttribute  : NUnitAttribute, IApplyToTest
    {
        public NameAttribute(string name)
        {
            Name = name;
        }

        public string Name { get; set; }

        public void ApplyToTest(Test test)
        {
            test.Properties.Add("Name", Name);
        }
    }
}

You then use it like a regular NUnit property (Just like Category and Description).

[Test, Name("My Awesome Test"), Category("Cool.Tests"), Description("All cool tests")]
public void Test313()
{
    // Do something
}

You can see the data in your TestContext:

if (TestContext.CurrentContext.Test.Properties.ContainsKey("Name"))
{
    name = TestContext.CurrentContext.Test.Properties.Get("Name") as string;
}

Solution 3

Further to @forsvarir answer above, the following now works:

[TestCase(TestName = "Test case name")]
Public void TestSomething()
{
   ...
}

Solution 4

I wanted to change the test name of a parameterized NUnit test programmatically and dynamically, i.e. based on input files in a test data folder.

It took a couple of adjustments, but this works:

[Test, TestCaseSource(nameof(GetSites))]
public void TestForEveryFile(object ignored, FileInfo testFile) {
   // actual test using 'testFile'
}

public static IEnumerable<TestCaseData> GetSites()
{
    foreach (string testFile in Directory.EnumerateFiles("TestData"))
    {
        FileInfo fileInfo = new FileInfo(testFile);

        // Pass '' as first argument to TestCaseData to suppress the default test name
        // (seems to be necessary even if TestName is set)
        var testCase = new TestCaseData("", fileInfo) 
        {
            // Use the short file name as test name.
            // As dots (.) would indicate a test hierarchy, we replace them with '-'.
            TestName = fileInfo.Name.Replace(".", "-")
        };
        yield return testCase;
    }
}
Share:
15,193
shytikov
Author by

shytikov

Dynamics CRM / NAV Senior

Updated on June 21, 2022

Comments

  • shytikov
    shytikov almost 2 years

    I want my unit-tests based on NUnit framework named a bit more human readable in Visual Studio test explorer.

    For example instead of having Test_Case_1 or TestCase1 I would better have something like Test Case #1, Category: First, Category: Second (by assigning values from [Category] attributes as well), with spaces and characters not allowed in methods names.

    I know it's out-of-the-box possible in xUnit, but I cannot involve it, since I'm using my customizations that I was not able to implement using xUnit framework.

    Is it possible to rewrite unit test display name with NUnit? So far I can see, that FullName field of TestDetail has private setter.

    Is any other ways or approaches change display name for NUnit tests?

  • shytikov
    shytikov almost 9 years
    You're right... This is the only possible way for now... However, I've submitted issue, So maybe the default behavior will change in the future.
  • Rekshino
    Rekshino over 2 years
    I took in my case nameof(..) to show the actual name of tested method, so [TestCase(TestName = nameof(TargetClass.MethodToTest))]
  • Mounika
    Mounika about 2 years
    @Rekshino, [TestCase(TestName = nameof(TargetClass.MethodToTest))] is printing the method name instead of executing the method and using it's return value. What am I missing here?
  • srk
    srk about 2 years
    @Mounika - "...is printing the method name instead of executing the method." According to the documentation, it works that way because that's literally what the nameof expression does. More details in my answer to your question here.