Zaawansowane CPP/Ćwiczenia 4: Testowanie: Różnice pomiędzy wersjami
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 {mod09/exercises/max_error.h}<tt>maxerror.h</tt>. Znajdź znajdujące się tam błędy. | |||
}} | |||
{{cwiczenie|2|| | {{cwiczenie|2|| | ||
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 [http://osilek.mimuw.edu.pl/images/6/61/Stack.h stack.h]. Nie zapomnij o testach kopiowania i | klasy <code><nowiki>Stack</nowiki></code>. Implementacja tej klasy znajduje się w pliku [http://osilek.mimuw.edu.pl/images/6/61/Stack.h stack.h]. Nie zapomnij o testach kopiowania i | ||
przypisywania. | przypisywania oraz destruktora. | ||
Sprawdź czy stos zaimplementowany w pliku | |||
{mod09/exercises/stack_dyn.h}<tt>stackdyn.h</tt>, 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 1 ''' | |||
< | |||
Zobacz plik | |||
} | {mod09/exercises/max_array_test.cpp}<tt>maxarraytest.cpp</tt> i | ||
{mod09/exercises/max_cppunit.cpp}<tt>maxcppunit.cpp</tt>. | |||
'''Rozwiązanie 2 ''' | |||
Test stosu podzielę na cztery części: pierwsza zawierać będzie test | |||
podstawowych funkcji, druga destruktora, a trzecia i czwarta | |||
konstruktora kopiującego i operatora przypisania. | |||
Test podstawowy zawarty jest w składowej {test_base()} klasy | |||
{stack_test} w pliku | |||
{mod09/exercises/stack_test_cppunit.cpp}<tt>stacktestcppunit.cpp</tt>. 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ć implementacj {stac_dyn.h}. | |||
Zacznijmy od destruktora, zadaniem destruktora jest usunięcie pamięci | |||
zajętej przez stos, a objawem błedu 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. | |||
try { | |||
for(int i<nowiki> =</nowiki> 0;i<1000;i++) { | |||
Stack<double,1000000> s; | |||
} | |||
} catch(std::bad_alloc &) { | |||
CPPUNIT_ASSERT(0); | |||
}; | |||
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 | |||
{operator new} 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ę {equal} która porównuje dwa stosy, opróżniając | |||
je, a następnie uzupęłniając z powrotem. Kod znajduję się w pliku | |||
{mod09/exercises/stack_test_cppunit.cpp}<tt>stacktestcppunit.cpp</tt>. | |||
Częstym błedem 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ę {inc} | |||
która zwiększa każdy element stosu liczb całkowitych o jeden. | |||
W przypadku wspołdzielenia reprezentacji nastąpi zwiększenie obu | |||
stosów i oba stosy dalej będą równe. | |||
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 | |||
{mod09/exercises/stack_test_cppunit.cpp}<tt>stacktestcppunit.cpp</tt>. |
Wersja z 21:05, 26 wrz 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 {mod09/exercises/max_error.h}maxerror.h. Znajdź znajdujące się tam błędy.
Ć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 {mod09/exercises/stack_dyn.h}stackdyn.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 1
Zobacz plik {mod09/exercises/max_array_test.cpp}maxarraytest.cpp i {mod09/exercises/max_cppunit.cpp}maxcppunit.cpp.
Rozwiązanie 2
Test stosu podzielę na cztery części: pierwsza zawierać będzie test podstawowych funkcji, druga destruktora, a trzecia i czwarta konstruktora kopiującego i operatora przypisania.
Test podstawowy zawarty jest w składowej {test_base()} klasy {stack_test} w pliku {mod09/exercises/stack_test_cppunit.cpp}stacktestcppunit.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ć implementacj {stac_dyn.h}.
Zacznijmy od destruktora, zadaniem destruktora jest usunięcie pamięci zajętej przez stos, a objawem błedu 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.
try { for(int i = 0;i<1000;i++) {
Stack<double,1000000> s;
} } catch(std::bad_alloc &) { CPPUNIT_ASSERT(0); };
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 {operator new} 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ę {equal} która porównuje dwa stosy, opróżniając je, a następnie uzupęłniając z powrotem. Kod znajduję się w pliku {mod09/exercises/stack_test_cppunit.cpp}stacktestcppunit.cpp.
Częstym błedem 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ę {inc} która zwiększa każdy element stosu liczb całkowitych o jeden. W przypadku wspołdzielenia reprezentacji nastąpi zwiększenie obu stosów i oba stosy dalej będą równe.
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 {mod09/exercises/stack_test_cppunit.cpp}stacktestcppunit.cpp.