Test Driven Development

TDD, powody, dowody, studia, mantra, prawa, sposoby, warianty, narzędzia, techniki

Tomasz Borek, @LAFK_pl,

Organizacja

Przerwy, tempo, pytania - jak chcecie

O mnie

LAFK pl

Ja w sieci

LAFK pl wSieci

Zlecenia

  1. audyty kodu, infrastruktury, komponentów, systemu

  2. testy i audyty wydajności czy bezpieczeństwa

  3. wchodzę w bazy danych, GNU/Linuxy i inne pochodne Unixa

  4. programy na zlecenie

  5. prelekcje, wykłady tematyczne, warsztaty, szkolenia

Sages

  1. Sages - Szkolenia i doradztwo IT dla profesjonalistów

  2. dla firm w branży IT I spoza, jak długo w grę wchodzi tworzenie oprogramowania

Misja?

Misją firmy jest wspieranie procesu projektowania, wytwarzania i wdrażania oprogramowania w przedsiębiorstwach i instytucjach publicznych, aby zminimalizować koszty, czas i ryzyko, związane z tymi przedsięwzięciami.
http://www.sages.com.pl/sages
— Sages - o nas

O Was?

  1. Kim jesteś?

  2. Twe imię?

  3. Czemu jesteś tutaj?

O szkoleniu w punktach

  1. wprowadzenie, podstawy

  2. narzędzia, techniki

  3. zaawansowane - co: dalej, potem, następne
    …​

Będziecie sobie rączki brudzić

Łapki w górę, kto używa:

  1. Jawa IDE: Eclipse? Intellij? VSCode? Coś innego (Android Studio, STS, Netbeans…​)?

    1. Biblio: JUnit? TestNG? Spock? Mockito?

  2. Python IDE: IntelliJ PyCharm? Vim? Inne?

    1. Biblio: unittest? doctest? pytest?

  3. JS IDE: Intellij? Sublime? VSCode? Atom? Vim? Inne?

Szkolenie jest dla Was!

Jak w temacie. Jest dla Was. Was! Wyciągnijcie ile można!

Repeta i Retro

20 minut dziennie, 20 minut na koniec

będą kwizy, niniejszym ostrzegłem! :-)

Retrospektywa jedno

Realia drugie. Nie chciałbym podczas retro słyszeć, że:

  1. brakowało mi X

  2. może masz na slajdach, czekałem, ale nie masz

  3. bo tam w pracę wpadłem i nie wiedziałem…​ zapytaj!

Zmiana jest możliwa!

Mogę zmienić slajdy! Tylko muszę wiedzieć dokładnie czego dusza chce.

Pytania?

question mark
zwykle pojawia się przy okazji podsumowania. Czyli rzadko. Nie czekajcie nań!
a jak nie będzie pytań…​

Podstawy

Demonstracja: FizzBuzz

FizzBuzz

gra dla młodszych, by nauczyć ich liczenia. Dzieci krzyczą liczby, ale jeśli liczba podzielna jest przez 3, powinny krzyknąć fizz a jeśli przez 5 - buzz. Jeśli liczba podzielna jest przez 3 jak i przez 5 (np. 15), dziecko powinno powiedzieć fizzbuzz, stąd nazwa gry.

Najpierw FizzBuzz po prostu, bez testów.

Wnioski: FizzBuzz po prostu

  1. prosty problem można skiepścić

  2. nie ma pewności czy to działa nawet wtedy

  3. kilka linii kodu i kilka różnych scenariuszy testowych

  4. trudno testować monostan czy efekty uboczne (Java: statyki, voidy, Python: metody klasowe, JS: BOM, globale)

TDD?

TDD, Test Driven Development, Test Driven Design

technika programistyczna, pozwalająca by testy napędzały programowanie (lub, wedle niektórych, projektowanie), rozpropagowana przez Kenta Becka, pierwotnie jako jedna z technik XP, potem zaadoptowana do zwinnych metodyk. Polega na pisaniu testów przed pisaniem kodu produkcyjnego.

Klasyczna mantra TDD

  1. Red - zaczynamy od nieprzechodzącego testu

  2. Green - doprowadzamy test do stanu zielonego, czyli piszemy tyle kodu, by test przeszedł

  3. Refactor - zmieniamy kod, nie zmieniając zachowania, krok opcjonalny

Czerwone - Zielone - Refaktoryzacja, to klasyczna mantra TDD.

3 prawa TDD

  1. Piszesz kod produkcyjny tylko po to, by nieprzechodzący test zaczął przechodzić

  2. Piszesz minimum testu jednostkowego by nie przeszło; błędy kompilacji znaczą, że nie przeszło

  3. Piszesz minimum kodu produkcyjnego, by przeszedł test jednostkowy

Nie wolno pisać produkcyjnego kodu w innym celu lub dalej. Nie wolno pisać testów lub ich dopisywać PO osiągnięciu porażki.

3 prawa TDD wg wujka Boba

http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd

Przypominajka i FizzBuzz TDD

Prawa i mantra za nami. Test jednostkowy jest szybki, nie gada z…​ niczym właściwie. TDD to testy PRZED.

FIRST

Fast, Isolated/Independent, Repeatable, Self-explanatory/Self-validating, Thorough/Timely

Demo? FizzBuzz raz jeszcze, tym razem w TDD. Skasujcie poprzedni kod lub zacznijcie od nowa.

Wnioski: FizzBuzzTDD

  1. od jakiego testu zacząć?

  2. klasy wejść: liczba, przez 3, przez 5, przez oba

  3. grupy testów, parametryzacja rulez

  4. asercje…​

  5. nie testujemy …​

Wnioski: asercje

  1. co to jest asercja: assert i -ea, assert, console.assert lub własna funkcja

  2. miękka i twarda asercja

  3. dobry komunikat o błędzie (dobry, czyli?)

  4. ile asercji na jeden test?

Nie testujemy języka!

  1. Jawy (jak działa enum, komparator…​)

  2. Pytona (zakulisowa podmiana typu numerycznego, model danych…​)

  3. JawaSkrypta (konwersji typów, BOMa, wbudowanych API…​)

Nie testujemy dynamicznego typowania

EAFP > LBYL z Pytona obowiązuje też w JSie

EAFP

Easier to Ask For forgiveness than Permission

LBYL

Look, Before You Leap

Nie testujemy integracji!

  1. z konsolą, przeglądarką, wejściem, wyjściem :(

  2. o ile jest elementem języka, biblioteki, frameworka…​

Nie w testach jednostkowych (z niczym nie gadają? pamiętacie?), ale TAK, BARDZO TAK, w testach integracyjnych.
Ponownie: dopóki nas nie sparzy lub nie będzie to konieczne.

Wnioski: narzędzie testowe

  1. asercje

  2. identyfikacja metod testowych

  3. odpalanie metod testowych

  4. obsługa różnych wyników: sukces, porażka, ignorowanie, błąd

Dlaczego TDD może Ci pomóc

  1. Na rozum

  2. Inni mówią

  3. Wg założeń

  4. Zbadane efekty

Na rozum - brak błędów!

  1. 4 do 1

  2. koszt błędu

Koszt błędu?

The cost to fix an error found after product release was four to five times as much as one uncovered during design, and up to 100 times more than one identified in the maintenance phase.”
https://www.isixsigma.com/industries/software-it/defect-prevention-reducing-costs-and-enhancing-quality/
— Systems Sciences Institute at IBM
Laurent Bossavit has a nice piece of writing which undermines this quote as something taken out of course notes (so pretty much stated in a lecture)!
BugCostIBMSciencesInstitute

Nasa Mariner - start w 1962

Rakieta na Wenus zbacza z kursu, niszczona 290s po starcie.

One of the official reports was that the omission of a hyphen in coded computer instructions in the data editing program, resulted in incorrect guidance signals being sent to the spacecraft.
http://blog.celerity.com/the-true-cost-of-a-software-bug
— Janet Leon's Celerity blog

Koszt: 18+ mln $.

Ariane 5

ariane rocket cartoon

Koszt: 4 mln EURO.
Źródło: Bereza-Jarociński i Szomański, Inżynieria Jakości.
Obrazek za: CS Field Guide.

Toyota Lexus

In August 2009 a Lexus ES350 suddenly accelerated out of control at speeds estimated to exceed 100 mph. One of the passengers called 911 and reported that the car had "no brakes." All four passengers were killed when the car crashed.
http://blog.celerity.com/the-true-cost-of-a-software-bug
— Janet Leon's Celerity blog
In November 2009, Toyota dealers were instructed to remove and shorten the gas pedals and to update the onboard computers with a new program that would override the electronic gas pedal when the brake pedal was pressed. Toyota ended up recalling more than 9 million cars worldwide in 2010, but it wasn’t because of a mechanical issue. The cars had a software bug that caused a lag in the anti-lock-brake system.
  1. Koszt: 3 mld $ (odwołania, kampania nakłaniające do odwołań, itp.)

  2. przeciętny samochód z wyższej półki teraz ma mln linii kodu

Knight Capital

In August 2012 Knight Capital Group Inc., one of America’s largest trading firms, mistakenly sent out more than four million stock orders in less than an hour. These orders should have been spread out over a period of days—and reversing the trades cost almost half a billion dollars.
http://blog.celerity.com/the-true-cost-of-a-software-bug
— Janet Leon's Celerity blog

Koszt: 440mln $, więcej niż grupa zarobiła w całym 2011.
Zaktualizowali serwery. Poza jednym.

Podsumowanie

  1. NASA pomija - w kodzie, rakieta za 18mln$ bum

  2. NASA, stopy vs metry, prom nigdy nie ląduje

  3. Ariane 5 - kod, którego nikt nie używa, detonuje rakietę, 4mln€

  4. radioterapia śmiertelna bo zły if, umiera

  5. Toyota Lexus - zabija 4 osoby softem, 3mld$ wymiana tegoż

  6. Knight Capital - 1 serwer ze starym kodem - bankructwo (440mln$), więcej niż zarobili za cały rok 2011

Złożoność

  1. przypadkowa

  2. konieczna

  3. im większa tym gorsza

  4. FP > OOP

Złożoność cyklomatyczna

  1. ścieżki przez kod

  2. im więcej kodu tym gorzej

  3. krótkie metody dobre bo testy, czytelność, wydajność, JIT

Inni mówią

  1. czytelność

  2. jakość, mniej defektów

  3. lepszy projekt, API

  4. niższy koszt zmian

  5. dłuższy czas dowiezienia

Źródła

Problemy z tym wszystkim?

badania powinny być powtarzalne!

  1. jaki projekt i czemu robimy go dwa razy?

  2. studenci a studenci, programiści a programiści

  3. jak długo trzeba się uczyć by być dobrym w TDD?

  4. weteran TDD a nowicjusz - wciąż to samo?

  5. jak dany uczestnik jest "dobry w TDD"?

  6. relacje to tylko relacje

To dlaczego TDD może Ci pomóc?

  1. piszesz testowalny kod

  2. błędy

  3. żywa, krzycząca dokumentacja

  4. zrozumienie kodu przez Ciebie i przez innych

  5. automatyzacja sprawdzeń

  6. prostsza weryfikacja defektów

Komunikacja testami

Ćwiczenie w grupach

Pełny cykl TDD

Klasyczna mantra nie jest kompletna i nie obejmuje niektórych przejść pomiędzy stanami

Demonstracja: stosowanie cyklu TDD

  1. test nie przechodzi

  2. test przechodzi

  3. poprawki, jeśli jest co

Mechanika TDD

  1. znamy cykl

  2. jak wybrać następny test do zaimplementowania

  3. nazewnictwo testów

Następny!

  1. co łatwe

  2. losowo

  3. co ważne

  4. wg listy

  5. wg ścieżki

Demonstracja: stos

  1. wg wariantów: co łatwe, wg ścieżki

Nazwy

  1. kluczowe

  2. notacja wielbłąda

  3. notacja węża

  4. Java vs Python

  5. should, test, given-then

Szablony testów

  1. AAA

  2. GWT

Ćwiczenie:

Rzymski Kalkulator

Jako rzymski księgowy, chciałbym mieć program do kalkulacji:

  1. I - II - III - IV - V - VI - VII - VIII - IX - X

  2. X - XX - XXX - XL - L - LX - LXX - LXXX - XC - C

  3. C M D

Pytania?

question mark

Narzędzia i techniki (Jawa)

  1. IDE

  2. JUnit 4

  3. TestNG

  4. AssertJ

  5. Mockito

Na start

IDE

  1. generacja kodu

  2. skróty klawiszowe

  3. refaktoryzacja

  4. szablony

  5. własne szablony

JUnit 4

  1. @Parameterized

  2. @Theory

  3. @Theory

  4. @Rule

  5. Assume

Przykłady

TestNG

  1. patrz prezka Tomka Kaczanowskiego

  2. patrz dokumentacja

  3. demo na żywo

AssertJ

  1. patrz strona narzędzia

  2. demo na żywo

Maven

Maven SureFire i FailSafe

Narzędzia i techniki (JS)

  1. IDE / CLI

  2. Jasmine

  3. npm i Node

Jasmine

Chai

Npm

  1. scripts: …​ tests: "…​" i npm test

  2. j.w. ale integration-tests i npm run integration-tests

Podrabiane obiekty

  1. Izolacja

  2. Prościej

  3. Unikanie komplikacji

  4. Przegięcia:

    1. podróbmy wszystko

    2. podróbmy VO

    3. Testy współpracujących obiektów

Jak podrabiać?

czyli jakie są rodzaje podróbek?

  1. wydmuszka

  2. zaślepka

  3. kadłub/szkielet

  4. fałszywka

  5. podróbka

  6. szpieg

Czym to się różni?

  1. wydmuszka - pusta w środku, nie wołaj

  2. zaślepka - ślepe wołanie, nic nie robi

  3. kadłub/szkielet - częściowa robota

  4. fałszywka - coś zrobi, uproszczonego

  5. podróbka - udaje prawdziwe

  6. szpieg - owijka na obiekt z ekstra rzeczami

Detale: wydmuszka

  1. wzorzec NullObject

  2. rzuca wyjątki na implementacji

  3. nie chcesz wołać metod, potrzebujesz po prostu obiektu

Detale: zaślepka

  1. jak wydmuszka, ale bezpieczniejsza

  2. return cokolwiek

  3. jak wyżej, ale gdy jakieś wołanie się zdarzy

Detale: kadłubek

  1. zostawiasz kadłub z klasy

  2. wypełniasz części, które Ci są potrzebne

  3. w sposób, jaki Ci pasuje

Detale: fałszywka

  1. zwykle po prostu "słabsza" implementacja

  2. DocGenerator[Simple|Basic]DocGenerator

  3. robi robotę, wystarczającą na potrzeby

  4. ręczna robota

Detale: podróbka

  1. bliska prawdziwemu obiektowi

  2. większość lub wszystkie metody

Detale: szpieg

  1. bierze prawdziwy obiekt

  2. owija się wokół niego

  3. rozmowa kontrolowana

  4. wywołania są rejestrowane

  5. przekazywane do adresata

Terminy sobie

a źródła sobie. Znajdziecie inne definicje, pisane przez ludzi płyciej lub głębiej znających temat.

Tak naprawdę: testowe implementacje, obiekty do testów, podróbka, fałszywka.
Termin podróbka może oznaczać wszystkie: kadłubek, szkielet, zaślepka, wydmuszka, szpieg, itp.

Biblioteki?

Mockito.

Ew. coś innego, jak np. EasyMock.

Źródła

Zastosowania

  1. napędzane testami tworzenie warstwy dostępu do danych

  2. napędzane testami tworzenie interfejsu użytkownika (GUI)

Przykłady

Pytania?

question mark

Obiektowość a testy

Projektowanie obiektowe
    testability, czyli projektowanie pod kątem testów
    zasady wspierające dobry design (SOLID principles, Inversion of Control/Dependency Injection, powiązania, spójność)
Trochę szerszego spojrzenia
    rodzaje i poziomy testów: jednostkowe, integracyjne, akceptacyjne...
    TDD, a może BDD (Behavior-Driven Design) lub ATDD (Acceptance TDD)?
    Podejście klasyczne vs. podejście mockowe (Classical and Mockist Testing)
Praca z odziedziczonym kodem (Legacy Code)
    jak zrefaktoryzować kod, aby dało się go pokryć testem (rozcinanie zależności / Dependency Breaking)
    zrozumienie kodu i zabezpieczenie miejsca zmiany dzięki testom charakteryzacyjnym
Kontynuacja rozwoju
    wzorce stosowania TDD
    utrzymywanie testów - jak sprawić, by służyły mi za rok równie dobrze jak dziś

Pytania?

question mark

Szerzej o testach ogólnie

  1. rodzaje

  2. piramida

  3. dalsza automatyzacja

Rodzaje aplikacji i testowanie

  1. konsolowe, graficzne, sieciowe, mobilne, chmurowe…​

  2. finansowe, wojskowe, medyczne, telekomunikacyjne…​

  3. czarno-, biało-, szaro-skrzynkowe

  4. (nie)funkcyjne, ręczne, automatyczne, zmian (regresji)

    1. wydajność, bezpieczeńśtwo, elastyczność…​

  5. dynamiczne, statyczne

Piramida testów

RDZ: obrazek stożka lodów i piramidy, warstwy 3 ODDD - integracja - jednostki, żółw, zając, dolary,
image::piramidaTestów

Warstwa testów jednostkowych

  1. pomocne w weryfikacji struktury kodu, logiki, metod, TDD, mniej BDD, szybkie, testy zmian

  2. problem: dużo szpar, w szparach ginie co nie jest "jednostką", np. wymogi jakościowe, z niczym nie gada

Warstwa testów integracyjnych

  1. pomocne w ocenie połączeń między modułami, systemem a bazą, naszego systemu z bazą, plikami, itp.

  2. problem: kosztowne! I im szersze, tym trudniej postawić diagnozę

  3. tu często dodatkowe warstwy, np. API, komponentów, REST, usług, HTTP…​

Warstwa testów ODDD

ODDD, E2E

Od Deski Do Deski; testy ścieżek, End-to-End, testy przez interfejs, testy interfejsu

  1. pomocne w symulacji użytkowników, testują interfejs użytkownika i przez niego - całą aplikację.

  2. problem: diablo kosztowne! diablo czasochłonne! diablo wrażliwe! Diabelskie nasienie po prostu. ;-)

Testy statyczne

Statyczna analiza kodu

proces sprawdzania kodu aplikacji bez uruchamiania jej. Poleca się automatyzację tegoż.

Automatyzacja: wtyczki w IDE, lintery JSa (JSHint, JSLint, ESLint), npx eslint, npm run, .git/hooks, Husky

Narzędzia i Reguły
Dobre praktyki
Automatyzacja, wtyczki i githooks

CI - CD - CP

Czyli od ręcznego do automatycznego procesu budowy kodu, albo jak nowy gość w firmie robi git push i jego zmiany lądują na produkcji by użytkownicy mogli go obsobaczyć za "cud, miód, malina" kodzik.

Ciągła integracja

CI

Continuous Integration, integracja różnych linii kodu w jedną, moje zmiany z majstrem, moje i zespołu, majstra z wersją X, itp., serce automatyzacji procesu budowania kodu

Serwery, platformy, narzędzia - wszystko po to, by proces integracji był powtarzalny, automatyczny, szybki i z jasnym rezultatem (sukces, porażka, coś nie tak - nieważne, jak długo wiemy CO).

Serce i start automatyzacji tworzenia kodu. Używane do testów wszelakich. Serio, każdych niemal.

Ciągłe dostarczanie

CD

Continuous Delivery, dostawa nowych paczek na docelowy serwer; czasem kilka serwerów po kolei (lub naraz). Niektórzy w tym terminie zawierają też wdrożenie. Niektórzy nie. Zależy czy dostawa jest dla użytkowników, czy dla adminów. Jak mamy bardziej skomplikowany proces instalacji na serwerach docelowych to zwykle dostarczamy adminom i oni zajmują się paczką dalej. Wtedy czasem zamiast dostawy jest publikacja (np. w npm czy rejestrze firmowym) a admini dostają mejla i włączają swój proces.

Ciągłe wdrożenia

CD

Continuous Deployment, wdrożenie; mając nową wersję (łatę dla) aplikacji, składamy tę poprzednią i podmieniamy na nową (idealnie bez wpływu na użytkowników).

Bywa, że proces w firmie to CI - CD - CD, gdzie pierwsze CD to dostawa do serwera a drugie CD to wdrożenie na rzeczonym serwerze (lub serwerach). Zależy od stopnia skomplikowania jednego i drugiego procesu (i tego jak to "drzewiej" bywało).

Ciągła publikacja, ciągłe wdrożenia

CP

Continuous Publishing (Publication), publikacja nowej wersji np. w npm, Maven Central, PyPi lub na GitCzymśtam. Wersje GA (General Availability, dla szerokiej publiki a nie tylko beta-testerów), "release", czy po prostu numerkowe są właśnie publikowane. Tu także usłyszycie słówko "release". Publikacja wiążę się ze zmianą oficjalnego numeru wersji i często z ogłoszeniem co to dobrego w rzeczonej nowej wersji mamy.

Diagramy i narzędzia

Czyli jak to wyglądać może i jak to się osiąga. (pliki drawio)

Pytania?

question mark

Podsumowanie

Książki:

  1. Kent Beck: TDD by Example

  2. Tomek Kaczanowski: http://kaczanowscy.pl/books/practical_unit_testing_junit_testng_mockito.html strona zawiera wersje dla JUnit i TestNG

  3. Tomek Kaczanowski: Bad tests, good tests

  4. Michael Feathers: Working Effectively with Legacy Code

  5. Laurent Bossavit: https://leanpub.com/leprechauns

  6. Nat Pryce, Steve Freeman: Growing OO Code Guided By Tests, ładnie skleja OO i testowania

TDD

  1. projekt, API, nie tylko kod

  2. 3 prawa! test przed impl., min. imp. dla przejścia testu

  3. refaktoryzacja to kosmetyka a nie nowe funkcje

  4. pełniejszy diagram:

    1. czerwone → dąż do zielonego, JAK

    2. zielone → dąż do czerwonego, CO

Obiekty do testów

Testowe (na potrzeby testów) implementacje:

  1. fałszywka, wydmuszka, zaślepka

  2. podróbka, szpieg

Czytajcie dokumentację Mockito.

Testowalny kod

Narzędzia

  1. TestNG, Mockito, Maven Surefire i FailSafe, AssertJ

  2. doctest, pytest, setup scripts, .git/hooks,

  3. Jasmine, .git/hooks, npm

  4. jak potrzeba - inne