Próbuję dokładniej śledzić praktykę "jednego stwierdzenia na jednostkę testu". Nie zawsze jest to możliwe, ale uważam, że jest to przydatne do wskazywania błędów.Czy istnieje atrybut pozwalający uniknąć kaskadowych testów jednostkowych w MSTest?
Na przykład może mam coś takiego:
var toTest;
[TestInitialize]
Init() {
toTest = // Create toTest
}
[TestMethod]
TestIsCreated() {
Assert.IsNotNull(toTest);
}
[TestMethod]
TestIsProperty1Setup() {
Assert.IsNotNull(toTest.Property1);
// Maybe some more tests on Property1
}
// More tests for other properties...
Problemem jest to, czy tworzenie toTest były na niepowodzenie, a następnie wszystkich innych testów jednostkowych fail też. Tak więc możemy dodać trochę czeku w ten sposób:
...
[TestMethod]
TestIsProperty1Setup() {
if (toTest == null) Assert.Inconclusive()
Assert.IsNotNull(toTest.Property1);
// Maybe some more tests on Property1
}
...
Spowoduje to zatrzymanie awarii kaskady i wskaże dokładny problem. Jeśli linia // Create toTest zwróci wartość zerową, to otrzymam dokładnie jeden test jednostkowy, a także kilka nierozstrzygających testów. Kiedy naprawię jeden test, to wszystko inne przechodzi.
Są dwa miejsca, w których to spada. Jednym z nich jest fakt, że teraz powtarzam kod na początku prawie wszystkich testów jednostkowych.
Drugim problemem jest to, kiedy chcesz ustawić i sprawdzić bardziej złożony obiekt (w tym manekina przykład toTest ma również tablicę):
[TestMethod]
TestArrayIsNotNull() {
if (toTest == null) Assert.Inconclusive();
Assert.IsNotNull(toTest.Array);
}
[TestMethod]
TestArrayIsInitilizedWithOneElement() {
if (toTest == null) Assert.Inconclusive();
if (toTest.Array == null) Assert.Inconclusive();
Assert.AreEqual(1, toTest.Array.Count())
}
[TestMethod]
TestArrayIsInitilizedWithCorrectElement() {
if (toTest == null) Assert.Inconclusive();
if (toTest.Array == null) Assert.Inconclusive();
if (toTest.Array.Count() != 1) Assert.Inconclusive();
// Assert something about toTest.Array[0]
}
Teraz jest więcej duplikat kodu dla każdego testu, oraz ważniejsze jest, że Assery muszą być zsynchronizowane między różnymi testami, co oznacza, że jedna mała zmiana może przebiegać w wielu testach jednostkowych.
Idealnie chciałbym mieć atrybut, który znajduje się na górze każdego testu i uruchamia test tylko wtedy, gdy zdadzą "wstępne" testy. Może to wyglądać mniej więcej tak:
[TestMethod]
[OnlyRunIfOtherTestPasses(TestIsCreated())]
TestArrayIsNotNull() {
Assert.IsNotNull(toTest.Array);
}
[TestMethod]
[OnlyRunIfOtherTestPasses(TestArrayIsNotNull())]
TestArrayIsInitilizedWithOneElement() {
Assert.AreEqual(1, toTest.Array.Count())
}
[TestMethod]
[OnlyRunIfOtherTestPasses(TestArrayIsInitilizedWithOneElement())]
TestArrayIsInitilizedWithCorrectElement() {
// Assert something about toTest.Array[0]
}
Testy jednostkowe są teraz bardzo proste - nie ma powielanie i prowadzenie testów zsynchronizowane z ich „warunków” jest teraz automatyczne.
Czy jest coś takiego? Czy istnieje zupełnie inna funkcja, której mogę użyć, aby uzyskać ten sam efekt?
Jestem świadomy, że prawie na pewno występują problemy z odwołaniem się do metody testowej w atrybucie do innej metody testowej - prawdopodobnie musiałbyś użyć łańcucha, który jest zakodowany na sztywno do nazwy metody (więc co się stanie, jeśli metoda zmiana nazwy lub metoda nie istnieje). Jestem pewien, że istnieją potencjalne problemy z odwołaniami cyklicznymi. Ale mimo wszystkich tych problemów ktoś musiał rozwiązać ten problem. Czy ktoś może mi to wskazać?
IMHO masz zbyt dużo logiki w swoich testach jednostkowych. Powinny być zwięzłe i nie zawierać dużej logiki. Nie powinny także polegać na innych testach. Myślę, że musisz ponownie przemyśleć swoje podejście. – Belogix
Kiedy mówisz "przemyśleć swoje podejście", masz na myśli ponowne przemyślenie sposobu, w jaki napisane są testy jednostkowe (nie powinienem sprawdzać, czy test jest zawsze pusty) lub ponownie przemyśleć zależności badanej klasy (test nie powinien mieć tablica, którą należy skonfigurować)? – Jonny
Duplikat: http://stackoverflow.com/questions/15871933/how-to-stop-mstest-tests-execution-on-first-failure – BartoszKP