Можно ли улучшить следующий подход, чтобы следовать хорошим методам проектирования TDD (именованию, использованию тестов строк, разработке классов) в любой платформе .NET TDD/BDD?
Кроме того, есть ли лучший способ в любой из фреймворков иметь rowtests, где у меня может быть индивидуальное ожидание для каждой строки, как я это делаю в этом примере (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));
}
}
Во-первых, вы можете улучшить имя вашего модульного теста NarrowDown_Works
, очень неопределенно, и я не могу сказать, что должен делать этот класс.
У вас много утверждений и множество данных, я не могу сказать, что важно. Попробуйте разорвать ваш тест на более мелкие тесты , и их будет проще назвать. Если возможно, используйте одно утверждение за тест .
Ваше построение тестовых данных довольно сложно, подумайте об использовании сокетов , например NHamcrest для уменьшения объема данных утверждения, которые вам нужны, вместо использования Is.EquivalentTo
.
Вы могли бы также использовать конструктор-конструктор или фабричные конструкторы для упростить инициализацию для класса Constraint
, а не передавать в массиве Ranges
.
Вы должны использовать подход, основанный на данных, с фабриками данных (в NUnit-talk, они называются тестовыми источниками ). Это делает ваши тесты намного легче читать, понимать, модифицировать и поддерживать (или, в более общем плане, намного чище):
[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));
}
}
Посмотрите, насколько проще теперь ваши методы тестирования? Кроме того, это приведет к тому, что каждый набор данных из исходного источника тестового случая будет запущен в отдельном тесте, поэтому все это не будет терпеть неудачу только потому, что один набор данных вызывает сбой. Помните: тест должен содержать только один .
НТН!