rdodA (2)


A
Lista kontrolna kodowania

Aby krótko przypomnieć najważniejsze zagadnienia niniejszej książki,
sporządziłem listę kontrolną zawierającą najważniejsze zagadnienia dotyczące
projektu, implementacji, opcji testowych, testowania i poprawiania błędów.
Zrezygnowałem przy tym z przypominania rzeczy oczywistych, jak odpowiednie
ustawienie opcji kompilatora, utrzymywanie testowej wersji programu (obok jego
wersji handlowej), konieczność usuwania pojawiających się błędów na bieżąco
itd. Warto przynajmniej pobieżnie przeczytać ją co jakiś czas, szczególnie
przed przystÄ…pieniem do rozbudowy lub modyfikacji istniejÄ…cego kodu.
Projekt
Gdy wybiera się określoną koncepcję projektową, nie należy kierować się
wyÅ‚Ä…cznie kryterium efektywnoÅ›ci lub rozmiaru kodu. Należy także uwzglÄ™d­nić
ryzyko związane z implementowaniem i konserwacją kodu oraz upewnić się, iż kod
ten istotnie realizuje założone cele projektowe. Należy wówczas zadać sobie
następujące pytania:
Czy projekt uwzględnia wszelkie możliwe sposoby zachowania się programu, czy
też istnieją w nim elementy losowe lub niezdefiniowane? Czy projekt zawiera
elementy nadmiernej elastyczności lub czyni nieuzasadnione założenia?
Czy jakiekolwiek dane przekazywane są za pośrednictwem statycznych lub
globalnych buforów? Czy jakakolwiek funkcja uzależnia swe poprawne działanie od
szczegółów implementacyjnych innych funkcji? Czy każda funkcja wykonuje tylko
jedno, ściśle określone zadanie?
Czy projekt określa sposób postępowania z danymi o specjalnej postaci? Czy kod
dokonujący tej specjalnej obsługi jest odizolowany od reszty kodu?
Czy każdy z parametrów i ewentualny wynik funkcji reprezentuje dobrze
określoną informację, czy też łączy użyteczne dane z informacjami
diagnostycznymi?
Czy sposób zdefiniowania każdej z funkcji właściwie sugeruje poprawny sposób
jej użycia?
Czy w projekcie istnieją funkcje, które mogą zwracać informację o błędzie
zamiast oczekiwanego wyniku? Czy jest możliwe takie ich przedefiniowanie, by
zawsze kończyły się bezbłędnie? Pamiętaj, iż każdy przypadek sygnalizacji błędu
musi być obsłużony przez funkcję wywołującą.
I najważniejsze: czy możliwe jest automatyczne zweryfikowanie projektu za
pomocą testowania jednostek? Jeżeli nie, należy wybrać inny projekt.
Implementacja
Po zaimplementowaniu projektu należy upewnić się, iż implementacja jest
wystarczająco solidna i odporna na błędy.
Czy implementacja realizuje projekt sensu stricto, czy tylko jego przybliżenie?
Nawet drobne uchybienia pod tym względem niosą ze sobą poważne ryzyko błędów.
Przypomnij sobie zachowanie funkcji IntToStr w sytuacji, gdy konwertowana
liczba jest najmniejszÄ… liczbÄ… ujemnÄ….
Czy przy tworzeniu kodu poczyniono jakieś nieuzasadnione założenia? Czy użyto
nieprzenośnych typów danych? Czy implementacja w jakikolwiek sposób zależna
jest od konkretnych cech sprzętu, użytego kompilatora, czy systemu
operacyjnego?
Czy obliczane wyrażenia mogą powodować nadmiar lub niedomiar?
Czy używane są jakiekolwiek ryzykowne idiomy języka C? Czy kod zawiera
zagnieżdżone operatory ?:? Czy istnieją w kodzie wyrażenia łączące operatory z
różnych grup?
Czy kod napisany jest w sposób zrozumiały dla programisty o przeciętnych
kwalifikacjach?
Czy każda z czynności zawartych w projekcie wykonywana jest w ściśle określonym
miejscu kodu, czy też istnieje kilka fragmentów wykonujących (w różny sposób)
tę samą operację? Czy występują fragmenty dokonujące obsługi "przypadków
szczególnych" i czy można je wyeliminować dzięki użyciu innego algorytmu? Czy
istnieją instrukcje if, które można wyeliminować?
Czy wywoływana jest jakakolwiek funkcja, której wykonywanie może nie zakończyć
się pomyślnie? Czy można zmienić projekt w taki sposób, by taki przypadek
wyeliminować i uniknąć kłopotliwej obsługi błędu?
Czy występują w kodzie odwołania do nieprzydzielonych obszarów pamięci, w
szczególności pamięci zwolnionej? Czy implementacja nie narusza prywatnych
danych należących do innych aplikacji?
Czy implementacja funkcji określa ograniczony rozmiar buforów wejściowych i
wyjściowych? (Funkcja wywołująca mogła ograniczyć ten rozmiar do wartości
niezbędnej z punktu widzenia wywołania.)
Elementy testowe w aplikacji
Wyposażenie kodu aplikacji w asercje (i inny kod diagnostyczny) może
przy­czynić siÄ™ do zmniejszenia czasu niezbÄ™dnego do znalezienia i popra­wienia
błędu.
Czy funkcja zawiera asercje weryfikujące poprawność jej parametrów? Jeżeli nie
jest możliwe zweryfikowanie określonego parametru, z powodu niedostatecznej
informacji o nim, czy istnieją inne, dodatkowe środki kontrolujące integralność
funkcji?
Czy przyjęte w implementacji założenia weryfikowane są za pomocą stosownych
asercji? Czy kontrolowane są przypadki nadużywania mechanizmów specyficznych
dla określonego środowiska?
Programowanie defensywne przyczynia się do łatwiejszego wykrywania wewnętrznych
błędów aplikacji czy w wersji testowej programu istnieją związane z tym
asercje?
Czy każda z asercji jest samodokumentująca? Jeżeli nie, należy opatrzyć ją
stosownymi komentarzami. W przeciwnym razie programiści, nie rozumiejąc zadania
spełnianego przez asercję, uznają ją za zbędną i usuną z kodu.
Czy przydział i zwalnianie pamięci w wersji testowej połączone jest
z wypełnianiem przydzielonych i zwalnianych bloków odpowiednim wzorcem?
Wyeliminowanie losowej zawartości pamięci przyczynia się do powtarzalności
błędów wynikających z niewłaściwego zarządzania nią.
Czy procedury organizacyjne zwalniające bloki pamięci niszczą jednocześnie ich
zawartość?
Czy wyniki produkowane przez użyty algorytm dają się zweryfikować za pomocą
innego algorytmu?
Czy w programie istnieją dane, których poprawność można by zweryfikować już
przy starcie? Czy program zawiera tablice przeglądowe i czy ich zawartość można
w jakiś sposób zweryfikować?
Testowanie
Jest sprawą niezmiernie ważną, by programiści gruntownie testowali tworzony
przez siebie kod, nawet jeżeli miałoby to powodować opóźnienia w
harmonogramie.
Czy kod kompiluje się bez ostrzeżeń? Jeżeli używasz programu lint lub innego
narzędzia diagnostycznego, czy przeprowadziłeś wszystkie dostępne testy? Czy
przetestowane zostały wszystkie jednostki kodu?
Czy wykonanie kodu prześledzone zostało za pomocą pracy krokowej? Czy
zweryfikowana została poprawność przepływu danych?
Czy kod został poddany adiustacji lub reformatowaniu? Czy został później
przetestowany ponownie?
Czy dla nowo stworzonego kodu opracowano testy weryfikujące poprawną współpracę
jednostek?
Poprawianie błędów
Gdy przystępuje się do wykrycia przyczyny błędu raportowanego przez testerów,
należy każdorazowo rozważyć następujące kwestie:
Czy raportowany błąd istotnie występuje? Jeżeli nie, należy pamiętać, iż błędy
nie znikają samoczynnie, a jedynie przestają się objawiać w sposób powtarzalny
wskutek zmian poczynionych w kodzie. Być może błąd został poprawiony przez
innego programistę. Podczas analizy kodu źródłowego, należy zawsze używać tej
jego wersji, z której korzystają testerzy.
Czy dana okoliczność jest przyczyną błędu, czy tylko jego objawem?
W jaki sposób mogłem uniknąć popełnienia tego błędu? W jaki sposób mogę go
uniknąć w przyszłości?
W jaki sposób mógłbym doprowadzić do automatycznego wykrycia tego błędu? Jakie
zmiany w testowej wersji produktu należałoby wprowadzić w związku z tym?


Wyszukiwarka

Podobne podstrony:
RDODA
rdodA 06
rdodA 05
rdoda
rdodA 06

więcej podobnych podstron