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 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ć implementacj 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.
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 uzupełniając z powrotem. Kod znajduje się w pliku 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ę inc,
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.
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 stack_test_cppunit.cpp.