Skip to content

Use array argument contents in name of parameterized tests rather than just array type. #1382

Closed
@yaakov-h

Description

@yaakov-h

TestCase and TestCaseSource make it too easy to create tests with duplicate names.

Case 1: Arrays

Arrays are not formatted further, only their type name becomes part of the test name by default. For example, given the following test fixture:

using NUnit.Framework;

namespace NUnitDuplicateTests
{
    public class DuplicateTestFixture
    {
        [TestCase((object)new[] { "John", "Smith" })]
        [TestCase((object)new[] { "Emperor", "Palpatine" })]
        [TestCase((object)new[] { "Groot" })]
        public void EverybodyHasAtLeastTwoNames(string[] nameParts)
        {
            Assert.That(nameParts, Has.Length.GreaterThanOrEqualTo(2));
        }
    }
}

Only one test is discovered: NUnitDuplicateTests.DuplicateTestFixture.EverybodyHasAtLeastTwoNames(System.String[]).

Only one test shows up in the Visual Studio test explorer.

Only one unique test shows up with nunit3-console --explore, but is printed 3 times.

This creates issues for applications that use the Explore API, if they wish to track each test individually for various purposes.

I would expect the test name to be something along the lines of NUnitDuplicateTests.DuplicateTestFixture.EverybodyHasAtLeastTwoNames(["Emperor", "Palpatine"]).

Case 2: Test Names

I would logically expect a test name from TestCaseAttribute or TestCaseData to be local to the method that declares the test. It is often convenient to use the same test data for multiple test methods, e.g.

using System.Collections;
using NUnit.Framework;

namespace NUnitDuplicateTests
{
    public class DuplicateTestFixture
    {
        [TestCaseSource(nameof(Names))]
        public void EverybodyHasAtLeastTwoNames(string[] nameParts)
        {
            Assert.That(nameParts, Has.Length.GreaterThanOrEqualTo(2));
        }

        [TestCaseSource(nameof(Names))]
        public void EverybodyIsOnTheImperialPayroll(string[] nameParts)
        {
            // TODO: Talk to the Payroll division on Coruscant.
        }

        public static IEnumerable Names
        {
            get
            {
                yield return new TestCaseData(new[] { "Emperor", "Palpatine" }).SetName("Our grand Emperor");
                yield return new TestCaseData(new[] { "Darth", "Vader" }).SetName("Luke's Dad");
            }
        }
    }
}

Although this fixture declares four tests, there are only two unique test names - NUnitDuplicateTests.DuplicateTestFixture.Our grand Emperor and NUnitDuplicateTests.DuplicateTestFixture.Luke's Dad.

I would expect there to be four, somewhat resembling the following:

  1. NUnitDuplicateTests.DuplicateTestFixture.EverybodyHasAtLeastTwoNames."Our grand Emperor"
  2. NUnitDuplicateTests.DuplicateTestFixture.EverybodyHasAtLeastTwoNames."Luke's Dad"
  3. NUnitDuplicateTests.DuplicateTestFixture.EverybodyIsOnTheImperialPayroll."Our grand Emperor"
  4. NUnitDuplicateTests.DuplicateTestFixture.EverybodyIsOnTheImperialPayroll."Luke's Dad"

Case 3: String truncation

String parameters are truncated to 40 characters, which makes it difficult to use long strings (such as URLs) in test cases. e.g.:

using NUnit.Framework;

namespace NUnitDuplicateTests
{
    public class DuplicateTestFixture
    {
        [TestCase("The Imperial Death Star is a collossal waste of money. The Empire could better use those funds on supplies and soldiers.")]
        [TestCase("The Imperial Death Star is a collossal monument to the power of the Empire.")]
        public void AllOpinionsAreValid(string opinion)
        {
            Assert.That(opinion, Is.Not.Null, "Not having an opinion is not in itself an opinion.");
        }
    }
}

This fixture only has one unique test name, NUnitDuplicateTests.DuplicateTestFixture.AllOpinionsAreValid("The Imperial Death Star is a collossa...").

From this, I see three resolutions:

  1. Can test names be made smarter by introspecting arrays?
  2. Can explicit test names be made local to their method, not local to their fixture?
  3. Can strings be not truncated, or the truncation limit be increased well beyond 40 characters?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions