Nunit
Есть вот такой метод для теста
Как лучше, оставить как есть или сделать через параметры и указывать все значения init1, do1, 0, 1 — через аттрибуты
Насколько это удобно будет отлаживать во 2м случае ?
const string init1 = "init1";
const string init2 = "init2";
const string do1 = "do1";
const string do2 = "do2";
[Test]
public void Test()
{
var a = new A();
a.Init(init1);
Assert.IsEqual( a.Do(do1), 0 );
a = new A();
a.Init(init2);
Assert.IsEqual( a.Do(do2), 1 );
}
Здравствуйте, Аноним, Вы писали:
А>Nunit
А>Есть вот такой метод для теста
А>Как лучше, оставить как есть или сделать через параметры и указывать все значения init1, do1, 0, 1 — через аттрибуты
А>Насколько это удобно будет отлаживать во 2м случае ?
Конечно здесь явно напрашиваются
параметризованные тесты, ведь по сути, здесь не один тест, а два.
[TestCase("init1", "do1", Result = 0)]
[TestCase("init2", "do2", Result = 1)]
public int Test_That_Do_Produces_Expected_Result(string initData, string doData)
{
// У нас же тут ООП, как никак, а раз так, то инварианты класса А
// должны устанавливаться в конструкторе
var a = new A(initData);
return a.Do(doData);
}
Основной плюс параметризованных тестов в том, что это четко показывает, что у нас не один тест, а два. Ведь существуют правила написания юнит-тестов, один из вариантов которых называется
F.I.R.S.T.. Одним из самых важных принципов является I — isolated, это значит, что если один из тестов падает, то другие должны продолжаться исполняться с чистого листа.
В исходном примере, если тест упадет при init1, то второй тест вообще не будет выполнен. Тем более, предложенный вариант очень плохо расширяем. А что если нам понадобиться покрыть десяток кейсов? Так и будем плодить константы и плодить один и тот же код внутри теста? Как-то это кажется не самым удачным подходом.
Параметризованные тесты — это отличный инструмент, который позволяет добиться хорошего покрытия тестов с минимумом усилий. В этом случае добавление еще одно тест-кейса в существующий код — это дело буквально нескольких секунд. К тому же, можно воспользоваться чудо паттерном
"Object Mother" и выделить отдельные методы, создающие тестовые данные:
class CustomObjectMother
{
public static IEnumerable GetTestCasesForYouSpecificCase()
{
yield return new TestCaseData("init1", "do1").Returns(0);
yield return new TestCaseData("init2", "do2").Returns(1);
}
}
Теперь, если у нас будет несколько тестов, которым подходят эти данные, то можно будет их использовать несколько раз:
[TestCaseSource("CustomObjectMother.GetTestCasesForYouSpecificCase")]
public int Test_That_Do_Produces_Expected_Result(string initData, string doData)
{}
[TestCaseSource("CustomObjectMother.GetTestCasesForYouSpecificCase")]
public int Another_Test_With_The_Same_Arguments(string initData, string doData)
{}
> Насколько будет удобно отлаживать во втором случа?
Если у вас есть решарпер, то это сделать очень просто:
В случае VS2012+, отлаживать тесты тоже просто. Ставим NUnit Test Adapter, в результате можно будет использовать для отладки встроенный Test Explorer:
С Новым Годом
Здравствуйте, SergeyT., Вы писали:
ST>Здравствуйте, Аноним, Вы писали:
А>>Nunit
А>>Есть вот такой метод для теста
А>>Как лучше, оставить как есть или сделать через параметры и указывать все значения init1, do1, 0, 1 — через аттрибуты
А>>Насколько это удобно будет отлаживать во 2м случае ?
ST>Конечно здесь явно напрашиваются параметризованные тесты, ведь по сути, здесь не один тест, а два.
ST>С Новым Годом
Спасибо, а такой момент еще возник.
Например в тесте делается
public void TestA(string init)
{
var a = new A(init);
Assert.AreEquals( A.Property1, 1 );
Assert.AreEquals( A.Property2, "2" );
}
Можно ли сделать
public A TestA( string init )
{
return new A(init);
}
А проверку полей и property у A указать также в new TestCaseData("init1").Returns(???);
Только вот не совсем понятно что нужно будет в Returns описать.