Błędy, testowanie i weryfikacja programów

Transkrypt

Błędy, testowanie i weryfikacja programów
03-10-2016
1
Błędy, testowanie i weryfikacja programów
Jak napisać bezbłędny program?
2
Klasyfikacja błędów
Błąd składniowy (błąd kompilacji)
– pomyłka (np. nieprawidłowo zapisana nazwa, brak nawiasu, itp.)
Rozwiązanie:
– kompilator: przerywa kompilację, wskazuje miejsce, poprawia programista.
Błąd czasu wykonywania (runtime error)
– nieoczekiwane przerwanie działającego programu (dane nieprawidłowe, niewykonalna
operacja (/0), błąd zapisu…)
– zdarzenie zewnętrzne zmusza program do zakończenia pracy
Rozwiązanie:
– przewidzieć!, także testować
– sprawdzać dane, oprogramować lub przejąć obsługę błędu
Błąd logiczny (np. zliczanie zdań: sekwencja kropka-spacja;  “Na rys. 2
pokazano...”
– błąd algorytmu (działa, ale źle)
Rozwiązanie: stwierdzić istnienie!
– testować; najlepiej usunąć przed oddaniem programu
– po przekazaniu:  powtarzalność błędu określić sekwencję operacji
– poprawić algorytm
lub
– wykluczyć przypadek (ograniczyć dziedzinę)
–
3
Proces a program
Program jest obiektem statycznym
– to formalny opis tego, co ma być wykonane.
Proces jest obiektem dynamicznym
– to ciąg sekwencyjnie wykonywanych instrukcji programu.
Każdy program jest skończony
– trudno napisać nieskończony program…
Procesy mogą być:
– skończone (te z reguły nas interesują)
– nieskończone (kończone mniej lub bardziej brutalnie)
4
Poprawność programów
Poprawność częściowa - po zakończeniu:
– wygenerowane dane wyjściowe są
poprawne (zgodne ze specyfikacją dla przyjętych danych wejściowych).
Poprawność całkowita
– dla wszystkich dopuszczalnych zestawów danych wejściowych proces kończy swe działanie
– wygenerowane dane wyjściowe są poprawne
(zgodne ze specyfikacja dla przyjętych danych wejściowych).
5
Dowodzenie poprawności programów
Formuły częściowej poprawności programu
– Anthony Hoare, połowa lat 60.
Metoda dowodzenia warunku stopu (60)
– R. Floyd; korzysta z zasady indukcji
6
Przykład
Zadanie:
– czy w A[1..n]
jest x?
–
1
03-10-2016
bool jest = false;
for (int i=1; i<n; i++)
if (A[i] == x) jest = true;
Dowód poprawności:
7
Dowody poprawności, ze względu na ich nietrywialność,
stosuje się dla prostych algorytmów.
W praktyce nie dowodzi się poprawności większych
8
programów.
Co z tym bezbłędnym programowaniem…
…programowanie jest dziedziną wielce zróżnicowaną, często wymagającą złożonej działalności intelektualnej.
Przypuszczenie, że kiedykolwiek można by jego naukę skondensować w postaci ścisłych recept wydaje się
niesłuszne.
Wirth, 1989
Nie istnieją żadne absolutne reguły stylu programowania tak samo jak stylu pisania, ponieważ programowanie
jest częściowo sztuką, a częściowo nauką.
McCracken, Salmon, 1987
9
Etapy rozwoju programu
Rozwiązanie zadania:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10
dokładne zdefiniowanie zadania
wyjaśnianie i usunięcie nieokreśloności w sformułowaniu problemu
wybór sposobu rozwiązania problemu
naszkicowanie rozwiązania w zrozumiałym zapisie - schemat rozwiązania
kodowanie (proces, tak naprawdę, mało twórczy…), czyli mechaniczny przekład rozwiązania problemu na poprawne
gramatycznie zdania pewnego szczególnego języka (np. Pascala).
wyłapanie i usunięcie błędów z napisanego programu - odpluskwianie
napisanie i uzupełnienie dokumentacji programu
dokładne sprawdzenie (testowanie) programu
wdrożenie i utrzymanie (konserwacja) programu
Definiowanie i szkic rozwiązania
Faza definiowania problemu - częsty błąd => wpływ na cały proces!:
– niepełne zdefiniowanie zadania programistyczne
bo nie do końca rozumiem (albo potrafię dogadać się ze zleceniodawcą)
– pozostawienie niejasności, np.:
jest jeszcze jeden przypadek, ale rzadko występuje, potem ustalimy…
to ustalimy na końcu (zakres raportu, eksportowanych danych, …)
Szkic rozwiązania: program (nie „programik”):
– oddzielne, ale powiązanych zadania, np. System Magazynowy:
rejestracja dokumentu przychodu (obrót materiałowy, kartoteka…)
rejestracja dok. rozchodu…
…
– precyzyjnie określić zadania dla każdej z części programu
– podać związki między tymi częściami
– co na „wejściu”, co na „wyjściu”
– Efekt: wykonanie każdej z tych części z osobna =>> prawidłowa całość.
11
Algorytm i kodowanie
Wybór i reprezentacja algorytmu
– jak program ma rozwiązać zadanie?
– algorytm: sposób rozwiązania problemu:
dostępny w literaturze, bibliotekach algorytmów, opracowany przez programistę
2
03-10-2016
– reprezentacja: zapis schematyczny
Kodowanie
– wybór języka, narzędzi (zależnie od problemu, innych uwarunkowań)
12
Testowanie, dokumentacja
Faza sprawdzania - testowanie
– wybrać takie dane, dla których potrafimy przewidzieć wyniki
– dokonać wszelkich możliwych testów programu.
Dokumentacja
– wykonywana na bieżąco (jest zajęciem ciągłym!),
– dokumentację tworzą wszystkie materiały z etapów poprzednich:
szczegółowy opis problemu
przedstawienie algorytmiczne zadania
program jako taki.
Dokumentacja
– informacje dla użytkownika
– dla programistów (ewentualne zmiany w przyszłości).
13
Testowanie wskazuje
na obecność błędów, nie zaś na ich brak
E. Dijkstra _
14
Konserwacja i dostosowywanie
Program to narzędzie, które należy poprawiać:
– błędy w różnych fazach jego powstawania
– dostosowywać do aktualnej sytuacji: zmiany w przepisach, różnice w konfiguracji sprzętu komputerowego, różne urządzenia
wejścia-wyjścia, różnice w realizacji języków programowania dla różnych maszyn, itp.
Aktualizacja dokumentacji!
– każda modyfikacja programu => dokładna informacja.
–
Tylko dobrze zorganizowane programy, z przejrzystą dokumentacją, mają szanse na przetrwanie.
15
Czas (w przybliżeniu)
Definiowanie, analiza wymagań użytkownika: 10%
Określenie funkcjonalności: 30%
– analiza zasobów systemowych, szkic dokumentacji, przewodnik użytkownika (pomaga w całym procesie pisania programu i jego konserwacji), analiza możliwych
błędów i opis reakcji itp.
Projektowanie programu: 20%
– wybór typów danych, algorytmu, podział programu na fragmenty, itd.
Kodowanie: 15%
– zapis projektu w języku wyższego poziomu (Pascal, C++, itd.)
Sprawdzanie poprawności: 15%
– kompilacja, usuwanie błędów, wykonanie obliczeń z danymi, które prowadzą do znanych wyników, z danymi błędnymi, przypadkowymi i rzeczywistymi
Instalacja: 10%
– umieszczenie programu na komputerze klienta, innym niż ten, na którym został przygotowany, szkolenie personelu obsługującego program itd.): 10%
Konserwacja programu: dalsze 100%...
– usługi gwarancyjne, inne błędy, usuwanie problemów związanych z nowym sprzętem itd.
16
McCrackena i Salmon, 1987
Styl programowania
McCracken, Salmon, 1987
Ogólne reguły:
– nazwy zmiennych w programie,
– wielkości stałe,
– liczba zmiennych globalnych,
– deklaracje typów zmiennych,
– odstępy, puste linie, akapity,
– „inteligentne” komentarze,
– podział na sekcje, podprogramy.
17
Nazwy zmiennych w programie
Zależnie od przeznaczenia:
– rzeczowniki dla oznaczania nazw wszelkich danych,
– czasowniki dla funkcji i procedur (rozkazy, np. dziel, dodaj itp),
– przymiotniki dla zmiennych logicznych.
Mnemoniczne nazwy
– nazwy jednolite - mało czytelne
l1, l2, l3, l55, l78, …
– lepiej - nazwy, które coś oznaczają,
3
03-10-2016
powiadamiają programistę o możliwościach modułu
wskazują sens stałych, zmiennych, typów itd.
Bardzo długie nazwy
– mało praktyczne, nieczytelne (dodajdwieliczby)
– stosować wyróżnienia!
DodajDwieLiczby, dodaj_dwie_liczby.
18
Wielkości stałe
Problemy: wielkości niecharakterystyczne
– stała pi, charakterystyczna
zapisana z 9 miejscami
zamienić na liczbę o 12 miejscach znaczących.
– rozmiar tablicy w programie (w modułach) [1..100].
automatyczna zamiana (edytor) 100  200,
przy okazji, np. temperatura procesu 100  200?
Oprócz 0, 1 i może jeszcze kilku innych
– nie używać wprost stałych w treści programu.
– zadeklarować (zgłosić) je w specjalnej części!
19
Zalecenia
Minimalizować liczbę zmiennych globalnych
– zmiana globalna, łatwa pomyłka
Deklarować typy zmiennych (using)
– podzakresy, definicje tablic, rekordów, plików itp.
Stosować odstępy, wcięcia
– puste linie (jedna, dwie) POWINNY! oddzielać różne fragmenty programu i podprogramy
– wcięcia w instrukcjach złożonych.
zdecydować się na jakiś styl
przestrzegać go (jednolita postać programu).
20
Modularyzacja, komentarze
Podział na moduły (podprogramy)
podział zadania na części
oprogramowanie i sprawdzenie części
połączenie części (wg zasady dziel i rządź)
– spójność modułów
jeśli uda się znaleźć słowo określające to co robi dany moduł,
to oznacza, że funkcja jest spójna.
– przejrzystość komunikacji modułów
„Inteligentne” komentarze
x = 7;
//pod zmienną x podstawiamy 7
???
21
Im większy program
im większy zespół
tym ważniejsze, by stosować
ww. uwagi
22
Wprowadzenie do testologii…
1.
Testy modułowe
–
–
–
–
2.
analiza ścieżek (path analysis)
użycie klas równoważności (equivalence partition)
testowanie wartości brzegowych
testowanie składniowe
Testy integracyjne pomiędzy:
– modułami: funkcjonalne
– modułami: wydajnościowe
3.
4.
5.
6.
23
Testy integracyjne pomiędzy:
systemami: funkcjonalne
systemami: wydajnościowe
systemami: regresywne
Testy w praktyce (VS)
Testy jednostkowe
4
03-10-2016
Testy jednostkowe
– sprawdzają funkcjonalność i poprawność,
Testy bazy danych
– testy jednostkowe służące do testowania procedur składowanych i innych artefaktów
bazodanowych,
Testy web
– monitorowanie ruchu pomiędzy przeglądarką a serwerem WWW.
24
… w praktyce
Testy UI
– rejestrowane są operacje wykonywane przez użytkownika (kliknięcia, wprowadzenia
określonych tekstów z klawiatury itp.); można je potem użyć np. do automatyzacji testów
funkcjonalnych;
Testy obciążeniowe
– symulujące olbrzymią liczbę użytkowników, którzy wykonują określone czynności.
25
Podstawowe narzędzia testowania
Śledzenie pracy programu: WriteLine, msgBox
26
Narzędzia środowiska
Debug: śledzenie pracy programu
– praca krokowa Step Into, Step Over
– punkty zatrzymania breakpoint
– wykonanie instrukcji i modyfikacja Immediate
27
Punkty kontrolne breakpoint
Ustawienie F9
28
Wartości zmiennych Locals
Wartości zmiennych
Zatrzymanie
– okno Locals
–
–
–
–
– okno Immediate
29
Praca krokowa
30
Zaawansowane narzędzia VS
Testy jednostkowe
Testy bazy danych
Testy web
Testy UI
Testy obciążeniowe
– http://msdn.microsoft.com/pl-pl/library/testowanie--wstep.aspx
31
Testy jednostkowe
Automatyczne testowanie aplikacji
– dla wybranych funkcji (metod)
– określić dane We/Wy
– wywołać funkcję, porównać
– komunikat o niezgodności.
Programista/tester
– uruchamia wybrane/wszystkie testy
– otrzymuje informacje o niezgodnościach.
5
03-10-2016
– otrzymuje informacje o niezgodnościach.
32
Testy jednostkowe w VS
Można oczywiście utworzyć „ręcznie”
VS – dostępny kreator
33
Generowanie testów
34
Testy jako nowy projekt
35
Wygenerowany test
Dla metody Plus()
[TestMethod()]
public void PlusTest()
{
int numberA = 0; // TODO: Initialize to an appropriate value
int numberB = 0; // TODO: Initialize to an appropriate value
int expected = 0; // TODO: Initialize to an appropriate val
int actual;
actual = Program.Plus(numberA, numberB);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
}
36
Wyniki testu
Uruchomienie
– kliknąć na nazwie testu
– z menu kontekstowego wybrać Run Tests
– komunikat z wynikami
 return numberA * numberB;
37
Dalsze informacje
Opis testów jednostkowych VS
– http://msdn.microsoft.com/pl-pl/library/testy-jednostkowe-w-visual-studio
Ogólnie o testowaniu
– http://msdn.microsoft.com/pl-pl/library/hh150106(v=vs.100).aspx
38
Z życia testera…
(za http://www.testowanie.net/testowanie/cykl-wytwarzania-oprogramowania/)
Programista tworzy „bezbłędny” kod.
Dział testów znajduje 20 błędów w aplikacji.
Programista: poprawia 10 z nich; pozostałe to nie błędy…
Dział testów: odrzuca 5 z 10 poprawek i znajduje 15 nowych błędów.
cykl poprawki/retesty powtarza się 3 razy
Naciski działu marketingu/handlowego - produkt zostaje wypuszczony.
Klient znajduje 137 błędów.
Programista pobrał już wynagrodzenie z kontraktu i jest nieosiągalny.
Nowy zespół programistów poprawia 137 błędów i wprowadza 456 nowych.
Programista, który stworzył system, wysyła kartkę z Fidżi do niedofinansowanego działu testów. Dział testów odchodzi.
Firma zostaje kupiona przez konkurencję za profity uzyskane ze sprzedaży ich ostatniej aplikacji, która zawiera 783 błędy.
Nowy szef zatrudnia programistę, aby napisał ten sam program od podstaw.
Programista tworzy „bezbłędny” kod…
6