Inżynieria oprogramowania

Podobne dokumenty
testy dynamiczne uruchamianie programu testy statyczne analiza kodu

Wykład 8. Testowanie w JEE 5.0 (1) Autor: Zofia Kruczkiewicz. Zofia Kruczkiewicz

Możliwe strategie tworzenia niezawodnego oprogramowania:

Testowanie oprogramowania. Testowanie oprogramowania 1/34

Projektowanie oprogramowania. Wykład Weryfikacja i Zatwierdzanie Inżynieria Oprogramowania Kazimierz Michalik

Wykład 7. Projektowanie kodu oprogramowania

12) Wadą modelu kaskadowego jest: Zagadnienia obowiązujące na egzaminie z inżynierii oprogramowania: 13) Wadą modelu opartego na prototypowaniu jest:

opracowanie Iteracje Rys.1. Przepływ działań w iteracyjno-rozwojowym procesie powstawiania oprogramowania obiektowego udział testowania

Maciej Oleksy Zenon Matuszyk

Automatyzacja testowania oprogramowania. Automatyzacja testowania oprogramowania 1/36

Porównanie metod i technik testowania oprogramowania. Damian Ryś Maja Wojnarowska

Techniki (automatyzacji) projektowania testów. Adam Roman WarszawQA, 24 II 2016

Kod doskonały : jak tworzyć oprogramowanie pozbawione błędów / Steve McConnell. Gliwice, cop Spis treści. Wstęp 15.

ECDL Podstawy programowania Sylabus - wersja 1.0

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Jarosław Kuchta Dokumentacja i Jakość Oprogramowania. Wymagania jakości w Agile Programming

Egzamin / zaliczenie na ocenę*

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

INŻYNIERIA OROGRAMOWANIA TESTOWANIE JEDNOSTKOWE 2015/2016

Szablony funkcji i szablony klas

Weryfikacja i walidacja. Metody testowania systemów informatycznych

Programowanie obiektowe

Projektowanie obiektowe oprogramowania Testowanie oprogramowania Wykład 13 Wiktor Zychla 2014

Liczby losowe i pętla while w języku Python

Zapisywanie algorytmów w języku programowania

TEMAT : KLASY DZIEDZICZENIE

TESTOWANIE OPROGRAMOWANIA

Programowanie obiektowe

INŻYNIERIA OPROGRAMOWANIA TESTOWANIE SYSTEMOWE

Testowanie i walidacja oprogramowania

Kontrola jakości artefaktów

Zasady organizacji projektów informatycznych

Podstawy programowania III WYKŁAD 4

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Programowanie Zespołowe

Etapy życia oprogramowania

Informatyka I. Wykład 3. Sterowanie wykonaniem programu. Instrukcje warunkowe Instrukcje pętli. Dr inż. Andrzej Czerepicki

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Podstawy Informatyki. Algorytmy i ich poprawność

Plan testów do Internetowego Serwisu Oferowania i Wyszukiwania Usług Transportowych

Główne założenia XP. Prostota (Simplicity) Komunikacja (Communication) Sprzężenie zwrotne (Feedback) Odwaga (Agressiveness)

Praca z kodem legacy : strategie, naprawa błędów, refaktoryzacja oraz

PROJEKTOWANIE. kodowanie implementacja. PROJEKT most pomiędzy specyfikowaniem a kodowaniem

Refaktoryzacja. Na podstawie

Zaawansowane programowanie w języku C++ Funkcje uogólnione - wzorce

Co to jest jest oprogramowanie? 8. Co to jest inżynieria oprogramowania? 9. Jaka jest różnica pomiędzy inżynierią oprogramowania a informatyką?

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Analiza i projektowanie oprogramowania. Analiza i projektowanie oprogramowania 1/32

lekcja 8a Gry komputerowe MasterMind

Cele przedsięwzięcia

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

Język ludzki kod maszynowy

Programowanie obiektowe

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Testowanie oprogramowania

PRZEWODNIK PO PRZEDMIOCIE

Testowanie aplikacji mobilnych na platformie Android - architektura, wzorce, praktyki i narzędzia

DOKUMENTACJA. Przeznaczenie dokumentacji użytkowej. Użytkownicy końcowi Administratorzy SKŁADNIKI DOKUMENTACJI. Synteza Dokumentacja.

OpenAI Gym. Adam Szczepaniak, Kamil Walkowiak

Jakość w procesie wytwarzania oprogramowania

Testowanie II. Celem zajęć jest zapoznanie studentów z oceną jakości testów przy wykorzystaniu metryk pokrycia kodu testami (ang. code coverage).

Szkoła programisty PLC : sterowniki przemysłowe / Gilewski Tomasz. Gliwice, cop Spis treści

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Metodyki zwinne wytwarzania oprogramowania

Interfejsy i klasy wewnętrzne

Specyfikacje formalne

Podstawy programowania w języku C

Programowanie obiektowe - 1.

Języki i metodyka programowania

Technologie cyfrowe. Artur Kalinowski. Zakład Cząstek i Oddziaływań Fundamentalnych Pasteura 5, pokój 4.15

Szablony klas, zastosowanie szablonów w programach

Całościowe podejście do testowania automatycznego dla programistów. (TDD, BDD, Spec. by Example, wzorce, narzędzia)

Programowanie poprzez testy z wykorzystaniem JUnit

Określanie wymagań. Cele przedsięwzięcia. Kontekst przedsięwzięcia. Rodzaje wymagań. Diagramy przypadków użycia use case diagrams

Testowanie I. Celem zajęć jest zapoznanie studentów z podstawami testowania ze szczególnym uwzględnieniem testowania jednostkowego.

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

Etapy życia oprogramowania. Modele cyklu życia projektu. Etapy życia oprogramowania. Etapy życia oprogramowania

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Program szkolenia: Test Driven Development (TDD) using Spock or JUnit 5

Modelowanie i Programowanie Obiektowe

Testy automatyczne. Korzystające z junit

PRZEWODNIK PO PRZEDMIOCIE

Podstawy Programowania Obiektowego

Podstawy Programowania C++

In ż ynieria oprogramowania wykład II Modele i fazy cyklu życia oprogramowania

Programowanie obiektowe

Programowanie, algorytmy i struktury danych

Cykle życia systemu informatycznego

Program szkolenia: Receptury testowania automatycznego - problemy, strategie, taktyki, techniki, narzędzia

Zaawansowane programowanie obiektowe - wykład 5

Usługa: Audyt kodu źródłowego

dr inż. Piotr Czapiewski Tworzenie aplikacji w języku Java Laboratorium 1

Lokalizacja Oprogramowania

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Język programowania DELPHI / Andrzej Marciniak. Poznań, Spis treści

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

Wprowadzenie do programowania aplikacji mobilnych

Transkrypt:

Politechnika Poznańska, Instytut Informatyki, Studia niestacjonrne Inżynieria oprogramowania Wykład 3 13.12.2015

Refaktoryzacja

Refaktoryzacja kodu Seria niewielkich modyfikacji kodu, z których każda zmienia (poprawia) wewnętrzną strukturę programu bez zmiany jego zewnętrznego działania Do pewnego! stopnia zastępuje szczegółowe projektowanie poprzedzające implementację i pozwala na poprawę błędów projektowych

Dwie drogi uzyskania dobrze zaprojektowanego oprogramowania Dobry projekt -> kod -> niewielka refaktoryzacja [Wstępny projekt] -> kod -> poważna refaktoryzacja

Dlaczego refaktoryzacja Poprawa projektu Utrzymanie kodu przy życiu, ułatwienie wprowadzania zmian, umożliwienie ponownego wykorzystania Poprawa czytelności Kod dla ludzi nie dla kompilatora Zrozumienie cudzego kodu Ułatwienie wyszukiwania błędów Np. refaktoryzacja przy debugowaniu Refaktoryzacja ma przyspieszać pracę

Kiedy refaktoryzować kod Kiedy istnieje potrzeba dodania/zmiany funkcjonalności i okazuje się to trudne Poprawa czytelności kodu Ułatwienie zmian Kiedy trudno znaleźć/zlokalizować błędy Poprawa czytelności kodu Przed przeglądem kodu

Złe zapachy (bad smells) w kodzie Powielany kod Długie metody i złożone klasy Długie listy parametrów Metody odwołujące się głównie do innych klas Powtarzające się grupy danych (Praktycznie) nie używany kod Delegowanie, nic nie wnoszące generalizacje

Złe zapachy (bad smells) w kodzie Zmienne chwilowe Zastępowanie wyrażeniami i metodami Łańcuchy wywołań foo.getbar().getfoo().getthis().getthat( ).dosomething(); Nieodpowiednie, nadmierne powiązania klas Komentarze?!?! // Dochód podstaw przychód kosz D = P K;

Jak weryfikować brak zmian zewnętrznego działania Testowanie Analiza formalna i nieformalna Unikanie dużych zmian Procedury proste kroki

Refaktoryzacja a rozszerzanie/ modyfikowanie funkcjonalności Brak zmian w funkcjonalności Nie dodaje nowych testów? (Może je zmieniać) Testy jako weryfikacja zmian Dodanie/zmiana możliwości systemu Nowe testy Cel - przejście testów

Stosunek przełożonych do refaktoryzacji Jeżeli nie jest akceptowana przez przełożonych (z braku zrozumienia), to... stosuj refaktoryzację Rób to, co według Twojej zawodowej wiedzy przynosi dobre efekty

Przykłady refaktoryzacji Dodanie parametru Ekstrakcja metody Ekstrakcja klasy Przesuń pole Przesuń metodę Zamień dziedziczenie na związek klas Ukryj pole/metodę

Refaktoryzacja w VS 2005

Procedura przesuwania metody Zadeklaruj metodę w klasie docelowej Przekopiuj kod metody Dodaj związek od klasy źródłowej do docelowej Zmień metodę źródłową na delegującą Skompiluj i przetestuj Znajdź miejsca wywołania metody Zmień na wywołania nowej metody Usuń metodę źródłową Skompiluj i przetestuj

Opis refaktoryzacji w UML

Refaktoryzacja a wzorce projektowe Refaktoryzacja często polega na zastosowaniu wzorców projektowych

Wzorzec Client-Server dla pakietów klas

Wzorzec Facade Facad

Oryginalny program

Ekstrakcja metody Powiadom

Ekstrakcja generalizacji interfejsu Widok

Modyfikacja w programie dodanie kolejnego algorytmu ewolucyjnego

Ekstrakcja generalizacji Algorytm ewolucyjny

Wzorzec Observer

Cechy (zalety) wzorca Observer Możliwość wielu sposobów prezentacji Przedmiot (subject) może nie znać (liczby) swoich obserwatorów Łatwość dodawania nowych przedmiotów i obserwatorów Możliwość dynamicznego łączenia

Projektowanie przez kontrakty (design by contract) Kontrakt oznacza zobowiązanie (klasy), do pewnego zachowania, pod warunkiem, że klient korzystający z klasy także spełni pewne warunki

Rodzaje kontraktów Implementacja interfejsu Klasa zobowiązuje się (o ile nie jest abstrakcyjna), że zaimplementuje wszystkie operacje abstrakcyjne Stałe ograniczenia dotyczące pól klas Muszą być spełnione zawsze (być może nie w trakcie realizacji pewnych metod) Warunki początkowe operacji (pre-conditions) Przy tych warunkach operacja musi zostać wykonana poprawnie. Obejmują ograniczenia dotyczące pól klas. Warunki końcowe operacji (post-conditions) Te warunki muszą być spełnione po wykonaniu operacji

Specyfikacja operacji Warunki początkowe i końcowe mogą, ale nie muszą dokładnie specyfikować działanie operacji Rozwiaz (in double a, in double b, in double c, out boolean istnieje, out double x1, out double x2) Warunek końcowy Jeżeli istnieje to a x1^2+b x1+c = 0 i a x1^2+b x1+c = 0

Niezawodność i poprawność

Niezawodność Błąd fault, error, bug Błędne wykonanie failure Czy niezawodność jest ważna? Miary niezawodności: Prawdopodobieństwo błędnego wykonania podczas realizacji transakcji Częstotliwość występowania błędnych wykonań Średni czas pomiędzy błędnymi wykonaniami Dostępność (procent czasu, w którym system jest dostępny)

Typowa zależność między gęstością błędów a niezawodnością Gęstość błędów (/1000l) Śr. czas pomiędzy błędnymi wykonaniami >30 <2 min 20-30 4-15 min 10-20 5-60 min 5-10 1-4 h 2-5 4-24 h 1-2 24-160 h <1 -

Jak poprawiać niezawodność Unikanie błędów Stosowanie warunków poprawności Odporność na błędy Testowanie Wykorzystanie gotowych komponentów Generowanie kodu

Testowanie Atestowanie i weryfikacja Atestowanie testowanie zgodności z rzeczywistymi potrzebami użytkowników Weryfikacja testowanie zgodności z wcześniej określonymi wymaganiami Cele testowania: wykrycie i usunięcie błędów w systemie - wykrywanie błędów ocena niezawodności systemu testy statystyczne

Testowanie Techniki testowania: testy dynamiczne uruchamianie programu testy statyczne analiza kodu Etapy testowania Testy jednostkowe w modelu kaskadowym wykonywane w fazie implementacji Testy integracyjne Testy systemu Testy akceptacyjne

Testy dynamiczne Jak dobrać dane testowe (w tym informacje kontrolne)? Jak określić czy wykonanie jest poprawne? Jak zlokalizować błąd?

Jak określić czy wykonanie jest poprawne? Sytuacje oczywiste, np. zawieszenie się programu, Porównanie z poprawnymi wynikami - dane z przeszłości, wyniki wyznaczone ręcznie, porównanie z wynikami innych programów (zastosowanie wyroczni) Zastosowanie warunków poprawności - ręczne, zautomatyzowane (zewnętrzny lub wewnętrzny kod) Powtarzalność wyników

Wyrocznia zwykła i odwracająca Dane wejściowe Testowany moduł Porównanie Ocena Wyrocznia zwykła Dane wejściowe Testowany moduł Wyrocznia odwracająca Ocena

Wyrocznia oceniająca Stosująca warunki poprawności Dane wejściowe Testowany moduł Wyrocznia oceniająca Ocena

Wykorzystanie sytuacji szczególnych Np. funkcja: Przyjmie wartość 0 dla x = 0, Π/2, Π...

Testy statystyczne Losowy dobór danych testowych z rozkładem prawdopodobieństwa zbliżonym do rzeczywistego Możliwość automatyzacji Wykrywają przyczyny najczęstszych błędnych wykonań Pozwalają na oszacowanie niezawodności oprogramowania!

Poprawa niezawodności w testach statystycznych

Testy nastawione na wykrywanie błędów Dane testowe dobierane są systematycznie tak, aby maksymalizować szanse na wykrycie nowych błędów Rodzaje: Funkcjonalne Strukturalne

Testy funkcjonalne Testy czarnej skrzynki Testowanie według powinności Dane testowe dobierane są na podstawie analizy specyfikacji oprogramowania Podział danych wejściowych na klasy grupy danych, dla których program działa jakościowo tak samo Testujemy dla kilku przypadków z każdej klasy Testowanie warunków granicznych

Testy funkcjonalne - przykład Zamówienia o wartości powyżej 3000 zł są realizowane w trybie przetargu, zamówienia do 3000 zł w trybie zapytania ofertowego Zamówienie o wartości do 3000 zł Zamówienie o wartości dokładnie 3000 zł Zamówienie o wartości powyżej 3000 zł

Testy funkcjonalne - przykład Sprzęt komputerowy jest zawsze kupowany w trybie przetargu sprzęt komputerowy, wartość < 3000, sprzęt komputerowy, wartość = 3000, sprzęt komputerowy, wartość > 3000, inne zakupy, wartość < 3000, inne zakupy, wartość = 3000, inne zakupy, wartość > 3000.

Testy funkcjonalne - przykład /** Posortowana lista różnych elementów *Dla każdego i, j >= 0 i < size () i < j => (*this) [i] < (*this) [j] */ class TOrderedList : public vector <double> { public: }; /** Sprawdza czy podany element jest na liście */ bool Exists (double ditem);

Klasy danych Lista jest pusta Lista nie jest pusta Podany element jest na liście Podanego elementu nie ma na liście

Testy funkcjonalne - przykład Funkcja przyjmuje dane w zakresie 1-100. Dla danych spoza tego zakresu zwraca wyjątek Klasy danych: [1-100] <1 i > 100 Wartości graniczne 1 i 100

Testy strukturalne Testy białej/szklanej skrzynki Testowanie według implementacji Dane testowe dobierane są na podstawie analizy kodu i dokumentacji technicznej

Kryterium pokrycia wszystkich instrukcji programu Dobierz zestaw danych testowych tak, aby po wykonaniu wszystkich testów każda instrukcja programu została przynajmniej raz wykonana Kryterium często nie wystarczające: int a; if (W) a = b; c = a;

Kryterium pokrycia wszystkich instrukcji programu - przykład TData TerminPlatnosci; if (Faktura.Typ == _MATERIALY) { // W1 TerminPlatnosci = min (DataAktualna + 14, Faktura.TerminPlatnosci); // B1 } else { Faktura.Sprzet = true; // B2 } if (Faktura.Wartosc > 1000) { // W2 Faktura.OsobaAkceptujaca = Dyrektor; // B3 PrzekazDoAkceptacji (TerminPlatnosci); } else { Faktura.Zaakceptowania = true; // B4 }

Kryterium pokrycia wszystkich instrukcji programu - przykład W1 Dwie ścieżki, np.: B1 B2 W1-B1-W2-B3 W1-B2-W2-B4 W2 Zapewniają pokrycie B3 B4 wszystkich instrukcji programu

Kryterium pokrycia wszystkich instrukcji warunkowych Każda instrukcja warunkowa musi być przynajmniej raz spełniona i raz nie spełniona int a; if (W) a = b; c = a; Ta instrukcja musi być raz spełniona i raz nie spełniona

Kryterium pokrycia wszystkich warunków elementarnych Każdy warunek elementarny musi być przynajmniej raz spełniony i raz nie spełniony if ((A > B) && (C == D)) Każdy warunek elementarny (A > B) i (C == D) musi być przynajmniej raz spełniony i raz nie spełniony

Kryterium pokrycia wszystkich ścieżek w grafie przepływu sterowania programu Należy przejść przez testowany fragment programu wszystkimi możliwymi ścieżkami

Kryterium pokrycia wszystkich ścieżek w grafie przepływu sterowania programu W1 Niezbędne jest pokrycie B1 B2 czterech ścieżek: W1-B1-W2-B3 W2 W1-B2-W2-B4 B3 B4 W1-B1-W2-B4 W1-B2-W2-B3

Łączenie kryteriów Jeżeli dana ścieżka jest definiowana przez warunek złożony, np. (A < B) (A > C) to należy przejść tę ścieżkę przy (nie)spełnionym każdym z tych warunków (lub nawet każdej ich kombinacji)

Testowanie pętli while (W) B1; B2 W Możliwe ścieżki: W-B2 W-B1-W-B2 W-B1-W-B1-W -B2 B1 B2... W-{B1-W} -B2

Testowanie pętli wskazówki szczególne Dobierz dane tak, aby: pętla została wykonana minimalną liczbę razy pętla została wykonana maksymalną liczbę razy pętla została wykonana przeciętną liczbę razy

Testy strukturalne - przykład /** Posortowana lista różnych elementów * Dla każdego i, j >= 0 i < size () i < j => (*this) [i] < (*this) [j] */ class TOrderedList : public vector <double> { public: /** Sprawdza czy podany element jest na liście */ bool Exists (double ditem); };

Jeżeli lista jest pusta to (W1) zwróć FALSE (B1) jeżeli podany element jest mniejszy od pierwszego elementu na liście lub większy od ostatniego elementu na liście to (W2) zwróć FALSE (B2) jeżeli podany element jest równy pierwszemu lub ostatniemu elementowi na liście to (W3) zwróć TRUE (B3) rozważaj przedział od pierwszego do ostatniego elementu na liście (B4) powtarzaj, dopóki początek i koniec przedziału nie są odległe o więcej niż 1 (W4) Znajdź element środkowy przedziału pomiędzy (B5) jeżeli podany element jest równy elementowi środkowemu to (W5) zwróć TRUE (B6) jeżeli podany element jest mniejszy od elementu środkowego przedziału to (W6) uczyń element środkowy końcem rozważanego przedziału (B7) w przeciwnym wypadku uczyń element środkowy początkiem rozważanego przedziału (B8) zwróć FALSE (B9)

W1 B1 Możliwe ścieżki W1-B1 W2 B2 W1-W2-B2 W3 B3 W1-W2-W3-B3 W1-W2-W3-B4-W4-B9 B4 W4 B9 W1-W2-W3-B4-W4-B5-W5-B6 B5 W1-W2-W3-B4-W4-{B5-W5-W6-B7-W4}- B9 W5 B6 W1-W2-W3-B4-W4-{B5-W5-W6-B8-W4}- B9 B8 W6 B7 W1-W2-W3-B4-W4-{B5-W5-W6-B8-W4 W4-B5-W5-W6-B8-W4}-B5-W5-B6

W1-B1 W1-W2-B2 Pusta lista Lista niepusta. Podany element jest mniejszy od pierwszego elementu na liście lub większy od ostatniego elementu na liście W1-W2-W3-B3 Lista niepusta. Podany element jest równy pierwszemu lub ostatniemu elementowi na liście W1-W2-W3-B4-W4-B9 Lista niepusta o długości 1 lub 2. Podany element jest większy od pierwszego elementu na liście i mniejszy od ostatniego elementu na liście W1-W2-W3-B4-W4-B5-W5-B6 Lista niepusta o długości >= 3. Podany element jest równy środkowemu elementowi listy

W1-W2-W3-B4-W4-{B5-W5-W6-B7-W4}-B9 W1-W2-W3-B4-W4-{B5-W5-W6-B8-W4}-B9 Lista niepusta o długości >= 3. Podanego elementu nie ma na liście W1-W2-W3-B4-W4-{B5-W5-W6-B8-W4 W4-B5-W5-W6-B8- W4}-B5-W5-B6 Lista niepusta o długości >= 4. Podany element jest na liście

Testy statyczne Formalne dowody poprawności Nieformalne inspekcje kodu (choć to drugie jest pojęciem szerszym) ~150 linii kodu/h Inspekcje kodu są bardzo efektywną formą testowania!

Dwa sposoby analizy programu Śledzenie przebiegu programu Liniowy przegląd kodu

Lista kontrolna typowych błędów Błąd zakresu Błędna operacja na zmiennych dynamicznych Błąd w wyrażeniu arytmetycznym/logicznym/znakowym Błąd w instrukcji warunkowej Niezainicjowanie zmiennej Niezgodność typów/błędna konwersja typów Nieuwzględnienie sytuacji wyjątkowej Błąd algorytmiczny Błąd techniczny Użycie niewłaściwej zmiennej

Rodzaje nieformalnych testów statycznych Indywidualne przeglądy kodu (cudzego lub własnego) Formalne przeglądy techniczne Praca parami

Formalne przeglądy techniczne 3-5 osób Wstępne przygotowanie 1-2h na osobę Czas trwania < 2h Uczestnicy: Autor, lider przeglądu, 2-3 recenzentów, sekretarz Prezentacja autora Decyzja Akceptacja, zwrot do małych poprawek, zwrot do dużych poprawek Podpis

Formalne przeglądy techniczne - wskazówki Ocena produktu, a nie autora Ustalenie i trzymanie się zakresu przeglądu Ograniczona dyskusja Wskazywanie błędów, a nie koniecznie rozwiązywanie Notatki Ograniczona liczba uczestników Wcześniejsze przygotowanie Lista kontrolna Zapewnienie zasobów i zaplanowanie w harmonogramie

Testy jednostkowe Testy jednostkowe nie powinny być odkładane w czasie Zasada trochę kodu, test, trochę kodu, test Fowler: Zawsze, kiedy chcesz wyprowadzić na ekran lub zobaczyć pod debuggerem jakąś zmienną lub wyrażenie, napisz prosty test lub warunek poprawności

Testy poprzedzające kodowanie Zasady stosowane np. w programowaniu ekstremalnym Wytwarzanie Najpierw test, potem funkcjonalność Wprowadzanie poprawek Najpierw test, potem poprawka

Warunki poprawności a warunki testów Warunki poprawności muszą być spełnione zawsze niezależnie od danych wejściowych Warunki testów są spełnione dla konkretnych danych

Narzędzia testów jednostkowych JUnit, CppUnit,... Funkcje Definiowanie testów jednostkowych Współdzielenie kontekstu testowania zmienne, obiekty Zestawy testów Wykonywanie testów (wzorzec Template method) Interfejs użytkownika

Przykład class Complex { friend bool operator ==(const Complex& a, const Complex& b); double real, imaginary; public: Complex( double r, double i ); };

Wykorzystanie CppUnit class ComplexNumberTest : public CppUnit::TestCase { public: ComplexNumberTest( std::string name ) : CppUnit::TestCase( name ) {} void runtest() { CPPUNIT_ASSERT( Complex (10, 1) == Complex (10, 1) ); CPPUNIT_ASSERT(!(Complex (1, 1) == Complex (2, 2)) ); } };

Testowanie połączone z zarządzaniem Fakt, że moduł/program przeszedł zestaw testów nie oznacza, że przejdzie go w przyszłości!!! Testowanie po zbudowaniu systemu Zautomatyzowany zestaw testów sprawdzających poprawność aktualnej wersji Automatyczne uruchamianie testów po wprowadzeniu zmian w repozytorium projektu

Szacowanie skuteczności testowania i liczby nieznanych błędów Posiewanie błędów Porównywanie niezależnych testów

Posiewanie błędów X - liczba nieznanych błędów w programie P liczba posianych błędów W liczba wykrytych błędów WP W liczba wykrytych posianych błędów WP/P skuteczność testowania X = P/WP (W-WP)

Porównywanie niezależnych testów W1, W2 liczby błędów wykrytych w dwóch niezależnie przeprowadzonych testach WP<W1, W2 liczba wspólnych błędów wykrytych w obu testach WP/W2, WP/W1 skuteczności testowania w testach pierwszym! i drugim! X = W2/WP (W1-WP) X = W1/WP (W2-WP)

Psychologiczne aspekty testowania Problem motywacji Czy powinno się wprowadzać oddzielny zespół testujący? Osoby szczególnie predestynowane do testowania

Unikanie błędów Kwestia nastawienia psychicznego Ile kosztuje błąd? Koszt wykrycia (błędnego wykonania) Koszt lokalizacji Koszt poprawy Koszt dystrybucji do klientów Obsługa zgłoszeń o niepoprawnym działaniu programu Koszt opinii klientów Analiza przyczyn błędów

Unikanie niebezpiecznych technik Goto, itp. Wskaźniki Liczby zmiennopozycyjne Rekursja Przerwania Obliczenia równoległe Skomplikowane wyrażenia

Zasada ograniczonego dostępu Lub zasada need to know (dostęp do danych ma tylko ten, kto musi wiedzieć) Dostęp do danych i funkcji powinny mieć tylko te fragmenty kodu, które z nich rzeczywiście korzystają Trudne do pełnego zrealizowania w typowych językach programowania Języki obiektowe Pola i metody chronione, prywatne, klasy, funkcje zaprzyjaźnione, pakiety

Stosowanie kompilatorów sprawdzających zgodność typów - wymuszanie niezgodności typów Nowoczesne kompilatory (np. C#) nie pozwalają na niebezpiecznie konwersje typów, np. double d=5.6; float f=d; //błąd kompilacji float f=(float)d; //instrukcja poprawna double d2=f; //instrukcja poprawna Wymuszanie niezgodności poprzez stosowanie własnych typów/obiektów

Pisanie czytelnego kodu TData du; TData da; TCzas cp; Cp = da du; CzasPracy = DataAktualna DataUrodzenia;

Warunki poprawności Warunek poprawności to warunek logiczny, który zawsze musi być spełniony w danym miejscu programu Jest to warunek konieczny, ale nie wystarczający poprawności programu

Źródła warunków poprawności Ograniczenia dotyczące danych zmiennych, pól, parametrów Wzrost > 0 Płaca minimalna <= Płaca maksymalna Rodzic.DataUrodzenia < Dziecko.DataUrodzenia Dla każdego i, j i < j => A [i] < A [j] Niezmienniki algorytmów

Sortowanie tablicy N elementowej Dla każdego i = 1,...,N-1 { Dla każdego j = i + 1,...,N { Jeżeli A [i] > A [j] to Zamień A [i] z A [j] } (A[i] <= A[i + k], k=1,...n-i) } Niezmiennik algorytmu

Relacja dominacji (dla maksymalizacji kryteriów) Rozwiązania niezdominowane Rozwiązania dominujące x Rozwiązania zdominowane Rozwiązania niezdominowane

Rozwiązania niezdominowane f2 f1

Uaktualnianie zbioru rozwiązań Pareto-optymalnych Uaktualnianie zbioru PP przy wykorzystaniu rozwiązania x Wszystkie rozwiązania zdominowane przez x są usuwane z PP x jest dodawane do PP jeżeli żadne rozwiązanie w PP nie dominuje x

bool bzdominowane = false; bool bdominujace = false; Dla każdego i dopóki bzdominowane == false Jeżeli X dominuje N [i] to Usuń N [i] bdominujace = true W przeciwnym wypadku jeżeli X jest zdominowane przez to N [i] bzdominowane = true Jeżeli!bZdominowane to Dodaj X do N!(bZdominowane && bdominujace)

Warunki poprawności Cechy dobrego warunku poprawności Prostota Ogólność Makro assert w C++

Odporność na błędy (tolerancja błędów) Program jest odporny na błędy jeżeli nie prowadzą one do błędnych wykonań Etapy: wykrycie błędu wyjście z błędu, tj. zakończenia pracy modułu, w którym wystąpił błąd w poprawny sposób ewentualna naprawa błędu, tj. zmiany programu tak, aby zlikwidować wykryty błąd

Jak wykrywać błędy podczas pracy programu Sprawdzanie warunków poprawności danych Porównywanie wyników różnych wersji modułu

Programowanie n-wersyjne Wersja 1 Wersja 2 Porównanie wyników... Wersja n

Programowanie n-wersyjne Załóżmy, że prawdopodobieństwo wystąpienia błędnego wykonania w module wynosi 0.01 Jeżeli są to zdarzenia niezależne to prawdopodobieństwo wystąpienia błędnego wykonania jednocześnie w dwóch wersjach modułu wynosi 0.01 0.01 = 0.0001 Prawdopodobieństwo takiego samego błędnego wykonania może być jeszcze dużo mniejsze

Technika zapasowych modułów Wersja podstawowa Weryfikacja poprawności Wersja zapasowa

Powrót do poprzedniego stanu Stosowane, jeżeli korzystamy tylko z jednej wersji modułu i nie możliwe zapewnienie poprawnego wykonania Zachowywanie poprawnego stanu Zapamiętywanie zmian Nadmiarowość danych