Kiedy używam VS do generowania testów jednostkowych, otrzymałem Assert.Inclusive dla wygenerowanych metod testowania i zwykle zmieniam asercję, więc coś innego, gdy je pracuję. Używam znaków zapytania Assert.Inconclusive w wyniku testu jako markerów, aby szybko powiedzieć mi, które testy jeszcze nie zostały zakończone.
Cóż, po prostu tak go używam. Od jego nazwy "Niekonsekwentny", myślę, że możesz użyć do wskazania swojego niezdefiniowanego stanu, o ile będziesz dokumentować, co to znaczy.
Jednakże, z opisu metody Average()
, myślę, że być może twój test jednostkowy nie jest wystarczająco atomowy, aby objąć tylko jedną "jednostkę", jeden konkretny scenariusz. Czasami piszę 2 lub 3 jednostki metody testowe dla jednej metody. Możesz też złamać swoją metodę na mniejsze metody obejmujące pojedyncze obowiązki. W ten sposób możesz przetestować te mniejsze metody przed testowaniem jednostki pod numerem Average()
.
Johannes,
To w jaki sposób zaimplementować metody Sum()
i Average()
.
public static class MyMath
{
private static void ValidateInput(ICollection<int> numbers)
{
if (numbers == null)
throw new ArgumentNullException("numbers", "Null input. Nothing to compute!");
if (numbers.Count == 0)
throw new ArgumentException("Input is empty. Nothing to compute!");
}
public static int Sum(int[] numbers)
{
ValidateInput(numbers);
var total = 0;
foreach (var number in numbers)
total += number;
return total;
}
public static double Average(int[] numbers)
{
ValidateInput(numbers);
return Sum(numbers)/numbers.Length;
}
}
Dla uproszczenia, po prostu rzucać ArgumentException
wyjątki od metody ValidateInput(ICollection<int>)
. Możesz również sprawdzić, czy nie ma możliwości przepełnienia i wrzucenia metody OverflowException
w metodzie.
Powiedziawszy, oto jak przetestować funkcję Average(int[])
.
[TestMethod]
public void AverageTest_GoodInput()
{
int[] numbers = {1, 2, 3};
const double expected = 2.0;
var actual = MyMath.Average(numbers);
Assert.AreEqual(expected, actual);
}
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void AverageTest_NullInput()
{
int[] numbers = null;
MyMath.Average(numbers);
}
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void AverageTest_EmptyInput()
{
var numbers = new int[0];
MyMath.Average(numbers);
}
Dzięki tym ustawieniom testów mogę być pewien, że po przejściu wszystkich testów moja funkcja jest poprawna. Cóż, z wyjątkiem przypadku przepełnienia. Teraz mogę wrócić do metody ValidateInput(ICollection<int>)
, aby dodać logikę w celu sprawdzenia nadmiaru, a następnie dodać jeszcze jeden test, aby oczekiwać wyrzucenia OverflowException
dla tego rodzaju danych wejściowych, które powodują przepełnienie. Lub robisz to w odwrotnej kolejności, jeśli chcesz podejść do używania TDD.
Mam nadzieję, że pomoże to wyjaśnić pomysł.
. Czy mógłbyś wyjaśnić, jak podejść do tego w tym szczególnym przypadku? –
Dziękuję bardzo. więc w istocie mówisz, że nie ma potrzeby pisania wyraźnego testu dla Sum(), ale testowanie go przez Average(). Z perspektywy pokrycia kodu generuje to ten sam wynik. –
Chciałbym również napisać testy dla Sum(). Kto wie w mojej śpiącej chwili, mógłbym wpisać "-" zamiast "/". :) Z testami dla Sum() w miejscu, jeśli dostałem wszystkie testy dla Pass(), ale niektóre testy dla Average() zawodzą, mogę być pewny, że implementacja dla Average() jest błędna. Nie będę w stanie winić Sum(), że spowodowało, że średnia() jest zła. :) – tranmq