 No dobra, zaczynamy. Nie mamy wiele czasu, ale to doskonale wiecie, co będziemy, czy działa, dobra działa. Tak, czy czas jest kluczowym zasobem. Ja studiując, ucząc się biznesu przez ostatnie 8 lat, plus równocześnie rozwijając się jako Architektu Oprogramowania zauważyłem, że czas, który poświęcamy na wytwarzanie oprogramowania, jest kosztem projektu. Czyli im szybciej coś zrobię, tym więcej zarobię na tym projekcie pieniędzy. To jest naprawdę normalne. Ale niestety te procesy, które są niezoptymalizowane powodują, że tracimy dużo czasu na sprawdzanie rzeczy, których nie powinniśmy sprawdzać, albo tracimy czas na błędy, które cały czas do nas wracają, a my nie potrafimy ich logicznie rozwiązać. I dlatego dzisiaj opowiem o TestDream and Development, ale w taki trochę inny sposób, ponieważ chciałbym przejść z wami przez proces wytwarzania oprogramowania krok po kroku, zwracając uwagę na dwie rzeczy. Pierwszą rzeczą to, ile czasu poświęcamy na testowanie, a drugą rzeczą jest to, co dokładnie będziemy testować w konkretnych scenariuszach. Dlatego przejdziemy przez implementację trzech prostych guzików w aplikacji i pokażę Wam, jak rośnie skomplikowanie oprogramowania przy trzech prostych guzikach typu Switch i jak to wpływa na jakość oprogramowania. Zaczynamy. Następnie zwróćcie uwagę, proszę, na taki eksperyment Pana Jasona Gormana, który już pewnie za jakieś 50 lat programuje. Mamy tam dwa słupki. Przepraszam odwrócić się na chwilę pecami. Mamy słupek po lewej, ten mniejszy szary i ten ciemniejszy. Pan Jason Gorman programuje już około 50 lat i to jest osoba, która programowała w TestDream and Development zanim jeszcze to miało jakokolwiek nazwę. Ten eksperyment, który widzimy tutaj na slajdzie, to czas mierzony w minutach. Zadanie polegało na tym, że jeden dzień pracował z TestDream and Development, a drugi dzień pracował bez TestDream and Development. Dzień, w którym pracował z TestDream and Development to są te mniejsze słupki po lewej stronie. Okazało się, że jednego dnia robił tak, drugiego dnia robił bez tej dyscypliny. W dzień, w który robił z dyscypliną zawsze osiągał za każdym razem rezultat tego swojego kodu wynikowego. To było przeliczanie liczb rzymskich, podstawowe kata dla programistów. Osiągał ten efekt dużo szybciej. Osiągał go chociaż z postrzeżenie z tego eksperymentu brzmiało tak. Pomimo tego, że najgorszy czas z TestDream and Development jest dużo lepszy od najlepszego czasu bez dyscypliny TestDream and Development to i tak wydawało mi się, gdy pisałem testy, że poświęcam na to dużo więcej czasu niż poświęcałem w rzeczywistości. Jaki wniosek z tego płynie? Płynie taki wniosek, że może trochę więcej kilo, może trochę więcej mózg o kalorii spalimy pisząc na początku testy, gdy doprecyzujemy to, co chcemy stworzyć zanim zaczniemy tworzyć nasze oprogramowanie. I dlatego mózgowi wydaje się, jakby to zajęło więcej czasu, ale efekt jest taki, że do wyników dochodzimy szybciej. Czyli w krótszym czasie otrzymujemy to, co chcemy otrzymać, żeby działało w taki sposób, jak ma działać. No i Uncle Bob, pan Martin mówi, że Slow and Steady wins the race, tylko że co jest tym żółwiem, bo żółw wygrał z królikiem wyścigu i niestety w oprogramowaniu tym żółwiem jest chaos, chaos na wszystkich pochłonie, albo chaos, albo rozstrzyżające się słońce. I niestety za każdym razem, gdy robimy Quick Fix, a bez testowania i wrzucamy go do repozytorium, gdy robimy deploy na których jest naszych środowisk, no to i nie sprawdzimy, czy wszyscy jakie funkcjonalności działają, no to narażamy się na to, że za 3 dni przy kolejnym Quick Fixie dołożymy kolejną warstwę chaosu do naszego programowania, nie mając pewności, czy to będzie działało czy nie. I teraz tak, zabieram was w podróż, w której przejdziemy przez implementację trzech prostych guzików. Zadanie jest całkiem proste, musimy zainplementować prosty guzik, który ma dwa możliwe stany. Jak widzicie, ma on zmieniać stan w naszej aplikacji z Dark Mode'u na Light Mode. Nic jakby skomplikowanego. Jak się domyślamy, ten guzik ma dwa możliwe stany, on i off, nie ma ich więcej. Jeżeli zainplementujemy to, to jakby testowanie stanu on i testowanie stanu off zajmuje nam równo po minucie, zapamiętajmy to. Dwa możliwe stany i każdy będziemy testować po minucie. Zainplementowaliśmy właśnie to nasze zadanie, zostało one skończone. No i co, testujemy sobie nasze zadanie, poświęcamy minutę na stan off, aplikacja działa prawidłowo, wszystkie stany działają. Poświęcamy minutę na stan off, sprawdzamy czy wszystko działa, działa, oddajemy nasz produkt. No i przechodzimy do kolejnego zadania. Czyli znowu, tak samo słuchajcie, znowu guzik, on i off, dwa możliwe stany, każdy testujemy po minucie. I pojawiać takie pytanie, skończyłem już to, skończyłem już implementację tego zadania, więc chciałbym sprawdzić czy działa, sprawdzam czas on, znaczy stan on działa, sprawdzam stan off również działa, czyli poświęciłem dwie minuty. Ale pojawia się pytanie, skoro zainplementowałem drugi guzik, to czy powinienem teraz sprawdzić, czy pierwszy dalej działa, czy zmiany w pierwszym jak będą on na off przełączane, to czy dalej będzie to działało. No bo wyjdźmy z założenia, znaczy postawmy takie pytanie, czy jestem w 100% pewien, tak, jaki był scope tych zmian, które wprowadziłem w oprogramowaniu. Niestety nasz prosty, trywialny mózg nie jest w stanie ogarnąć tego, jak wpłynie to na resztę aplikacji, bo te błędy bardzo często albo jakby rzeczy, które zmieniamy, mogą mieć wpływ na naprawdę takie elementy naszej aplikacji. Które nigdy byśmy w życiu nie pomyśleli, że one są w jakikolwiek sposób od siebie zależne, jest to dla nas trudny proces. Więc skoro z drugiego zadania przechodzę i wracam, testuję znowu to pierwsze zadanie, to zobaczcie, że przy drugim zadaniu miałam dwa stany, poświęciłem na to dwie minuty, wracam do pierwszego zadania i pojawia się pytanie, czyli czy gotowe zadanie testujemy tylko raz. Bo mamy już dowód na to, że przechodzimy z drugiego zadania, czyli z drugiego naszego, tego guzika typu switch i przychodzimy do pierwszego i znowu musimy go przetestować. Czyli tu mamy dwa razy po minucie, w poprzednim mamy dwa razy po minucie. W teorii zaraz przejdziemy do wykresu, zobaczymy, jak się zamienia ilość czasu testowania, bo jest z tych stanów tak naprawdę więcej. Czyli mamy drugie zadanie, tak, zainplementowaliśmy drugie zadanie, mamy już dwa nasze guziki. No właśnie i tak jak powiedziałem, czy jesteśmy w pewnym z tego zakresu prowadzanych zmian, no nie jesteśmy, więc dlatego sprawdziliśmy ten pierwszy i drugi. Wprowadzamy trzeci guzik, bardzo proste, znowu mamy stan on i of i kilka drobny drobiazgu będzie nam się zmieniało w naszej aplikacji. Zarówno stan of, jak i on będziemy testowali tak po minucie. I tak, zobaczmy, a właśnie, i jakby domyślamy się, że proces wyglądał tak samo, czyli przetestowałem teraz to zadanie trzecie, to minutę poświęciłem, tak, na ten stan on, of, czyli dwie minuty poświęciłem na to. No ale pytanie, czy powinienem przetestować zadanie drugie, czy powinienem przetestować działanie zadania pierwszego. Skoro nie jestem pewien zakresu wprowadzanych zmian i nigdy nie powinienem być pewien tego, to powinienem wrócić teraz zadania drugiego do zadania pierwszego i sprawdzić, czy to działa. W teorii można by powiedzieć, że skoro każdy guzik testuje po minucie, to mam, tak, trzy razy dwa stany, to to jest sześć, ale to wcale tak nie działa, mamy dwa razy dwa razy dwa, równa się mamy osiem możliwych konfiguracji, które musimy przetestować. I podsumowanie, nasz pierwszy guzik, tak, ma on i of, dwa możliwe stany, nasz drugi guzik ma on i of, zastanawiamy się ile czasu nam zajmie testowanie tego tak naprawdę. Całkowicy czas, który spędzamy. Po lewej stronie mamy, tak, jeden guzik. Jeden guzik ma dwa możliwe stany. Każdy testujemy po minucie, więc czas testowania zajmuje nam dwie minuty. Środkowy wykres, to już są dwa guziki. Dwa guziki razy, tak, dwie minuty, to już, zobaczcie, mamy cztery możliwe stany, tak, każdy testujemy po minucie. Łącznie wychodzi osiem minut testowania. Trzeci, trzeci ma dwa razy dwa razy dwa, no to już mamy, tak, osiem możliwych stanów, tak, każdy guzik testujemy po minucie, wychodzą 24 minuty testowania. Przy trzech prostych guzikach z dwoma możliwymi stanami. Mam pytanie, jak często implementujemy w oprogramowaniu tak proste funkcjonalności, które testuje się po minucie? Prawie nigdy, nie? Prawie nigdy. Więc skoro czas testowania w taki sposób rośnie, to pytanie, skoro testowałem wszystko manualnie, jak często powinienem teraz wrócić do tego testowania? Pojawił się jakiś fix, który trzeba zrobić, nie? Testuję jeszcze raz. Drobna poprawka, cokolwiek zmieniam w kodzie, powinienem przetestować znowu regresję wszystkie rzeczy, zanim wyplnę to klientowi. Czyli za każdym jednym razem mamy 24 minuty. No właśnie, a teraz zastanówmy się, skoro na samym początku pokazałem wam fajny wykres, tak? Moglibyście mi powiedzieć, że no tak, ale testowanie manualne seba jest szybsze. Sprawdzę, pyk pyk pyk, działa, koniec kropka. Ale ten wykres nie bez powodu się pojawił pierwszy, jako jeden z pierwszych slajdów. Bo zobaczcie, że napisanie testów, a potem napisanie oprogramowania jest wygodniejsze. Ba jest nawet szybsze. A jako przewagę mamy w tym, że zautomatyzowaliśmy nasze testy na początku. Przewaga polega na tym, że teraz cokolwiek się zmieni, cokolwiek będziemy chcieli tak wprowadzić do naszego oprogramowania, to te testy nie będą trwały 24 minuty, a będą trwały w granicach 3-4-5 sekund. Tak? Czyli jeżeli zacząłem od pisania testów, potem napisałem oprogramowanie, które zdaje te testy, to automatycznie dochodzę do sytuacji, w której każdy smolfik, który wprowadzam, jest testowany nie 24 minuty, tylko za każdym jednym razem oszczędzam, zamiast 24 minuty, poświęcam na to na przykład 5 sekund. Czyli zobaczcie, w jaki sposób obniżyłem koszt wytwarzania oprogramowania. Bo czas testowania skrócił się znacząco, z 24 minuty do 2 sekund, czy do 5 sekund, nawet niech to będzie minuta. Czyli za każdym razem, tak, zyskuje 23 minuty czasu mojego na przykład testera manualnego. Czas, w którym on mógłby zacząć się uczyć na przykład pisać testy automatyczne, chociażby. Tak, widzę ten śmiech. Tak, ludzie chcą się rozwijać i naprawdę jak dajemy możliwości, to będą korzystali z tego i rozwijali się, ewentualnie zmienią pracę. Jak nie będą mocno tego ścięli. OK, zobaczcie, że ten czas testowania, i wróćmy jeszcze raz do tego, że ten smallfix, tak, jakichś mamy update zależności, chcemy paczkę zabdejtować w naszym repozytorium, cokolwiek chcemy zrobić, to musimy wszystko sprawdzić. Ba, refaktor. Jak możemy robić refaktor kodu, nie mając testów? Nie chcemy w stanie zrobić porządnego refaktoru, jeżeli testów nie mamy. Wczoraj na warsztatach pokazywałem, w jaki sposób pisze się serwisy w TestDream & Development, gdy pierwszym założeniem jest to, że naprawdę zastanówmy się, czy my w ogóle wiemy, co chcemy zrobić z tym naszym oprogramowaniem, nie? A TestDream & Development to znaczy, pomyśl, jak ma być ukształtowane twoje oprogramowanie. Napisz prosty test, jeżeli tak, ten test się wywala. Teraz twórz tą magię w postaci kodu, która ten test zda. Jeżeli to już działa, to kolejny krok. Znowu napisz kawałek kodu, ja zawsze śmieję, rozpisz swoje oczekiwania względem tego serwisu, tak, żeby te testy się wywaliły, a za chwilę bierzemy i piszemy kawałek kodu, który jest w stanie te testy wypełnić. Z doświadczenia wiem, że nie warto jakby wprowadzać tych metod od razu w środowisku produkcyjnym, bo będziecie w tym nie efektywni. Ale jeżeli chcecie, to warto jest pomyśleć o TestDream & Development, chociaż te pół godziny sobie raz w tygodniu wrzucić do swojego kalendarza, żeby chociaż poćwiczyć, bo to, co zyskacie przez TestDream & Development, to nawet nie musi być wdrożone do waszych projektów, ale zobaczycie, że wasz sposób myślenia się zmieni, że zaczniecie nie od tego, bo jakby jako programiści mamy tendencję do unikania problemu, czyli okodujemy wszystko naokoło, a te miecho najtrudniejsze bardzo często zostaje na sam koniec i na dodatek nie możemy tego kodu za bardzo zmieniać, ponieważ nie wiemy, czy to będzie działało, czy to nie będzie działało. Jeżeli zaczniemy od testów, napiszemy sobie testy, które już określają wymagania względem tego naszego kodu, bo też bardzo często ja wpadałem w taką sytuację, że rozumiałem zadanie, chociaż nasz mózg lubi nas trochę z tym oszukać. Chciałem pisać testy do tego i myślę, o kurczę, muszę iść do kogoś z biznesu i zapytać się, co to tak naprawdę ma robić. Bo to jak z tymi tutorialami. Pamiętajcie, że możemy obejrzeć 50 tutoriali i nam się wydaje, że rozumiemy zagadnienie. Ale co, kładziemy ręce na klawiaturę, chcemy to napisać i jak to było dokładnie? Nasz mózg lubi nas trochę oszukać, gdy rzeczy oglądamy, w takim celu, żebyśmy za moc co się nie przepracowywali. Ale techniki w stylu zadaje sobie pytanie, co dokładnie ten człowiek zrobił i dlaczego to zrobił i tak dalej, powoduje, że mobilizujemy się do pracy nad danym zagadnieniem. I test driven development jest tak samo, czyli zależy nam na tym, żeby na początku zastanowić się, co my w ogóle chcemy zrobić. I to jest w mojej ocenie tutaj najważniejsze. Zmieni się Wam od takich prostych praktyk testowania tego w domu, pisanie sobie jakichś prostych code kata, z wykorzystaniem test driven development. Zobaczcie, że zmieni Wam się w ogóle postrzeganie tego, jak tworzyć programowanie i jak w ogóle zdawać pytania na temat oprogramowania. To wszystko z mojej strony, dziękuję.