Automatyzacja testów. Kompletny przewodnik dla testerów oprogramowania - ebook
Automatyzacja testów. Kompletny przewodnik dla testerów oprogramowania - ebook
Ten solidny i dokładny przewodnik pomoże Ci zbudować i utrzymać skuteczną automatyzację testów W miarę jak branża związana z oprogramowaniem odchodzi stopniowo od tradycyjnych paradygmatów kaskadowych na rzecz tych bardziej zwinnych, automatyzacja testów staje się ważnym narzędziem, które pozwala zespołom deweloperów na dostarczanie oprogramowania w coraz szybszym tempie, bez obniżania przy tym jakości. Korzystanie z automatyzacji testów we właściwy i efektywny sposób nie jest proste. Wiele prób automatyzacji testów kończy się niepowodzeniem. Dużo jest czynników, które mają wpływ na wartość automatyzacji testów i jej koszty. Książka omawia te aspekty, aby ułatwić podejmowanie decyzji pozwalających na stworzenie możliwie najlepszego rozwiązania, które nie tylko sprawi, że projekt automatyzacji testów odniesie sukces, lecz także pozwoli rozwijać się całemu projektowi oprogramowania. Dzięki tej książce: Poznasz prawdziwą wartość, jakiej możesz oczekiwać od automatyzacji testów Odkryjesz kluczowe cechy, które sprawią, że Twój projekt odniesie sukces Poznasz różne czynniki, jakie należy wziąć pod uwagę podczas planowania testów automatycznych w porównaniu z testami manualnymi Określisz, kto powinien implementować testy, i poznasz konsekwencje tej decyzji Opracujesz projekt testów i dostosujesz go do architektury testowanej aplikacji Zaprojektujesz i zaimplementujesz wysoce wiarygodne testy automatyczne Zintegrujesz automatyzację testów z procesami biznesowymi zespołu tworzącego oprogramowanie Wykorzystasz automatyzację testów w celu poprawy wydajności i jakości swojej organizacji Dowiesz się, jak różne rodzaje testów automatycznych będą pasować do wybranej przez Ciebie strategii testowania, wliczając w to testowanie jednostkowe, testowanie obciążenia i wydajności, testowanie wizualne
Kategoria: | Programowanie |
Zabezpieczenie: |
Watermark
|
ISBN: | 978-83-01-20854-7 |
Rozmiar pliku: | 9,1 MB |
FRAGMENT KSIĄŻKI
Arnon Axelrod jest ekspertem w dziedzinie automatyzacji testów i pracuje jako starszy konsultant, architekt, szkoleniowiec oraz lider zespołu automatyzacji w Sela Group. W wieku 10 lat Arnon zaczął programować swój komputer ZX-Spectrum i od tamtej pory nigdy nie zatracił pasji do programowania.
Po uzyskaniu w 1999 roku tytułu licencjata z matematyki i informatyki na Uniwersytecie Ben-Guriona, Arnon rozpoczął pracę w korporacji Microsoft na stanowisku inżyniera testów oprogramowania, gdzie po raz pierwszy zetknął się z zagadnieniem automatyzacji testów. Od tamtej pory pracował w kilku nowoczesnych firmach, głównie jako inżynier oprogramowania, aż po dzień, w którym ponownie odkrył automatyzację testów z zupełnie nowej perspektywy. W 2010 roku, po kilku latach korzystania z metodyki Agile, Arnon – pracując wówczas w firmie Retalix (zakupionej później przez NCR Corporation) – zdał sobie sprawę, że efektywna automatyzacja testów, a dokładniej technika tworzenia oprogramowania sterowanego testami akceptacyjnymi (ATDD), jest niezbędna do błyskawicznego i efektywnego dostarczania wysokiej jakości oprogramowania. Podczas pracy w NCR Arnon zaprojektował infrastrukturę do automatyzacji testów, która była stosowana przez ponad 100 deweloperów i umożliwiała wykonywanie ponad 4000 testów akceptacyjnych w mniej niż 20 minut.
W 2015 roku Arnon dołączył do Sela Group, gdzie pracuje obecnie, a jego misją jest popularyzowanie swojej wiedzy wśród jak największej liczby firm i osób indywidualnych, aby pomóc im efektywniej tworzyć wysokiej jakości oprogramowanie poprzez właściwe wykorzystywanie automatyzacji testów.
W wolnym czasie Arnon lubi żeglować, grać na fortepianie i śpiewać w chórze. Mieszka w mieście Matan w Izraelu wraz ze swoją żoną, Osnat, oraz ich trzema synami: Orim, Eladem i Avivem.
Arnona Axelroda można obserwować na LinkedIn, czytać jego blog pod adresem http://blogs.microsoft.co.il/arnona/ lub też skontaktować się z nim bezpośrednio pod adresem [email protected] recenzencie technicznym
Bas Dijkstra jest konsultantem oraz szkoleniowcem w zakresie testowania i automatyzacji. Specjalizuje się w tworzeniu oraz implementowaniu strategii automatyzacji wspierających testowanie – zaczynając od udzielania odpowiedzi na pytanie „dlaczego” automatyzacja, aż po samo pisanie efektywnych rozwiązań automatyzacji.
Bas prowadzi szkolenia na różne tematy związane z automatyzacją. Ponadto regularnie publikuje posty blogowe i artykuły poświęcone różnym tematom związanym z automatyzacją testów – zarówno na swojej własnej stronie (https://www.ontestautomation.com/), jak również w innych witrynach i magazynach branżowych.Podziękowania
Przede wszystkim chciałbym podziękować mojej żonie Osnat – ta książka nie byłaby możliwa bez ogromnego wsparcia, jakie od Ciebie otrzymałem, a wiem, że nie było to proste! Choć robiłem co w mojej mocy, aby praca nad tą książką nie miała wpływu na nasze życie prywatne, to jednak pozostawiałem Cię samotną przez wiele długich wieczorów i zrzucałem na Ciebie więcej domowych obowiązków niż zazwyczaj. Nie sądzę, że w ten sposób uda mi się Ci to jakoś wynagrodzić, ale chcę Ci powiedzieć jedną rzecz: kocham Cię!
Następnie chciałbym bardzo podziękować mojemu bezpośredniemu menedżerowi i szefowi działu „DevOps and Automation” w firmie Sela, Shmulikowi Segalowi, który również wspierał mnie w tej pracy i pozwolił mi poświęcić cenny czas na pracę nad tą książką, pomimo że nie miało to żadnego ekonomicznego uzasadnienia. Shmulik, pomijając już Twoje wsparcie przy tworzeniu tej książki, dziękuję Ci jako menedżerowi i człowiekowi. Dajesz mi siłę, która pozwala mi sięgać szczytów w mojej karierze, na które nigdy nie myślałem, że będę w stanie się wznieść. A wszystko to robisz w sposób bardzo sympatyczny.
Chcę również podziękować Sashy Goldshteinowi, byłemu CTO w firmie Sela (autorowi książki Pro .NET Performance wydawnictwa Apress z 2012 roku oraz współautorowi Introducing Windows 7 for Developers od Microsoft Press z 2011 roku), który próbował odwieść mnie od pisania tej książki, ale jak widać to mu się udało. Miałeś rację przynajmniej w jednym: napisanie jej zajęło mi znacznie więcej czasu niż planowałem. Niemniej jednak znacząco mi pomogłeś i doradziłeś, w tym również zachęciłeś mnie do wysłania propozycji na książkę do wydawnictwa Apress.
Chciałbym także podziękować Zoharowi Lavy’emu z Seli, który koordynuje mój harmonogram i pomaga mi przy wielu zadaniach administracyjnych – praca z Tobą to prawdziwa przyjemność! Dziękuję całej załodze administracyjnej w Sela za całą istotną i ciężką pracę, jaką wykonujecie za kulisami, a także moim przełożonym i właścicielom Seli: dyrektorowi naczelnemu, Davidowi Basa’owi, prezesowi Sela College, Caro Segalowi oraz wiceprezesowi ds. operacji globalnych, Ishai Ramowi, za przewodnictwo Seli i uczynienie z niej tak wspaniałego miejsca do pracy. I w końcu dziękuję wszystkim moim utalentowanym współpracownikom – od każdego z Was sporo się nauczyłem.
Dziękuję Carlowi Franklinowi i Richardowi Campbellowi, prowadzącym podcast „.NET Rocks”, za poszerzanie moich horyzontów, rozbawianie mnie i sprawianie, że moja droga do pracy jest dużo bardziej przyjemna. Carl, dziękuję również za stworzenie kolekcji „muzyki do słuchania podczas kodowania”, która pomogła mi skupić się podczas pracy nad tą książką.
Muszę również podziękować wszystkim ludziom, dzięki którym książka ta nabrała właściwego kształtu: przede wszystkim Basowi Dijkstrze, mojemu świetnemu i wysoce profesjonalnemu recenzentowi technicznemu, za uważne przeczytanie każdego zdania i dostarczenie wielu cennych uwag, wniosków i sugestii, które pozwoliły mi ulepszyć tę książkę. Bez Ciebie ta książka byłaby prawdopodobnie nic nie warta…
Na koniec chcę także podziękować całemu zespołowi redaktorskiemu w Apress: Ricie Fernando Kim, mojej redaktorce koordynującej, za zarządzanie postępem moich prac i dostarczanie cennych wskazówek i porad odnośnie wszystkiego, o co pytałem lub powinienem zapytać. Laurze C. Berendson, redaktor prowadzącej, za pomoc w ukształtowaniu i zaprezentowaniu moich pomysłów w najlepszy możliwy sposób; Shivangi (Shiva) Ramachandranowi, redaktorowi, za zarządzanie tym projektem, a także Susan McDermott, starszej redaktorce, za zaakceptowanie mojej propozycji na tę książkę i przede wszystkim za wiarę we mnie. Dziękuję Wam wszystkim!Wprowadzenie
Istnieje wiele świetnych książek na temat automatyzacji testów, a w szczególności na temat najlepszych praktyk w tym zakresie. Jednak żadna z tych książek nie jest uniwersalna. Jak to ktoś kiedyś powiedział: „Te ‚najlepsze praktyki’ są zawsze kontekstowe: nawet coś tak powszechnego jak oddychanie może mieć katastrofalne skutki, jeśli kontekstem będzie swobodne nurkowanie…”.
Większość książek, które przeczytałem do tej pory na temat automatyzacji testów, skierowana jest w dużej mierze do deweloperów i skupia się głównie na testach jednostkowych lub pisanych przez deweloperów testach kompleksowych. Inne książki, które albo przeczytałem, albo o których słyszałem, poświęcone są konkretnej technologii automatyzacji testów, konkretnej metodyce, lub po prostu są już zbyt nieaktualne. Choć ogólnie zgadzam się z tym, że idea, zgodnie z którą to deweloperzy piszą testy, może być w wielu sytuacjach bardzo efektywna, to w rzeczywistości nie pasuje ona do wszystkich organizacji na wszystkich etapach. Co więcej, automatyzacja testów jest narzędziem, które służy i ma wpływ niemal na wszystkich interesariuszy organizacji tworzącej oprogramowanie, wliczając w to testerów, menedżerów produktu, architektów oprogramowania, ludzi z zespołów DevOps oraz menedżerów projektów, a nie tylko deweloperów. Ponieważ każda organizacja i każdy projekt oprogramowania jest inny, próba dostosowania technik, praktyk i narzędzi, które nie pasują do potrzeb lub umiejętności danego zespołu, może doprowadzić do niepowodzenia projektu automatyzacji testów, a w niektórych przypadkach nawet do upadku całego projektu oprogramowania.
Książka ta ma na celu zaprezentowanie szerokiego poglądu na temat automatyzacji testów, aby umożliwić czytelnikowi podejmowanie mądrych decyzji dotyczących jego konkretnego przypadku – biorąc przy tym pod uwagę jego ograniczenia i korzyści, jakie chce on uzyskać dzięki automatyzacji testów – ale również dostarczenie szczegółowych i praktycznych porad w zakresie efektywnej budowy automatyzacji testów, a przynajmniej dla większości przypadków.
Kto powinien przeczytać tę książkę?
Ponieważ automatyzacja testów wywiera wpływ na prawie wszystkich interesariuszy organizacji tworzącej oprogramowanie i w tej książce staramy się omówić prawie każdy aspekt automatyzacji testów, jest ona przeznaczona dla każdego, kto jest zaangażowany w proces tworzenia oprogramowania i chce dowiedzieć się, w jaki sposób można uzyskać więcej korzyści z automatyzacji testów. Do grona tych osób zaliczyć można: menedżerów zespołów zapewniania jakości, menedżerów zespołów deweloperów, deweloperów, testerów, architektów, menedżerów produktu (nazywanych również analitykami biznesowymi, analitykami systemu lub jeszcze inaczej), ludzi z zespołów DevOps itd. No i oczywiście deweloperów automatyzacji testów, których głównym zadaniem jest tworzenie testów automatycznych…
Znaczna część tej książki nie ma zbyt technicznego charakteru i skierowana jest do szerszego odbiorcy, jednak rozdziały od 11 do 14 są bardzo techniczne i skierowane do osób, które piszą kod i są dobrze zaznajomione z programowaniem obiektowym – w szczególności mam tu na myśli profesjonalnych deweloperów automatyzacji testów. Kod w tej części napisany został w języku C#, ale same koncepcje i pojęcia można z łatwością przenieść na inny obiektowy język programowania. Ponieważ języki C# i Java są do siebie podobne, programiści Java nie powinni mieć większego problemu ze zrozumieniem tego kodu. Jestem jednak przekonany, że również programiści innych języków będą w stanie łatwo go zrozumieć, a przynajmniej jego główne idee.
W szczególności mam nadzieję, że książkę tę przeczyta wielu menedżerów zespołów deweloperów i zapewniania jakości, ponieważ zwykle to oni mają największy wpływ na kształtowanie metodyki i procesów pracy w swojej organizacji, z którymi to automatyzacja testów powinna się integrować i wspomagać ich rozwój. Ponadto książka ta zawiera wskazówki i techniki przydatne dla osób niebędących menedżerami, pozwalające im usprawniać stosowane w organizacji metodyki i procesy pracy nawet bez żadnej formalnej władzy.
Jak zorganizowana jest ta książka?
Gdy po raz pierwszy usiadłem do pisania tej książki, starałem się myśleć o jej ogólnej strukturze, ale zorientowałem się, że będzie to bardzo trudne zadanie, ponieważ wygląda na to, że prawie każdy temat jest powiązany z wieloma innymi tematami. W tamtym czasie nie mogłem znaleźć przejrzystego i logicznego sposobu podzielenia jej treści na ogólne części, tak więc napisałem „gruntowny spis” tematów, które chciałem w tej książce omówić i po prostu zacząłem je pisać, przelewając swoją wiedzę bezpośrednio na papier (a mówiąc bardziej precyzyjnie, na klawiaturę…). Naturalnie rozpocząłem od najprostszych i najbardziej ogólnych rzeczy, a następnie stopniowo rozbudowywałem je o kolejne, bardziej zaawansowane i szczegółowe rozdziały. Ponieważ tematy te są ze sobą ściśle powiązane, często pisałem fragmenty odwołujące się do tematu, którego jeszcze nie napisałem, a przy bardziej zaawansowanych tematach odwoływałem się do wcześniejszych rozdziałów. Tak więc ostatecznie, niczym w dobrym projekcie Agile (a skoro już mowa o odwołaniach do innych rozdziałów, to zobacz rozdział 1, zawierający więcej informacji na temat metodyki Agile), ogólna struktura tej książki zaczęła się stopniowo ujawniać. W pewnym momencie zdałem sobie sprawę, że książka przybrała dosyć logiczną strukturę złożoną z dwóch części: pierwsza część odpowiada bardziej na ogólne pytania typu „dlaczego” oraz „co”, zaś druga część odpowiada na bardziej szczegółowe i techniczne pytania typu „jak”.
Ogólnie zachęcam czytelników do przeczytania całej książki od początku do końca. Ponieważ jednak książka ta skierowana jest do szerokiego grona odbiorców o różnych problemach, umiejętnościach, zainteresowaniach, potrzebach itd., można również skupić się na lekturze wyłącznie konkretnych rozdziałów, przeglądając lub nawet pomijając pozostałe. Można przy tym też skakać w przód i w tył do innych rozdziałów wspominanych w aktualnie czytanym fragmencie, aby w razie potrzeby uzupełnić swoją wiedzę. Wreszcie warto zawsze trzymać tę książkę w pobliżu, aby skorzystać z niej później, gdy zastosowanie automatyzacji testów w organizacji wystarczająco dojrzeje i zacznie stawiać czoło nowym wyzwaniom.
Oto przegląd poszczególnych części i rozdziałów tej książki:
Część I: „Dlaczego” oraz „Co”
Ta część omawia temat automatyzacji testów pod kątem wielu różnych aspektów, ale w bardziej „ogólny” sposób. Ta część książki jest niezbędna dla tych, którzy nie mają dużego doświadczenia z automatyzacją testów i chcą się dowiedzieć, jak wpasowuje się ona w szeroki obraz tworzenia oprogramowania, oraz od czego można zacząć. Zawarte w niej rozdziały pomogą nam również zrozumieć to, czego możemy, a także czego nie powinniśmy oczekiwać od automatyzacji testów. Jest to szczególnie istotne dla menedżerów zespołów deweloperów i zapewniania jakości, ponieważ omawiają one takie aspekty jak struktura biznesu, procesy pracy, architektura itd. Ta część książki pomoże nam przy podejmowaniu wielu decyzji, jakie nas czekają (czego wiele osób nie bierze nawet pod uwagę!) i pokaże nam, jaki wpływ może mieć każda z nich. Nawet jeśli nie jesteśmy menedżerami i uważamy, że nie mamy żadnego wpływu na te rzeczy, powinniśmy przeczytać rozdziały z tej części, aby zrozumieć ograniczenia i zalety w naszej obecnej sytuacji, a także być w stanie lepiej komunikować je naszym menedżerom.
Jeśli mamy już doświadczenie z automatyzacją testów, to ta pierwsza część pomoże nam poszerzyć w tym temacie nasze horyzonty i pokaże nam opcje oraz konsekwencje związane z decyzjami, które wcześniej podjęliśmy w mniej świadomy sposób.
Część II: „Jak”
Po ogólnym zapoznaniu się z dziedziną automatyzacji testów, czas zakasać rękawy i zacząć pisać testy wraz z wymaganą infrastrukturą. Po napisaniu kilku testów wyjaśniamy, w jaki sposób możemy zrobić krok na przód i najbardziej efektywnie wykorzystać automatyzację testów w cyklu tworzenia oprogramowania.
Od strony merytorycznej rozdziały w tej części można podzielić na dwie grupy (przy czym podział ten nie jest nigdzie jawnie podany, z wyjątkiem tego miejsca): rozdziały od 9 do 14 pisane są jako praktyczny samouczek, w ramach którego projektujemy i tworzymy system automatyzacji testów wraz z kilkoma testami (z użyciem narzędzia Selenium) dla istniejącego projektu open source, zaś rozdziały od 15 do 19 stanowią przewodnik po wykorzystywaniu automatyzacji testów w najbardziej efektywny sposób, pokazując przy tym, jak wyciągnąć z niej maksimum korzyści.
Większość rozdziałów z tej pierwszej grupy ma bardzo techniczny charakter, w przeciwieństwie do rozdziałów drugiej grupy. Z tego powodu pierwsza grupa rozdziałów jest bardziej odpowiednia dla deweloperów, a w szczególności dla deweloperów automatyzacji testów posiadających umiejętności w zakresie programowania obiektowego, natomiast druga grupa rozdziałów może być użyteczna dla każdego. Doświadczonych deweloperów zachęcam do podążania za samouczkiem krok po kroku i wykonywania wszystkich kroków samodzielnie, aby mogli oni doświadczyć ich w lepszym stopniu. Osoby, które nie potrafią programować, powinny przejrzeć te bardziej techniczne rozdziały w celu zapoznania się z głównymi koncepcjami, które są w nich zawarte, nawet jeśli osoby te nie zamierzają implementować ich w swoim własnym projekcie.
Oto kompletny opis rozdziałów:
Część I:
- Rozdział 1: Wartość automatyzacji testów – w tym rozdziale wyjaśniono, dlaczego automatyzacja testów jest potrzebna i jakie są jej krótko- i długoterminowe korzyści.
- Rozdział 2: Od testowania ręcznego do automatycznego – ten rozdział zawiera omówienie różnic pomiędzy testowaniem ręcznym i automatycznym oraz początek nakreślenia realistycznych oczekiwań dotyczących automatyzacji testów, ponieważ znacząco różni się ona od zwyczajnie szybszych testów manualnych.
- Rozdział 3: Ludzie i narzędzia – w tym rozdziale wyjaśniono, kto powinien pisać testy i infrastrukturę automatyzacji, oraz jakie są konsekwencje stosowania alternatywnych rozwiązań. Dodatkowo omówiono sposób dobierania właściwych narzędzi w zależności od wybranej opcji.
- Rozdział 4: Osiąganie pełnego pokrycia – w tym rozdziale nakreślono realistyczne oczekiwania dla długoterminowej mapy drogowej projektu automatyzacji, a także pokazano, w jaki sposób możemy zacząć czerpać z niej korzyści jeszcze na długo przed tym, jak automatyzacja zastąpi większość manualnych testów regresji.
- Rozdział 5: Procesy biznesowe – w tym rozdziale wyjaśniono, w jaki sposób automatyzacja testów powiązana jest z procesami biznesowymi wytwarzania oprogramowania i podano ogólny zarys tematów, które omawiane są bardziej szczegółowo pod koniec tej książki.
- Rozdział 6: Automatyzacja i architektura testów – w tym rozdziale omówiono sposób, w jaki automatyzacja testów jest powiązana z architekturą testowanego systemu, oraz dlaczego ważne jest, aby były one do siebie dostosowywane.
- Rozdział 7: Izolacja i środowiska testowe – w tym rozdziale wyjaśniono, w jaki sposób należy planować automatyzację testów oraz jej środowiska wykonywania, aby zagwarantować, że testy są wiarygodne i nie mają na nie wpływu żadne niepożądane efekty.
- Rozdział 8: Szersza perspektywa – w tym rozdziale omówiono wzajemne zależności pomiędzy wszystkimi tematami omawianymi w poprzednich rozdziałach – głównie między architekturą, strukturą biznesu, procesami biznesowymi i oczywiście automatyzacją testów. Omówiono również sposób, w jaki wszystkie te tematy odnoszą się do kultury biznesu.
Część II:
- Rozdział 9: Przygotowanie do samouczka – ten rozdział zawiera opis proces wykorzystywany w ramach samouczka, który ma również zastosowanie w większości projektów automatyzacji testów. W rozdziale tym pokazano również, jak można skonfigurować własną maszynę, aby móc samodzielnie wykonywać kolejne kroki tego samouczka.
- Rozdział 10: Projektowanie pierwszego przypadku testowego – w tym rozdziale uczymy się konkretnej techniki projektowania przypadków testowych w sposób najlepiej pasujący do testów automatycznych.
- Rozdział 11: Kodowanie pierwszego testu – w tym rozdziale pokazano, w jaki sposób możemy rozpocząć pisanie kodu dla pierwszego testu. Zaczynamy od napisania prostego szkieletu testu, w sposób, który pozwoli nam zaprojektować i utworzyć modułową infrastrukturę do wielokrotnego użytku. Pod koniec tego rozdziału nasz test będzie się kompilował, ale nie będzie on wykonywał jeszcze żadnej pracy.
- Rozdział 12: Uzupełnianie pierwszego testu – w tym rozdziale kończymy pracę, którą zaczęliśmy w rozdziale poprzednim. Pod koniec tego rozdziału będziemy mieć działający test oraz dobrze zaprojektowaną infrastrukturę, która będzie go obsługiwać.
- Rozdział 13: Badanie niepowodzeń – w tym rozdziale ćwiczymy sposób badania i radzenia sobie z rzeczywistym niepowodzeniem testu, które miało miejsce w nowej kompilacji testowanego systemu, oraz tworzenia raportu, który pomoże nam zbadać dodatkowe niepowodzenia w przyszłości.
- Rozdział 14: Dodawanie kolejnych testów – w tym rozdziale dodajemy jeden dodatkowy test. Ponadto omawiamy sposób dodawania coraz większej liczby testów przy jednoczesnym rozszerzaniu i usprawnianiu wspierającej ich infrastruktury, w tym obsługę testowania w wielu przeglądarkach, obsługę wielu środowisk i znacznie więcej.
- Rozdział 15: Ciągła integracja – w tym rozdziale (rozpoczynającym drugą grupę rozdziałów z części II) wyjaśniono, w jaki sposób możemy integrować testy do postaci kompilacji ciągłej integracji. Poza aspektami technicznymi, w rozdziale tym pokazano, jak zapewnić sukces ciągłej integracji jako narzędzia organizacyjnego i podano porady dla osób bez doświadczenia w programowaniu, jak stopniowo zmieniać na lepsze kulturę i procesy danej organizacji poprzez wykorzystywanie zalet ciągłej integracji.
- Rozdział 16: Tworzenie oprogramowania sterowane testami akceptacyjnymi (ATDD) – w tym rozdziale wyjaśniono korzyści ze stosowania oraz sposób implementacji metodyki tworzenia oprogramowania sterowanego testami akceptacyjnymi, która dzięki wykorzystaniu ciągłej integracji obejmuje cały cykl tworzenia oprogramowania i pomaga zespołowi efektywnie wykorzystywać metodykę Agile.
- Rozdział 17: Testy jednostkowe i tworzenie oprogramowania sterowane testami (TDD) – w tym rozdziale omówiono techniki, które tradycyjnie przypisywane są wyłącznie programistom aplikacji: testy jednostkowe i tworzenie oprogramowania sterowane testami, ale są tak naprawdę nieodłączną częścią automatyzacji testów.
- Rozdział 18: Inne rodzaje testów automatycznych – w tym rozdziale omówiono dodatkowe rodzaje testów automatycznych, w tym testowanie wydajności i obciążenia, testowanie w środowisku produkcyjnym, testowanie wizualne, testy instalacji, testowanie z wykorzystaniem sztucznej inteligencji i więcej.
- Rozdział 19: Co dalej? – w tym rozdziale podano pewne wskazówek dotyczące dalszego zdobywania i rozwijania umiejętności w zakresie automatyzacji testów.
Poza tymi rozdziałami, na końcu książki dostępne są również cztery dodatki:
- Dodatek A: Rzeczywiste przykłady – ten dodatek stanowi uzupełnienie rozdziału 6 („Automatyzacja i architektura testów”) i zawiera cztery rzeczywiste przykłady architektur aplikacji oraz odpowiadające im rozwiązania automatyzacji.
- Dodatek B: Mechanizm oczyszczania – ten dodatek zawiera opis sposób budowy mechanizmu oczyszczania, przedstawionego w rozdziale 7 („Izolacja i środowiska testowe”).
- Dodatek C: Projekt „Test Automation Essentials” – w tym dodatku opisałem stworzony przeze mnie projekt open source o nazwie Test Automation Essentials, zawierający wiele przydatnych narzędzi kodu (napisanych w C#) dla projektów automatyzacji testów.
- Dodatek D: Wskazówki i praktyki zwiększające produktywność programisty – ten dodatek stanowi uzupełnienie dla rozdziałów od 9 do 14 i zawiera wskazówki, które pozwolą nam zwiększyć produktywność podczas programowania. Choć wskazówki te mogą być przydatne dla dowolnego programisty, będą one szczególnie użyteczne dla programistów automatyzacji testów.
Przyjemnej lektury!Ponieważ książka ta nosi tytuł Automatyzacja testów. Kompletny przewodnik dla testerów oprogramowania, obejmuje ona teorię i praktykę, tematy na poziomie początkowym i zaawansowanym, metodologiczne aspekty i techniczne szczegóły itd. Jest tak, ponieważ próbowałem się odnieść w tej jednej książce do tak wielu różnych pytań dotyczących automatyzacji testów, jak to tylko możliwe.
W pierwszej części tej książki staramy się udzielić odpowiedzi głównie na pytania typu „dlaczego” oraz „co”, pozostawiając większość pytań typu „jak” na drugą część. Rozpoczynamy od wyjaśnienia, dlaczego w ogóle potrzebujemy automatyzacji testów i na czym tak naprawdę ona polega (jak również na czym nie polega). Następnie odpowiadamy na wiele pytań, rozwiązujemy wiele dylematów i omawiamy wiele czynników (tj. której opcji powinniśmy użyć i dlaczego) dotyczących automatyzacji testów, które będą istotne dla każdego, kto planuje rozpocząć korzystanie z automatyzacji testów lub usprawnić istniejącą automatyzację. Na koniec spoglądamy na to wszystko z dalszej perspektywy i patrzymy, jak te wszystkie elementy są ze sobą powiązane.
Przyjemnej lektury!Rozdział 1. Wartość automatyzacji testów
Ponieważ tematem tej książki jest automatyzacja testów, powinniśmy w zasadzie zacząć od jej definicji. Jednak bez nakreślenia właściwego kontekstu definicja taka może nie być wystarczająco przejrzysta i może bardziej prowadzić do dezorientacji niż zrozumienia. Jest to na tyle szeroki i zróżnicowany temat, że trudno jest tu podać taką definicję, która będzie jednocześnie dokładna, przejrzysta i obejmie wszystkie istniejące rodzaje automatyzacji testów. Gdybym jednak miał teraz przytoczyć jakąś definicję, mogłaby ona wyglądać tak: „Używanie oprogramowania w celu ułatwienia testowania innego oprogramowania”, ale nie jestem do końca pewien, na ile jest ona przydatna. Dlatego też zamiast skupiać się na formalnych definicjach, w pierwszej części książki szczegółowo analizuję ten obszerny temat, starając się w ten sposób wyjaśnić, czym tak naprawdę jest automatyzacja testów, a także – co równie istotne – czym ona nie jest!
Dlaczego potrzebujemy automatyzacji testów?
Gdy pytam moich klientów, czego spodziewają się uzyskać dzięki automatyzacji testów, najczęściej udzielaną odpowiedzią jest skrócenie czasu potrzebnego na przetestowanie oprogramowania przed jego wydaniem. Z jednej strony, choć jest to niewątpliwie ważny cel, to w zakresie korzyści, jakie możemy uzyskać dzięki automatyzacji testów, stanowi on jedynie wierzchołek góry lodowej. Ponadto osiągnięcie celu w postaci skrócenia cykli testów manualnych zajmuje zwykle sporą ilość czasu. Z drugiej strony, dużo wcześniej możemy zacząć zauważać pozostałe korzyści. Ale najpierw zobaczmy, dlaczego ten prosty cel w postaci skrócenia czasu trwania cyklu testowego stał się w ostatnich latach tak istotny.
Od modelu kaskadowego do zwinnego tworzenia oprogramowania
Mimo że niektóre organizacje korzystają z automatyzacji testów już od dekad, jednak zaczęła być ona powszechnie stosowana dopiero w ostatnich latach. Jest wiele powodów, dla których tak się stało, ale bez wątpienia można powiedzieć, że wzrost zapotrzebowania na automatyzację testów zawdzięczamy w dużej mierze odejściu od tradycyjnego modelu kaskadowego (waterfall) na rzecz programowania zwinnego (Agile software development). W tradycyjnym podejściu kaskadowym projekty oprogramowania postrzegane były jako coś jednorazowego, podobnie jak budowanie mostu. Najpierw planujemy i projektujemy oprogramowanie, potem je budujemy, a na końcu testujemy i sprawdzamy jakość końcowego produktu, naprawiając przy tym pomniejsze błędy, które znaleźliśmy. Opieramy się tu na założeniu, że jeśli fazy planowania i budowy zostały przeprowadzone poprawnie, to poza pewnymi drobnym pomyłkami programistycznymi, które możemy bardzo łatwo naprawić, wszystko powinno działać zgodnie z planem. Takie podejście sprawia, że proces weryfikowania, czy rezultat końcowy zachowuje się zgodnie ze specyfikacją, musimy przeprowadzić tylko raz. Ponowne wykonanie testu powinno mieć miejsce tylko w przypadku wykrycia jakiegoś błędu i przygotowania dla niego odpowiedniej poprawki, a następnie jej sprawdzenia. Jeśli każdy test wykonywany jest tylko raz lub dwa razy, to w wielu przypadkach znacznie taniej i łatwiej będzie wykonywać je ręcznie niż je automatyzować.
Po latach stało się jasne, że w większości przypadków podejście kaskadowe nie spełnia swoich obietnic. Większość projektów oprogramowania była już na tyle skomplikowana, że zaplanowanie i domknięcie wszystkich technicznych szczegółów w początkowej fazie tworzenia było niemożliwe. Nawet w tych przypadkach, w których było to wykonalne, do czasu ukończenia takiego projektu (trwającego zwykle kilka lat) zmieniały się zarówno sama technologia, jak i potrzeby biznesowe, czyniąc takie oprogramowanie mniej adekwatnym niż miało być początkowo. Z tych właśnie powodów szybkie reagowanie na opinie klientów stało się cenniejsze od sztywnego trzymania się początkowego planu. Wraz z upływem czasu większość przemysłu oprogramowania odeszła od tych jednorazowych projektów, rezygnując z cyklicznego wydawania nowych wersji tego samego oprogramowania co kilka lat na rzecz szybkich cyklów wydawniczych. Dzisiaj niektóre z największych firm działających w sieci Web dostarczają nowe funkcje i poprawki dla swojego oprogramowania po kilka razy dziennie, a niekiedy nawet kilka razy na minutę!
MANIFEST PROGRAMOWANIA ZWINNEGO
W 2001 roku 17 liderów z obszaru rozwoju oprogramowania sformułowało Manifest programowania zwinnego, którego treść jest następująca¹:
Odkrywamy nowe metody programowania dzięki praktyce w programowaniu i wspieraniu w nim innych. W wyniku naszej pracy zaczęliśmy bardziej cenić:
Ludzi i interakcje od procesów i narzędzi
Działające oprogramowanie od szczegółowej dokumentacji
Współpracę z klientem od negocjacji umów
Reagowanie na zmiany od realizacji założonego planu
Oznacza to, że elementy wypisane po prawej są wartościowe, ale większą wartość ma ją dla nas te, które wypisano po lewej.
Kent Beck
James Grenning
Robert C. Martin
Mike Beedle
Jim Highsmith
Steve Mellor
Arie van Bennekum
Andrew Hunt
Ken Schwaber
Alistair Cockburn
Ron Jeffries
Jeff Sutherland
Ward Cunningham
Jon Kern
Dave Thomas
Martin Fowler
Brian Marick
© 2001, autorzy powyżej
Deklaracja ta może być swobodnie kopiowana w dowolnej formie, ale wyłącznie w całości, z uwzględnieniem tej uwagi.
Oczywiście nie wszystkie firmy i zespoły przyjmują te zasady, ale prawie każdy, kto jest dziś zaangażowany w rozwój oprogramowania, preferuje szybsze dostarczanie nowych wersji (i dalsze ich dostarczanie na przestrzeni długiego okresu czasu), zamiast dostarczać tylko kilka nowych wersji z długimi przerwami między nimi. Oznacza to również, że zmiany pomiędzy kolejnymi wydaniami są teraz mniejsze niż w przypadku dostarczania nowej wersji raz na kilka lat. Naturalnie firmy tworzące oprogramowanie dla sektorów o kluczowym znaczeniu są mniej skłonne do podejmowania ryzyka, dlatego zwykle wydają one oprogramowanie w stosunkowo długich cyklach wydawniczych. Jednak już nawet i one zaczynają dostrzegać korzyści w szybszym dostarczaniu oprogramowania, przynajmniej wewnętrznie do zespołów QA.
Manualne testowanie każdej takiej wersji programu może zająć mnóstwo czasu, co stanowi oczywisty powód, dla którego automatyzacja testów stała się tak istotna. Nie jest to jednak jedyny ważny powód.
Koszt złożoności oprogramowania
Do każdej nowej wersji programu dodawane są nowe funkcje. W miarę dodawania funkcji oprogramowanie staję się coraz bardziej złożone, a wówczas coraz trudniej dodawać do niego nowe funkcje, nie psując przy tym istniejącego kodu. Jest to szczególnie widoczne przy dużej presji na szybkie dostarczanie nowych wersji oprogramowania, gdy nie poświęca się wystarczająco dużo czasu na planowanie i poprawę jakości kodu (jak to często ma miejsce w przypadku źle wdrożonej metodyki Scrum²). Ostatecznie następuje spadek szybkości dostarczania nowych wersji, czyli coś, czego chcemy uniknąć od samego początku!
Części z dodanej w ten sposób złożoności nie da się uniknąć. Będzie ona istnieć nawet wtedy, gdy skrupulatnie zaplanujemy i zaprojektujemy z góry całe oprogramowanie. Jest to tzw. złożoność wewnętrzna (inherent complexity). Jednak w większości przypadków powodami istnienia przeważającej części złożoności oprogramowania jest szybkie wprowadzanie nowych funkcji bez odpowiedniego projektu, brak komunikacji wewnątrz zespołu lub brak odpowiedniej wiedzy – czy to w zakresie wykorzystywanej technologii, czy też w obszarze potrzeb biznesowych. Teoretycznie złożoność tę można by zredukować poprzez skrzętne zaplanowanie z góry całego oprogramowania, ale w rzeczywistości jest ona naturalną częścią każdego projektu oprogramowania. Ten typ złożoności nazywany jest często złożonością przypadkową (accidental complexity).
Każda złożoność – czy to wewnętrzna, czy przypadkowa – niesie ze sobą pewien koszt. Koszt ten jest oczywiście częścią całkowitego kosztu wytworzenia oprogramowania, na który wpływ ma głównie liczba programistów i testerów pomnożona przez czas potrzebny im na dostarczenie oprogramowania (oczywiście pomnożona również przez ich wynagrodzenie). Zgodnie z powyższym, gdy złożoność fragmentu oprogramowania wzrasta, jego koszt również rośnie, ponieważ przetestowanie wszystkiego oraz naprawa znalezionych błędów (i ponowne przetestowanie kodu) wymaga większej ilości czasu. Ponadto złożoność przypadkowa sprawia również, że oprogramowanie jest bardziej ułomne i trudniejsze w utrzymaniu, a co za tym idzie, wymaga jeszcze więcej czasu na przetestowanie i naprawę błędów.
Utrzymywanie stałego kosztu
Na rysunku 1.1 pokazano to, co chcemy osiągnąć: koszt utrzymywany na stałym poziomie w miarę dodawania nowych funkcji. Niestety dodawanie nowych funkcji oznacza zwykle zwiększanie złożoności oprogramowania, co naturalnie zwiększa jego koszt. Istnieją jednak dwa czynniki, które mogą nam pomóc w utrzymaniu kosztu na stałym poziomie:
1. Minimalizowanie kosztów uruchamiania stale powiększającego się zestawu testów regresji.
2. Pisanie kodu, który jest łatwy w utrzymaniu.
Pierwszy czynnik możemy łatwo osiągnąć poprzez zautomatyzowanie większości testów. Natomiast na drugi czynnik duży wpływ ma złożoność przypadkowa, przez co znacznie trudniej go kontrolować.
W kodzie, który jest łatwy w utrzymaniu, złożoność wprowadzana do oprogramowania w wyniku dodawania do niego nowych funkcji ma bardzo mały lub zerowy wpływ na złożoność funkcji już istniejących. Oznacza to, że jeśli wzrost złożoności będziemy utrzymywać w tempie liniowym, to nadal będziemy mogli utrzymać stabilny koszt, jak to pokazano na rysunku 1.2. Oczywiście tę zdolność do dodawania złożoności chcielibyśmy zachować jedynie dla złożoności wewnętrznej (tj. nowych funkcji) i nie marnować jej na złożoność przypadkową. Niestety złożoność przypadkowa sprawia, że w większości rzeczywistych projektów, w miarę dodawania kolejnych funkcji złożoność rośnie dużo szybciej niż liniowo (patrz rysunek 1.3). To z kolei powoduje również wzrost kosztów dodawania nowych funkcji na przestrzeni czasu, co zostało przedstawione na rysunku 1.4.
Rysunek 1.1. Pożądany koszt dodawania nowych funkcji na przestrzeni czasu
Rysunek 1.2. Pożądany wzrost złożoności po dodaniu nowych funkcji jest liniowy
Rysunek 1.3. Powszechny przypadek: złożoność rośnie dużo szybciej w powodu dodanej złożoności przypadkowej
Rysunek 1.4. Koszt rozwoju oprogramowania w typowym przypadku: dodawanie nowych funkcji staje się coraz bardziej kosztowne wraz z upływem czasu
W większości przypadków przerywanie dotychczasowych prac i planowanie wszystkiego od początku w celu obniżenia złożoności przypadkowej jest całkowicie niepraktyczne. A nawet gdyby byłoby inaczej, to do czasu zrównania się pod względem funkcjonalnym nowej (tworzonej od zera) wersji z wersją poprzednią, będzie już ona miała swoją własną złożoność przypadkową…
Refaktoryzacja
Wydaje się więc, że tworzenie kolejnych nowych funkcji na ustabilizowanym poziomie kosztów jest niemożliwe, ponieważ złożoność przypadkowa jest nieunikniona. Czy jesteśmy zatem skazani na porażkę? Cóż… nie do końca. Rozwiązaniem pozwalającym trzymać złożoność przypadkową pod kontrolą jest refaktoryzacja. Refaktoryzacja jest procesem polegającym na usprawnianiu projektu (lub „wewnętrznej struktury”) danego fragmentu oprogramowania, bez wpływu na jego zewnętrzne zachowanie. Innymi słowy, refaktoryzacja pozwala nam pozbyć się złożoności przypadkowej. Refaktoryzacji możemy dokonywać małymi krokami, usprawniając nasz projekt kawałek po kawałku, bez konieczności przeprojektowywania całego systemu. W książce Martina Fowlera, Refaktoryzacja. Ulepszanie struktury istniejącego kodu³, podano odpowiednie techniki pozwalające dokonywać refaktoryzacji w bezpieczny sposób. Obecnie najpopularniejsze zintegrowane środowiska programistyczne⁴ zawierają pewne narzędzia do automatycznej refaktoryzacji lub oferują dodatki, które je dostarczają.
Ale nawet w przypadku używania narzędzi do automatycznej refaktoryzacji może dojść do pomyłki programisty, w wyniku której w projekcie pojawią się błędy psujące jakąś istniejącą funkcjonalność. Z tego powodu refaktoryzacja wymaga również przeprowadzania wyczerpujących testów regresji. Tak więc w celu utrzymania szybkiego tempa wydawania nowych i stabilnych wersji zawierających nowe funkcje, musimy regularnie refaktoryzować nasz kod. Aby być w stanie to robić, musimy bardzo często go testować. Jest to drugi ważny powód, dla którego powinniśmy stosować automatyzację testów. Rysunek 1.5 pokazuje, w jaki sposób refaktoryzacja pomaga trzymać złożoność przypadkową pod kontrolą.
Rysunek 1.5. Refaktoryzacja pomaga trzymać złożoność pod kontrolą
Ciągłe doskonalenie
To, co fascynuje mnie najbardziej w automatyzacji testów, to jej związki ze wszystkimi innymi aspektami cyklu tworzenia oprogramowania. Poza związkiem z jakością i produktywnością, który jest oczywisty, automatyzacja testów powiązana jest również z architekturą tworzonego produktu, procesami biznesowymi, strukturą organizacyjną, a nawet z kulturą biznesu (patrz rysunek 1.6). Dla mnie osobiście automatyzacja testów jest niczym lustro, które odzwierciedla wszystkie te rzeczy. Każdy z tych aspektów ma pewien wpływ na automatyzację testów. Ale odzwierciedlenie tych wpływów w automatyzacji testów możemy również wykorzystać do zmiany i usprawnienia dowolnego z tych aspektów.
W wielu przypadkach klienci, którzy korzystają już z automatyzacji testów, proszą mnie o pomoc w rozwiązaniu napotkanych problemów. Problemy te bardzo często objawiają się na poziomie technicznym. Kiedy jednak przychodzę do tych klientów i pomagam im rozpoznać bezpośrednią przyczynę tych problemów, często okazuje się, że są one tak naprawdę związane z co najmniej jednym z tych pozostałych aspektów. Pozbycie się tych problemów nie zawsze jest proste, ale przynajmniej uświadamiają sobie znaczenie tych problemów, co jest pierwszym krokiem prowadzącym do zmiany.
Rysunek 1.6. Automatyzacja testów powiązana jest z wieloma innymi aspektami tworzenia oprogramowania
Mam nadzieję, że po przeczytaniu tej książki będziemy mogli lepiej dostrzegać wpływy, jakie tego rodzaju problemy wywierają na budowaną przez nas automatyzację testów i będziemy w stanie uświadomić ich istnienie odpowiednim osobom, umożliwiając w ten sposób dokonanie niezbędnych usprawnień. Oczywiście, jeśli w zespole panuje kultura ciągłego doskonalenia (np. organizowanie retrospektywnych spotkań i opieranie na nich swoich działań), wówczas będzie to łatwiejsze do zrobienia. A nawet jeśli tak nie jest, pamiętajmy, że świadomość jest kluczem pozwalającym dokonać zmiany i że automatyzacja testów pomoże to osiągnąć, nawet na stanowisku młodszego programisty ds. automatyzacji w dużej i biurokratycznej firmie (więcej informacji na temat tego, w jaki sposób stopniowo zmieniać strukturę swojej organizacji w celu skorzystania z zalet automatyzacji testów, można znaleźć w rozdziale 17).Przypisy
1 Tłumaczenie treści manifestu pochodzi ze strony: http://agilemanifesto.org/iso/pl/manifesto.html (przyp. tłum.)
2 Scrum jest najbardziej powszechną metodyką, która bazuje na wartościach zwinnego programowania.
3 Martin Fowler, „Refactoring: Improving the Design of Existing Code” (Addison-Wesley Professional, 1999).
4 Zintegrowane środowisko programowania (Integrated Development Environment, IDE) odnosi się do oprogramowania, które składa się głównie z edytora, kompilatora oraz zintegrowanego debugera. Przykładem najpopularniejszych środowisk dla języków C# i Java są Microsoft Visual Studio, Eclipse oraz IntelliJ.
5 Testy regresji są testami sprawdzającymi, czy funkcjonalność, która działała wcześniej zgodnie z założeniami, nadal działa poprawnie.
6 W tym kontekście „kod” odnosi się do dowolnego artefaktu będącego częścią systemu i mogącego wpływać na jego zachowanie. Jeśli na przykład lista państw w bazie danych jest czymś, czego użytkownik nie może i nie powinien zmieniać, to listę taką można uznać za część kodu aplikacji.
7 Operacja ewidencjonowania (check-in), znana również jako operacja commit, push lub submit, polega na zastosowaniu zmian wprowadzonych przez programistę na jego lokalnym komputerze w scentralizowanym repozytorium kodu źródłowego, który jest współdzielony przez cały zespół tworzący oprogramowanie. Repozytoria te zarządzane są przez systemy kontroli kodu źródłowego, takie jak Git, Microsoft Team Foundation Server, SVN, Mercurial i wiele innych.
8 Pewne wskazówki na temat dzielenia dużych historyjek użytkownika można znaleźć pod adresem http://agileforall.com/new-story-splitting-resource/.
9 Termin przypadek testowy (test case) może mieć wiele znaczeń. Dla mnie przypadek testowy jest jednym scenariuszem testowym, złożonym z konkretnych kroków (czynności) i weryfikacji. Przypadki testowe są zwykle grupowane w pakiety testów (test suites). Z kolei plan testowania zawiera zwykle wiele pakietów testów, w tym również inne szczegóły dotyczące planowania, zasobów itd.
10 Termin „skrypt” został tutaj użyty w celu opisania pojedynczego automatycznego przypadku testowego, bez względu na to, czy został on napisany w kodzie, w języku skryptowym, za pomocą narzędzia do nagrywania i odtwarzania, czy w dowolnej innej formie.
11 Zobacz opis testów „towarzyskich” (sociable tests) pod adresem https://martinfowler.com/bliki/UnitTest.html. Inne istotne odnośniki to: https://martinfowler.com/articles/is-tdd-dead/ oraz http://www.se-radio.net/2010/09/episode-167-the-history-of-junit-and-the-future-of-testing-with-kent-beck/ (od około 22 do 26 minuty).
12 IDE jest skrótem od Integrated Development Environment (Zintegrowane środowisko programowania). Są to aplikacje, która umożliwiają programistom pisanie, edytowanie, kompilowanie i debugowanie kodu, pozwalając przy tym na wykonywanie wielu innych czynności związanych z tworzeniem oprogramowania.
13 Atrapy nazywane są również obiektami imitacji (przyp. tłum.).
14 Niektóre języki kompilowane są do kodu pośredniego (byte-code), który wykonywany jest przez dedykowany silnik wykonawczy. Maszyna wirtualna Javy (JVM) oraz środowisko uruchomieniowe .NET (CLR) to najbardziej znane silniki wykonawcze kodu pośredniego. Biblioteki, które kompilowane są dla tych silników mogą być wykorzystywane przez aplikacje pisane w dowolnym języku, jaki może być skompilowany dla tego samego silnika. Przykładowo biblioteka WebDriver dla języka Java może być wykorzystywana przez testy pisane w językach Scala i Groovy, zaś powiązanie języka C# (.NET) – przez testy napisane w językach VB.NET oraz F#.
15 DOM to skrót od Document Object Model. DOM opisuje drzewo elementów HTML wraz z ich właściwościami, które w danej chwili są dostępne. Za pomocą języka JavaScript strona może manipulować swoim modelem DOM w czasie wykonywania, dzięki czemu strona jest dynamiczna. Zwróćmy uwagę, że choć DOM może się zmieniać, to sam kod HTML jest statycznym opisem strony, jaką serwer wysłał do przeglądarki.