475 lines
17 KiB
Plaintext
475 lines
17 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n",
|
||
"<div class=\"alert alert-block alert-info\">\n",
|
||
"<h1> Przygotowanie do projektu badawczo-rozwojowego</h1>\n",
|
||
"<h2> 8. <i>Testowanie w programowaniu zwinnym</i>[wykład]</h2> \n",
|
||
"<h3>Krzysztof Jassem (2021)</h3>\n",
|
||
"</div>\n",
|
||
"\n",
|
||
"![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 1. Przykłady katastrof spowodowanych złym testowaniem"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Start sondy kosmicznej Mariner-1 (1962) </h3>\n",
|
||
"<a href=\"https://plwiki.pl/Leksykon/Mariner_1\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Start sondy kosmicznej Mariner-1 (1962) </h3>\n",
|
||
"<a href=\"https://plwiki.pl/Leksykon/Mariner_1\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Maszyna do radioterapii Therac-25 (1985-1987) </h3>\n",
|
||
"<a href=\"https://ucgosu.pl/2018/09/therac-25-czyli-blad-w-sofcie-medycznym-powodujacy-smierc-pacjentow/\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Zestrzelenie Airbusa 290 (1988) </h3>\n",
|
||
"<a href=\"https://www.msn.com/pl-pl/wiadomosci/historia/jak-w-1988-roku-zestrzelono-ira%C5%84ski-samolot-pasa%C5%BCerski/ar-BBYPtLv?li=BBr5MK7\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Awaria sieci AT T (1990) </h3>\n",
|
||
"<a href=\"https://www.computerworld.pl/news/Najgorsze-skutki-bledow-programistow,369992.html\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Błąd systemu obrony przeciwrakietowej Patriot (1992) </h3>\n",
|
||
"<a href=\"https://www.konflikty.pl/technika-wojskowa/na-ladzie/patriot-dhahran-co-sie-stalo/\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Awaria rakiety Ariane-5 (1996) </h3>\n",
|
||
"<a href=\"https://ucgosu.pl/2018/09/ariane-5-int-overflow-ktory-wysadzil-w-powietrze-rakiete/\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Błąd konwersji w sondzie Mars Climate Orbiter (1999) </h3>\n",
|
||
"<a href=\"https://ichi.pro/pl/blad-konwersji-wynoszacy-328-milionow-dolarow-271395322355666\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"\n",
|
||
"<h3> Awaria systemu PEKA (2014) </h3>\n",
|
||
"<a href=\"https://www.fakt.pl/wydarzenia/polska/poznan/awaria-systemu-peka-w-poznaniu-awaria-kart-peka/9d1pbb1\">Przeczytaj w Internecie</a>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 2. Podstawowe pojęcia testowania"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Błąd (error)</h3>\n",
|
||
" \n",
|
||
"<b>Błąd</b> to objaw nieoczekiwanego działania programu ujawniony podczas testów.\n",
|
||
" \n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Defekt (fault)</h3>\n",
|
||
" \n",
|
||
"<b>Defekt</b> to niedoskonałość w kodzie programu. \n",
|
||
"\n",
|
||
"<i>Błąd</i> ujawniony w czasie testów świadczy o <i>defekcie</i> w testowanym kodzie.\n",
|
||
" \n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Testowanie</h3>\n",
|
||
" \n",
|
||
"<b>Testowanie </b> to proces, który ma na celu <b><i>wykazanie</i></b> istnienia defektów w kodzie programu poprzez wywołanie błędów w działaniu.\n",
|
||
" \n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Usuwanie defektów</h3>\n",
|
||
" \n",
|
||
"<b>Usuwanie defektów </b> to proces lokalizacji i poprawiania defektów.\n",
|
||
"\n",
|
||
"Procesy testowania i usuwania defektów często przeplatają się w pętlach iteracyjnych:\n",
|
||
"<ol>\n",
|
||
"<li>Wywołaj błąd (testowanie)</li>\n",
|
||
"<li>Zlokalizuj defekt (usuwanie defektów)</li>\n",
|
||
"<li>Zaprojektuj naprawę defektu (usuwanie defektów)</li>\n",
|
||
"<li>Napraw defekt (usuwanie defektów)</li>\n",
|
||
"<li>Wróć do 1.</li>\n",
|
||
"</ol>\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Testy bialej skrzynki</h3>\n",
|
||
" \n",
|
||
"<b>Testy białej skrzynki</b> zakładają wgląd w wewnętrzną strukturę (kod) programu – na tej podstawie tworzone są przypadki testowe.\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Testy czarnej skrzynki</h3>\n",
|
||
" \n",
|
||
"W <b> testach czarnej skrzynki</b> program traktowany jest jak czarna skrzynka, której zawartość pozostaje nieznana; \n",
|
||
"<ul>\n",
|
||
"<li>Przypadki testowe tworzone są bez znajomości kodu.\n",
|
||
"<li>Celem testowania jest wykrycie sytuacji, w których dane wejściowe przekształcane są na wyniki niezgodnie z oczekiwaniami.\n",
|
||
"</ul>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-info alert-success\">\n",
|
||
"<h3>Zasady testowania</h3>\n",
|
||
" \n",
|
||
"<ol>\n",
|
||
"<li> Programiści nie testują swoich programów (poza tworzeniem testów jednostkowych).\n",
|
||
"<li> Firma nie testuje swoich produktów (a dokładniej: niezbędne jest testowanie zewnętrzne)\n",
|
||
"<li> Przypadki testowe muszą być zapisane. Nie należy tworzyć przypadków ulotnych.\n",
|
||
"<li> Testowanie jest czynnością kreatywną.\n",
|
||
"</ol>\n",
|
||
"\n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## 3. Przypadki testowe"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"<div class=\"alert alert-block alert-success\">\n",
|
||
"<h3>Przypadek testowy</h3>\n",
|
||
" \n",
|
||
"<b>Przypadek testowy</b> to eksperyment przeprowadzany w testowaniu, który można opisać w kategoriach:\n",
|
||
"<ul>\n",
|
||
"<li> wartości wprowadzanych danych, \n",
|
||
"<li> akcji wykonywanej przez użytkownika\n",
|
||
"<li> oczekiwanych wyników. \n",
|
||
"</ul>\n",
|
||
"\n",
|
||
"Przypadki testowe służą do <b>ograniczenia</b> przestrzeni sytuacji, które należy sprawdzić, aby wywołać błąd programu. \n",
|
||
"</div>"
|
||
]
|
||
},
|
||
{
|
||
"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",
|
||
"<img src=\"obrazy/klasy równoważności.png\" alt=\"Klasy równoważności przypadków testowych\" width=400px>\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",
|
||
"<img src=\"obrazy/wartości brzegowe.png\" alt=\"Analiza wartości brzegowych\" width=400px>"
|
||
]
|
||
},
|
||
{
|
||
"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",
|
||
"<img src=\"obrazy/przypadki testowe.png\" alt=\"Opis przypadków testowych\" width=900px>\n",
|
||
"\n",
|
||
" \n",
|
||
"**Przykład opisu przypadku testowego ze scenariuszem:**\n",
|
||
"<img src=\"obrazy/przypadek testowy ze scenariuszem.png\" alt=\"Opis przypadku testowego ze scenariuszem\" width=900px>"
|
||
]
|
||
},
|
||
{
|
||
"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",
|
||
"<img src=\"obrazy/poziomy testowania.gif\" alt=\"Poziomy testowania\" width=600px>\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",
|
||
"<img src=\"obrazy/testy jednostkowe.png\" alt=\"Testy jednostkowe\" width=800px>\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",
|
||
" <img src=\"obrazy/stub.png\" alt=\"Przykład zalążka\" width=400px>\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
|
||
}
|