Zaawansowane CPP/Ćwiczenia 4: Testowanie: Różnice pomiędzy wersjami
Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 4: | Linia 4: | ||
<code><nowiki>CppUnit</nowiki></code> dodaj testy sprawdzające wersję szukającą maksimum w | <code><nowiki>CppUnit</nowiki></code> dodaj testy sprawdzające wersję szukającą maksimum w | ||
tablicy. Wykorzystaj w tym celu dodatkową klasę testującą. | tablicy. Wykorzystaj w tym celu dodatkową klasę testującą. | ||
Sprawdź swój test na implementacji [ | Sprawdź swój test na implementacji [[media:Max_error.h | max_error.h]]. Znajdź znajdujące się tam błędy. | ||
}} | }} | ||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | <div class="mw-collapsible mw-made=collapsible mw-collapsed"><span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span><div class="mw-collapsible-content" style="display:none"> | ||
Patrz pliki [ | Patrz pliki [[media:Max_cppunit.cpp | max_cppunit.cpp]] i [[media:Max_cppunit.cpp | max_cppunit.cpp]]. | ||
</div></div> | </div></div> | ||
Linia 14: | Linia 14: | ||
Zaproponuj i napisz, używając <code><nowiki>CppUnit</nowiki></code>, testy | Zaproponuj i napisz, używając <code><nowiki>CppUnit</nowiki></code>, testy | ||
klasy <code><nowiki>Stack</nowiki></code>. Implementacja tej klasy znajduje się w pliku [ | klasy <code><nowiki>Stack</nowiki></code>. Implementacja tej klasy znajduje się w pliku [[media:Stack.h | stack.h]]. Nie zapomnij o testach kopiowania i | ||
przypisywania oraz destruktora. | przypisywania oraz destruktora. | ||
Sprawdź czy stos zaimplementowany w pliku [ | Sprawdź czy stos zaimplementowany w pliku [[media:Stack_dyn.h | stack_dyn.h]], przechodzi twoje | ||
testy. Jeśli tak, to znajdź błędy w kodzie i tak popraw testy, aby | testy. Jeśli tak, to znajdź błędy w kodzie i tak popraw testy, aby | ||
wyłapywały te błędy. Popraw kod tak, aby przeszedł uzupełnione testy. | wyłapywały te błędy. Popraw kod tak, aby przeszedł uzupełnione testy. | ||
Linia 27: | Linia 27: | ||
konstruktora kopiującego i operatora przypisania. | konstruktora kopiującego i operatora przypisania. | ||
Test podstawowy zawarty jest w składowej <tt>test_base()</tt> klasy <tt>stack_test</tt> w pliku [ | Test podstawowy zawarty jest w składowej <tt>test_base()</tt> klasy <tt>stack_test</tt> w pliku [[media:Stack_test_cppunit.cpp | stack_test_cppunit.cpp]]. Polega on na naprzemiennym wkładaniu i zdejmowaniu ze stosu liczb całkowitych i sprawdzaniu poprawności zdejmowanych elementów. Na końcu trzykrotnie wypełniamy i opróżniamy cały stos. | ||
Pozostałe testy wymagają więcej komentarza. Ich zadaniem jest testowanie funkcji generowanych automatycznie. W tym przypadku działają one prawidłowo, co można dość łatwo stwierdzić bez przeprowadzania testów. W ogólności jednak nie musi tak być. Przykładem może być implementacja [ | Pozostałe testy wymagają więcej komentarza. Ich zadaniem jest testowanie funkcji generowanych automatycznie. W tym przypadku działają one prawidłowo, co można dość łatwo stwierdzić bez przeprowadzania testów. W ogólności jednak nie musi tak być. Przykładem może być implementacja [[media:Stack_dyn.h | stack_dyn.h]]. | ||
Zacznijmy od destruktora. Zadaniem destruktora jest usunięcie pamięci zajętej przez stos, a objawem błędu w destruktorze jest wyciek pamięci. Nie znam uniwersalnego sposobu testowania wycieku pamięci. Zwykle używam prostej, ale ograniczonej sztuczki. Polega ona na tworzeniu i niszczeniu dużego stosu w dużej pętli. | Zacznijmy od destruktora. Zadaniem destruktora jest usunięcie pamięci zajętej przez stos, a objawem błędu w destruktorze jest wyciek pamięci. Nie znam uniwersalnego sposobu testowania wycieku pamięci. Zwykle używam prostej, ale ograniczonej sztuczki. Polega ona na tworzeniu i niszczeniu dużego stosu w dużej pętli. | ||
Linia 41: | Linia 41: | ||
}; | }; | ||
Jeśli destruktor nie zwolni pamięci, to w każdej iteracji następował będzie wyciek i pamięci w końcu zabraknie. Wtedy kolejne wywołanie <tt>operator new</tt> rzuci wyjątek. Oczywiście jeśli wyciek będzie mały np. parę bajtów, to ta metoda go nie wychwyci. | Jeśli destruktor nie zwolni pamięci, to w każdej iteracji następował będzie wyciek i pamięci w końcu zabraknie. Wtedy kolejne wywołanie <tt>operator new</tt> rzuci wyjątek. Oczywiście jeśli wyciek będzie mały np. parę bajtów, to ta metoda go nie wychwyci. | ||
Testy kopiowania i przypisania wyglądają podobnie. W obu przypadkach wynikiem powinny być dwa stosy o takiej samej zawartości. Proszę jednak zauważyć, że nie posiadamy możliwości bezpośredniego porównania zawartości stosów bez opróżniania ich. Nawet zresztą gdybyśmy mieli operator porównia, to i tak wymagałby on testowania. W tym celu napisałem funkcję <tt>equal</tt>, która porównuje dwa stosy, opróżniając je, a następnie uzupełniając z powrotem. Kod znajduje się w pliku [ | Testy kopiowania i przypisania wyglądają podobnie. W obu przypadkach wynikiem powinny być dwa stosy o takiej samej zawartości. Proszę jednak zauważyć, że nie posiadamy możliwości bezpośredniego porównania zawartości stosów bez opróżniania ich. Nawet zresztą gdybyśmy mieli operator porównia, to i tak wymagałby on testowania. W tym celu napisałem funkcję <tt>equal</tt>, która porównuje dwa stosy, opróżniając je, a następnie uzupełniając z powrotem. Kod znajduje się w pliku [[media:Stack_test_cppunit.cpp | stack_test_cppunit.cpp]]. | ||
Częstym błędem podaczas kopiowania/przypisywania jest doprowadzenie do współdzielenia reprezentacji. Musimy więc sprawdzić, czy dwie kopie nie tylko są równe, ale i niezależne. W tym celu napisałem funkcję <tt>inc</tt>, która zwiększa każdy element stosu liczb całkowitych o jeden. W przypadku współdzielenia reprezentacji nastąpi zwiększenie obu stosów i oba stosy dalej będą równe. | Częstym błędem podaczas kopiowania/przypisywania jest doprowadzenie do współdzielenia reprezentacji. Musimy więc sprawdzić, czy dwie kopie nie tylko są równe, ale i niezależne. W tym celu napisałem funkcję <tt>inc</tt>, która zwiększa każdy element stosu liczb całkowitych o jeden. W przypadku współdzielenia reprezentacji nastąpi zwiększenie obu stosów i oba stosy dalej będą równe. | ||
Linia 49: | Linia 49: | ||
Dodatkowo w trakcie przypisywania może dojść do wycieku pamięci w stosie, do którego przypisujemy nową wartość. Testujemy to podobnie jak w przypadku destruktora. | Dodatkowo w trakcie przypisywania może dojść do wycieku pamięci w stosie, do którego przypisujemy nową wartość. Testujemy to podobnie jak w przypadku destruktora. | ||
Całość kodu znajduje się w pliku [ | Całość kodu znajduje się w pliku [[media:Stack_test_cppunit.cpp | stack_test_cppunit.cpp]]. | ||
</div></div> | </div></div> |
Wersja z 10:25, 2 paź 2006
Ćwiczenie 1
Do przykładu testów max
napisanych w
CppUnit
dodaj testy sprawdzające wersję szukającą maksimum w
tablicy. Wykorzystaj w tym celu dodatkową klasę testującą.
Sprawdź swój test na implementacji max_error.h. Znajdź znajdujące się tam błędy.
Rozwiązanie
Ćwiczenie 2
Zaproponuj i napisz, używając CppUnit
, testy
klasy Stack
. Implementacja tej klasy znajduje się w pliku stack.h. Nie zapomnij o testach kopiowania i
przypisywania oraz destruktora.
Sprawdź czy stos zaimplementowany w pliku stack_dyn.h, przechodzi twoje testy. Jeśli tak, to znajdź błędy w kodzie i tak popraw testy, aby wyłapywały te błędy. Popraw kod tak, aby przeszedł uzupełnione testy.
Rozwiązanie