Чи можна поліпшити ці тестові тести на стиль рядків, щоб слідувати належним практикам дизайну TDD?

Чи можна покращити наступну одиницю тесту, щоб дотримуватися правильних практик проектування TDD (називання, використання пробілів, розробка класів) в будь-якій структурі. NET TDD/BDD?

Крім того, чи є кращий спосіб в будь-якій структурі мати проміжки, де я можу мати індивідуальне очікування для кожного рядка, як я роблю це в цьому (NUnit) прикладі?

Тут розглянута система - це клас Constraint , який може мати кілька діапазонів дійсних цілих чисел. Перевірте тест методом NarrowDown , який може зменшити дійсні діапазони на основі іншого обмеження.

[TestFixture]
internal class ConstraintTests
{
    [Test]
    public void NarrowDown_Works()
    {
        RowTest_NarrowDown(
            new Range[] { new Range(0, 10), new Range(20, 30), new Range(40, 50) },
            new Range[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) },
            new Range[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) });

        RowTest_NarrowDown(
            new Range[] { new Range(0, 10), new Range(20, 30), new Range(40, 50), new Range(60, 70) },
            new Range[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) },
            new Range[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) });

        RowTest_NarrowDown(
            new Range[] { new Range(0, 10), new Range(20, 30), new Range(40, 50) },
            new Range[] { new Range(1, 9), new Range(21, 29), new Range(41, 49), new Range(60, 70) });
    }

    private static void RowTest_NarrowDown(IEnumerable sut, IEnumerable context)
    {
        Constraint constraint = new Constraint(sut);
        Constraint result = constraint.NarrowDown(new Constraint(context));
        Assert.That(result, Is.Null);
    }

    private static void RowTest_NarrowDown(IEnumerable sut, IEnumerable context, IEnumerable expected)
    {
        Constraint constraint = new Constraint(sut);
        Constraint result = constraint.NarrowDown(new Constraint(context));
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Bounds, Is.EquivalentTo(expected));
    }
}
1
Кожен набір входів має бути незалежним тестом. Якщо логіка декількох тестів однакова, а не вхід-вихід, скористайтеся параметрами "Параметризовані тести". NUnit використовує атрибути або метод, який забезпечує різні набори входів для параметризованого тесту. Кожен набір виконується/повідомляється як інший тестовий випадок випробувальним бігунком.
додано Автор Gishu, джерело

2 Відповіді

По-перше, ви можете покращити назву свого одиничного тесту NarrowDown_Works надзвичайно розпливчасто, і я не можу сказати, що повинен робити тестовий клас.

У вас є багато тверджень і багато даних, я не можу сказати, що важливо. Спробуйте розбити тест на невеликі тести , і їх буде легше назвати. Якщо можливо, використовуйте одне підтвердження на тест .

Ваша побудова тестових даних досить складна, розгляньте можливість використання аналогів , як NHamcrest щоб зменшити кількість необхідних даних затвердження замість використання коду Is.EquivalentTo .

Ви також можете використовувати забудову або заводські конструктори, щоб полегшити ініціалізацію класу Constraint , а не пропускати його в масиві Діапазонів .

2
додано
+1 для підказки до NHamcrest
додано Автор bitbonk, джерело

Ви повинні використовувати підхід, керований даними, з фабриками даних (в NUnit-говор, вони називаються джерелами тестових випадків ). Це робить ваші випробування набагато простішими для читання, розуміння, модифікації та підтримки (або, загалом, набагато більш чистим):

[TestFixture]
internal class ConstraintTests
{
    static object[] TwoRanges = 
    {
        new object[]
            {
                new[] { new Range(0, 10), new Range(20, 30), new Range(40, 50) },
                new[] { new Range(1, 9), new Range(21, 29), new Range(41, 49), new Range(60, 70) }
            }
    };

    static object[] ThreeRanges = 
    {
        new object[]
            {
                new[] { new Range(0, 10), new Range(20, 30), new Range(40, 50) },
                new[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) },
                new[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) }
            },
        new object[]
            {
                new[] { new Range(0, 10), new Range(20, 30), new Range(40, 50), new Range(60, 70) },
                new[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) },
                new[] { new Range(1, 9), new Range(21, 29), new Range(41, 49) }
            }
    };

    [Test, TestCaseSource("TwoRanges")]
    public void NarrowDown_WhenCalledWithTwoRanges_GivesTheExpectedResult(IEnumerable sut, IEnumerable context)
    {
        Constraint constraint = new Constraint(sut);
        Constraint result = constraint.NarrowDown(new Constraint(context));
        Assert.That(result, Is.Null);
    }

    [Test, TestCaseSource("ThreeRanges")]
    public void NarrowDown_WhenCalledWithThreeRanges_GivesTheExpectedResult(IEnumerable sut, IEnumerable context, IEnumerable expected)
    {
        Constraint constraint = new Constraint(sut);
        Constraint result = constraint.NarrowDown(new Constraint(context));
        Assert.That(result, Is.Not.Null);
        Assert.That(result.Bounds, Is.EquivalentTo(expected));
    }
}

Подивіться, наскільки простішими стали ваші тестові методи? Крім того, це зроблять кожен набір даних з джерела вихідного тестового випадку запущені в окремому тесті, так що все це не збігатиметься лише тому, що один набір даних спричиняє збій. Пам'ятайте: тест повинен стверджувати лише одну речі.

HTH!

0
додано