{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Systemy informatyczne analizy danych

\n", "

8. Testowanie w programowaniu zwinnym[wykład]

\n", "

Krzysztof Jassem (2023)

\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Przykłady katastrof spowodowanych złym testowaniem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Start sondy kosmicznej Mariner-1 (1962)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Start sondy kosmicznej Mariner-1 (1962)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Maszyna do radioterapii Therac-25 (1985-1987)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Zestrzelenie Airbusa 290 (1988)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Awaria sieci AT T (1990)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Błąd systemu obrony przeciwrakietowej Patriot (1992)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Awaria rakiety Ariane-5 (1996)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Błąd konwersji w sondzie Mars Climate Orbiter (1999)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "

Awaria systemu PEKA (2014)

\n", "Przeczytaj w Internecie\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Podstawowe pojęcia testowania" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Błąd (error)

\n", " \n", "Błąd to objaw nieoczekiwanego działania programu ujawniony podczas testów.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Defekt (fault)

\n", " \n", "Defekt to niedoskonałość w kodzie programu. \n", "\n", "Błąd ujawniony w czasie testów świadczy o defekcie w testowanym kodzie.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Testowanie

\n", " \n", "Testowanie to proces, który ma na celu wykazanie istnienia defektów w kodzie programu poprzez wywołanie błędów w działaniu.\n", " \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Usuwanie defektów

\n", " \n", "Usuwanie defektów to proces lokalizacji i poprawiania defektów.\n", "\n", "Procesy testowania i usuwania defektów często przeplatają się w pętlach iteracyjnych:\n", "
    \n", "
  1. Wywołaj błąd (testowanie)
  2. \n", "
  3. Zlokalizuj defekt (usuwanie defektów)
  4. \n", "
  5. Zaprojektuj naprawę defektu (usuwanie defektów)
  6. \n", "
  7. Napraw defekt (usuwanie defektów)
  8. \n", "
  9. Wróć do 1.
  10. \n", "
\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Testy bialej skrzynki

\n", " \n", "Testy białej skrzynki zakładają wgląd w wewnętrzną strukturę (kod) programu – na tej podstawie tworzone są przypadki testowe.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Testy czarnej skrzynki

\n", " \n", "W testach czarnej skrzynki program traktowany jest jak czarna skrzynka, której zawartość pozostaje nieznana; \n", "\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Zasady testowania

\n", " \n", "
    \n", "
  1. Programiści nie testują swoich programów (poza tworzeniem testów jednostkowych).\n", "
  2. Firma nie testuje swoich produktów (a dokładniej: niezbędne jest testowanie zewnętrzne)\n", "
  3. Przypadki testowe muszą być zapisane. Nie należy tworzyć przypadków ulotnych.\n", "
  4. Testowanie jest czynnością kreatywną.\n", "
\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Przypadki testowe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "

Przypadek testowy

\n", " \n", "Przypadek testowy to eksperyment przeprowadzany w testowaniu, który można opisać w kategoriach:\n", "\n", "\n", "Przypadki testowe służą do ograniczenia przestrzeni sytuacji, które należy sprawdzić, aby wywołać błąd programu. \n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Jak tworzyć przypadki testowe?\n", "\n", " * Analiza klas równoważności:\n", " * Klasa równoważności – wszystkie możliwe wartości danych wejściowych przetwarzanych w ten sam sposób. \n", " * Jeden przypadek testowy reprezentuje jedną klasę równoważności. \n", "\n", "**Przykład**: Testowany komponent systemu operuje na parze danych, z których pierwszy element oznacza godzinę, a drugi minutę. Ile można wyróżnić klas równoważności?\n", " \n", "\"Klasy\n", "\n", " * Analiza wartości brzegowych\n", " * Metoda zakłada, że błędy mogą być spowodowane nieprzewidzianym zachowaniem programu w okolicach wartości brzegowych.\n", " * Jeden przypadek testowy odpowiada jednej wartości brzegowej.\n", "\n", "**Przykład**: Testowany komponent systemu operuje na parze danych, z których pierwszy element oznacza godzinę, a drugi minutę. Ile można wyróżnić przypadków testowych metodą analizy wartości brzegowych? \n", "\n", "\"Analiza" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Jak opisywać przypadki testowe?\n", "\n", " * W metodzie białej skrzynki – za pomocą testów jednostkowych, stosując metodę analizy wartości brzegowych lub klas równoważności\n", " * W metodzie czarnej skrzynki – w postaci:\n", " * Prostej instrukcji do testera\n", " * Scenariusza przypadku testowego\n", " \n", "**Przykład opisu przypadków testowych z prostą instrukcją:**\n", "\"Opis\n", "\n", " \n", "**Przykład opisu przypadku testowego ze scenariuszem:**\n", "\"Opis" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Poziomy testowania\n", "\n", "* Znalezienie defektu jest tym trudniejsze, im dłuższa droga dzieli miejsce defektu od miejsca ujawnienia błędu.\n", "\n", "* Każdemu etapowi wytwarzania oprogramowania odpowiada określony poziom testowania.\n", "\n", "\"Poziomy\n", "(źródło: https://edux.pjwstk.edu.pl/mat/200/lec/wyklady/11_3.html)\n", "\n", "* Zarządzanie poziomami testowania ma na celu skrócenie drogi od spowodowania defektu do wykrycia błędu.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Poziomy testowania w Scrumie\n", "\n", "* W programowaniu tradycyjnym testowanie odbywa się sekwencyjnie.\n", "\n", "* W Scrumie testowanie na wszystkich poziomach odbywa się równolegle (codziennie lub co przyrost).\n", "\n", "* Wnioski:\n", "\n", " * 1: Każdy zespół powinien zawierać osobę, która zajmuje się testowaniem „na pełen etat”.\n", " * 2: W każdym sprincie powinno odbyć się testowanie na każdym poziomie.\n", " * 3: W każdym kolejnym sprincie pojawiają się nowe przypadki testowe, ale wszystkie „stare” pozostają.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Testowanie jednostkowe\n", "### Zasady testowania jednostkowego\n", "\n", " 1. Przedmiotem testowania są podstawowe jednostki programu.\n", " 2. Testy jednostkowe tworzone są przez dewelopera - programistę.\n", " 3. W testowaniu jednostkowym (jak i w całym procesie Scrum) polecana strategia to Test First.\n", " 4. Test jednostkowy powinien testować jednostkę w izolacji.  " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.1. Przedmiotem testowania są podstawowe jednostki programu\n", " * Every method needs to be tested.”\n", " * W praktyce testowane są tylko metody publiczne…\n", " * …Co oznacza, że testy metod publicznych muszą być tak dokładne, by testowały WSZYSTKIE wywoływane przez nie metody prywatne…\n", " * …Co również oznacza, że defekty w metodach prywatnych ujawnione zostaną dopiero w testach dla metod publicznych.\n", " * „Keep test logic out of production code”\n", " * Nie wprowadzaj testów jednostkowych do kodu produkcyjnego." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.2. Testy jednostkowe tworzone są przez programistę\n", " \n", "\"Testy\n", "(rysunek na podstawie: Tilo Linz, \"Testing in Scrum\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.3. W testowaniu jednostkowym (jak i w całym procesie Scrum) polecana strategia to Test First\n", "#### Zasady strategii Test First \n", " * Zanim napiszesz linijkę kodu, napisz test automatyczny, który się nie powodzi.\n", " * Pisz kod tak długo, aż powiodą się wszystkie testy.\n", "#### Zalety strategii TestFirst\n", " * Testowanie zastępuje metodę prób i błędów.\n", " * Realizacja przypadków testowych jest obiektywną miarą postępów w pracy.\n", " * Przypadki testowe zastępują formalną specyfikację.\n", " * „Test first” wprowadza porządek w interfejsach między klasami.\n", " * „Test first” świetnie wpisuje się w Scrum." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.4. Test jednostkowy powinien testować wyłącznie jednostkę (w izolacji)\n", " * Każdy obiekt testowany jest indywidualnie…\n", " * …Ale działanie obiektu może zależeć od innych komponentów…\n", " * …Które mogą być niezaimplementowane w czasie testowania.\n", " * Takie komponenty zastępuje się zamiennikami (ang. placeholder).\n", "\n", " * Typy zamienników:\n", " * Stub (zalążek) - imituje obiekt zewnętrzny, który przekazuje dane do testowanego obiektu).\n", " * Spy (szpieg) - zapamiętuje historię danych przekazywanych przez testowany obiekt).\n", " * Mock (atrapa) - \"inteligentnie\" imituje obiekt zewnętrzny, który reaguje na dane przekazywane z testowanego obiektu.\n", " * Fake (podróbka) - mocno uproszczona atrapa obiektu zewnętrznego, która nie ma wpływu na wynik testowania.\n", " * Dummy (manekin) - pusty obiekt.\n", " * Blog na temat zamienników:\n", " [Przeczytaj o zamiennikach](https://dariuszwozniak.net/posts/kurs-tdd-19-mock-stub-fake-spy-dummy)\n", " \n", " **Przykład stuba (zalążka)**: \n", " \"Przykład\n", "(rysunek na podstawie: wikipedia\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. Testowanie integracyjne w Scrumie\n", " * Celem testowania integracyjnego jest sprawdzenie, czy niezależne komponenty (np. klasy) prawidłowo ze sobą współpracują.\n", " * Testowanie wykonują deweloperzy (na swojej maszynie) lub zespół testujący (w repozytorium).\n", " * Metody testowania integracyjnego:\n", " * Metoda wielkiego wybuchu\n", " * Metoda stopniowej integracji i testowania\n", " * W metodyce Scrum możliwe jest stosowanie obu metod:\n", " * Metoda wielkiego wybuchu na zakończenie sprintu lub\n", " * Metoda Ciągłej Integracji (testowanie po każdej zmianie)\n", " * Systemy Ciągłej Integracji ułatwiają testowanie po każdej zmianie poprzez uruchamianie testów automatycznych. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Podsumowanie\n", " * Niewykryte defekty w kodzie programu mogą doprowadzić do poważnej awarii lub katastrofy.\n", " * Testowanie jest czynnością kreatywną, której celem jest wykazanie istnienia defektów w kodzie.\n", " * Przypadki testowe mają na celu ograniczenie przestrzeni wyszukiwania defektów.\n", " * Testowanie odbywa się na różnych poziomach – w tradycyjnych systemach jest to proces sekwencyjny, a w Scrumie – iteracyjny." ] } ], "metadata": { "author": "Krzysztof Jassem", "email": "jassem@amu.edu.pl", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "lang": "pl", "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" }, "subtitle": "08. Testowanie w programowaniu zwinnym[wykład]", "title": "Przygotowanie do projektu badawczo-rozwojowego", "year": "2021" }, "nbformat": 4, "nbformat_minor": 4 }