-
Notifications
You must be signed in to change notification settings - Fork 0
/
DP_teoreticka.tex
410 lines (259 loc) · 74.2 KB
/
DP_teoreticka.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
\chapter{Aktuální řešení}
V této kapitole stručně popíši verzi aplikace, která byla vytvořena v rámci bakalářské práce \cite{bp} a kterou budu v praktické části rozšiřovat. Popíši implementované funkční i nefunkční požadavky, použité technologie a také konfiguraci prostředí a způsob nasazování. Na závěr stručně shrnu, jaké možné plány na rozšíření byly v rámci bakalářské práce nastíněny.
\section{Implementované požadavky}
Pro další práci je třeba si vyjasnit, co už stávající aplikace poskytuje za funkcionalitu a jak je řešená -- zaměřím se proto nejprve na implementované funkční požadavky a poté na vyřešené nefunkční požadavky. Krátce se vždy pokusím uvést, jak je příslušný požadavek v rámci aplikace řešen či jak souvisí s ostatními.
\subsection{Implementované funkční požadavky}
V této podsekci shrnu implementované funkční požadavky. Součástí této podsekce je také původní logický datový model aplikace z bakalářské práce \cite{bp} na obrázku~\ref{fig:db-model-bp} pro lepší pochopení domény.
Shrnutí implementovaných funkčních požadavků \cite{bp}:
\begin{itemize}
\item \textbf{evidence klientů a skupin:} evidování základních informací o klientovi a skupinách (skupina sdružuje několik klientů dohromady a patří k nějakému kurzu),
\item \textbf{evidence lekcí klientů:} evidování všech informací o lekcích (včetně stavů účasti všech účastníků a stavu jejich platby za danou lekci), lekce mohou být pro jednotlivce nebo pro skupiny, každá náleží nějakému kurzu,
\item \textbf{evidence předplacených lekcí:} předplacená lekce je řešená jako lekce, která nemá datum a čas konání,
\item \textbf{evidence kurzů a stavů účasti:} pro použití při evidenci lekcí,
\item \textbf{přehled lekcí pro aktuální den:} zobrazení pro dnešní lekce (kromě zrušených),
\item \textbf{karta klienta a skupiny}: zobrazení všech informací o klientovi/skupině včetně všech lekcí,
\item \textbf{upozornění na platbu příště:} když už klient nemá žádné předplacené lekce, zobrazí se u poslední placené lekce upozornění na fakt, že má příště zaplatit,
\item \textbf{pořadové číslo lekce:} u lekce se zobrazí (automaticky vypočítáno), o kolikátou navštívenou lekci v pořadí se jedná,
\item \textbf{týdenní přehled:} zobrazení lekcí jako v diáři.
\end{itemize}
\begin{figure}[h]\centering
\includegraphics[width=1\textwidth]{img/bp/db-model}
\caption[Logický datový model z bakalářské práce]{Logický datový model z bakalářské práce \cite{bp}}\label{fig:db-model-bp}
\end{figure}
\subsection{Implementované nefunkční požadavky}
Následuje shrnutí implementovaných nefunkčních požadavků \cite{bp}:
\begin{itemize}
\item \textbf{kompatibilita s webovými prohlížeči:} aplikace je plně funkční a kompatibilní s běžnými webovými prohlížeči (Google Chrome, Mozilla Firefox, Microsoft Edge, Apple Safari) v posledních verzích, důraz je především kladen na desktopový prohlížeč Mozilla Firefox, na kterém se aplikace používá primárně,
\item \textbf{podpora široké škály zařízeních:} aplikace je responzivní a korektně se zobrazuje na všech zařízeních používaných lektorkou -- iPad s iOS~13.3 a 9,7palcovým displejem, Nokia~5 s Androidem~9.0 a 5,2palcovým~displejem, notebook s Windows~10 s rozlišením 1920~×~1080 a 15,6palcovým~displejem,
\item \textbf{připravenost na rozšíření a údržbu}: kód byl tvořen s důrazem na budoucí možná rozšíření (např. použití konstant, respektování principu DRY (\enquote{Don\textquotesingle t repeat yourself}) ad.),
\item \textbf{bezpečnost:} JWT (JSON Web Token) autentizace a další produkční konfigurace pro zabezpečení aplikace,
\item \textbf{srozumitelné a jednoduché rozhraní aplikace:} iterativní návrh a implementace UI za neustálé spolupráce s lektorkou pro dosažení co nejlepší použitelnosti.
\end{itemize}
\section{Použité technologie}
V této sekci shrnu všechny podstatné použité technologie pro serverovou i klientskou část. Součástí bakalářské práce byl přehledný diagram nasazení pro lepší orientaci \cite{bp} -- vzhledem k tomu, že se jádro architektury nemění, původní diagram zde neuvádím, na obrázku~\ref{fig:deployment-diagram} z kapitoly návrhu~\ref{chap:navrh} v praktické části je ale k vidění jeho aktualizovaná verze.
Toto shrnutí použitých technologií je také užitečné pro následnou práci, protože je třeba mít podrobný přehled o všech možných používaných nástrojích, frameworcích, knihovnách, doplňcích apod. Taktéž to čtenáři umožní bližší představu o výchozím stavu aplikace, která bude v rámci praktické části rozšiřována.
\subsection{Serverová část}
Serverová část aplikace \cite{bp} je napsána v Pythonu~3.6.5 s webovým frameworkem \href{https://www.djangoproject.com/}{Django~2.0.5}. Pro správu závislostí se používá pouze jednoduchý soubor \verb|requirements.txt| obsahující specifikace přesných verzí knihoven (bez povolení jakkoliv malých aktualizací).
Aplikace vystavuje REST~API postavené na frameworku \href{https://www.django-rest-framework.org/}{Django~REST~framework~3.8.2}. Na produkci se používá webový server \href{http://gunicorn.org/}{Gunicorn~19.8.1} spolu s knihovnou \href{http://whitenoise.evans.io/en/stable/}{WhiteNoise~3.3.1} pro efektivní servírování zkomprimovaných statických souborů \cite{whitenoise}.
Odděleně od aplikace běží také SQL (Structured Query Language) databáze \href{https://www.postgresql.org/}{PostgreSQL}~9, se kterou Django komunikuje přes adaptér \href{https://www.psycopg.org/}{psycopg2}.
\subsection{Klientská část}\label{subsec:bp-klientskacast}
Klientská část aplikace \cite{bp} je napsána v JS (JavaScript) ve standardu ECMAScript®~2018 a čistém CSS (Cascading Style Sheets). Pro správu závislostí se používá soubor \verb|package.json|, v němž jsou verze přibližně poloviny knihoven definovány napevno (bez možnosti jakkoliv malé aktualizace), druhá polovina knihoven přijímá malé aktualizace.
Klientskou část aplikace lze klasifikovat jako:
\begin{itemize}
\item \textbf{SPA} (Single-Page Application), tedy aplikaci běžící přímo u klienta v prohlížeči nevyžadující znovunačítání při přecházení mezi stránkami \cite{spa1} a
\item \textbf{CSR} (Client-Side Rendering), tedy aplikaci, která je klientovi doručena jako jednoduchý HTML (Hypertext Markup Language) soubor s odkazy na JS/CSS (Cascading Style Sheets) soubory \cite{csr-ssr}.
\end{itemize}
Je postavena na knihovně \href{https://reactjs.org/}{React~16.3} spolu s UI frameworkem \href{https://getbootstrap.com}{Bootstrap~4.1} a související knihovnou \href{https://reactstrap.github.io/}{Reactstrap~5.0}, která umožňuje jednoduché použití Bootstrap komponent v Reactu \cite{reactstrap}. Pro asynchronní požadavky na REST API využívá knihovnu \href{https://github.com/axios/axios}{axios~0.18}.
Konfigurace celé klientské části stojí na nástroji \href{https://github.com/facebook/create-react-app}{create-react-app~1}, který umožňuje vytvářet React aplikace bez počáteční konfigurace \cite{cra}. Vzhledem k použití Djanga bylo ale potřeba pro pohodlný vývoj pomocí příkazu \verb|eject| \enquote{vysunout} celou konfiguraci klientské části a následně pak pomocí knihoven \href{https://github.com/owais/webpack-bundle-tracker}{webpack-bundle-tracker} a \href{https://github.com/owais/django-webpack-loader}{django-webpack-loader} propojit Django s nástrojem Webpack \cite{bp}. Webpack zde umožňuje mj. spouštět vývojový server pro klientskou část a vytvářet z jednotlivých modulů klientské části balíčky, které lze pak po zadaných transformacích servírovat na produkci pro běžné webové prohlížeče \cite{webpack-ackee}.
V případě vývoje na lokálním stroji se používá \cite{bp} pro serverovou část vývojový Django server a pro klientskou část \href{https://github.com/webpack/webpack-dev-server}{webpack-dev-server}, oba nabízejí podporu pro \enquote{hot reloading} (tedy okamžité automatické projevení změn v kódu bez kompletního znovunačtení aplikace \cite{webpack-docs-hmr}) a v tomto ohledu bylo vše i díky zmíněným knihovnám zprovozněno.
\section{Prostředí, testování a nasazování}\label{sec:prostreditestovaninasazovani}
Aplikace \cite{bp} je verzována v privátním repozitáři na serveru GitHub. Při každém nahrání nové revize na server (\verb|push|) se na integračním serveru \href{https://travis-ci.com/}{Travis~CI} (Continuous Integration) spustí sestavení aplikace, vytvoří se testovací databáze a spustí se základní testy (viz níže). Výsledné pokrytí kódu spočítané pomocí nástroje \href{https://coverage.readthedocs.io/}{Coverage.py} se poté nahraje na platformu \href{https://codecov.io/}{codecov.io} pro pokročilé statistiky o testování \cite{codecov}. Pokud vše na Travisu proběhne v pořádku, začne nasazování na produkční server běžící na \href{https://www.heroku.com/}{Heroku}. Nasazení na Heroku probíhá tak, že se přímo na něm spouští celé sestavení aplikace znovu, zmigruje se databáze a aplikace se nasadí. I tento průběh lze sledovat přímo z Travis terminálu.
Spouštěné testy jsou základní a velmi jednoduché, otestují \cite{bp}:
\begin{itemize}
\item přidání klienta a uživatele do databáze přes Django modely (tedy ne tak, jak to může dělat uživatel, ale na mnohem nižší úrovni),
\item zda Django uživateli zobrazí správnou stránku při příchodu do aplikace (neřeší, zda se pak vůbec JS aplikace vyrenderuje),
\item základní funkčnost API požadavků -- proběhne autorizace (a tedy získání JWT tokenu) a pokus o vytvoření nového klienta přes API.
\end{itemize}
Jak je vidět, testy byly skutečně pouze velmi povrchní, dalo by se říci, že se jedná o smoke testy. Také je třeba zdůraznit, že provedení \verb|push| na repozitář mělo za následek okamžité nasazení na produkci, pokud sestavení a tyto základní testy prošly. To může být nedozírné následky. I proto se v dalších kapitolách této teoretické i praktické části budu zaobírat možnostmi zlepšení.
\section{Plán rozšíření z bakalářské práce}\label{sec:planrozsirenibp}
Na závěr bakalářské práce \cite{bp} bylo zmíněno několik možných rozšíření aplikace. Následuje jejich stručný přehled, v kapitole~\ref{chap:sberpozadavkuaanalyza} se mimo jiné na některá z nich také dostane, případně bude vysvětleno, proč je daný požadavek vyřazen.
Přehled možných rozšíření \cite{bp}:
\begin{itemize}
\item \textbf{vylepšení předplacených lekcí:} pohodlnější způsob zaznamenávání předplacených lekcí, pro skupiny je to velmi krkolomné a nepohodlné, pro jednotlivce také,
\item \textbf{kontrola časového konfliktu lekcí:} aby se dvě nezrušené lekce vzhledem k datu, času a délce trvání nijak nepřekrývaly,
\item \textbf{vyhledávání v aplikaci:} např. vyhledávání klientů,
\item \textbf{evidování zájemců o kurz:} pro plánování nových lekcí kurzů pro jednotlivce a skupiny,
\item \textbf{evidence pomůcek a učebnic},
\item \textbf{testy:} doplnění dalších testů a vysoké pokrytí kódu,
\item \textbf{migrace na nový React:} k vydání verze~16.3 došlo na konci vývoje aplikace v rámci bakalářské práce, např. došlo ke změnám v API (životní cyklus komponent) \cite{react-blog-163},
\item \textbf{React Context API:} analýza možností využití Context API v rámci nového Reactu \cite{react-blog-163}, zejména by pravděpodobně pomohlo snížit např. počet přístupů do API z klientské části napříč aplikací,
\item \textbf{offline přístup:} analýza možností řešení offline přístupu, např. automatické ukládání do Google kalendáře, progresivní webové aplikace apod. a s tím související další oblasti jako SSR (Server-Side Rendering) -- tedy klient obdrží od serveru HTML dokument připravený k vyrenderování, oproti CSR, kde by klient pro vyrenderování aplikace musel čekat na stažení a spuštění JS souborů \cite{csr-ssr}.
\end{itemize}
\chapter{Možnosti automatizovaného testování}
Testování je důležitou součástí softwarového vývoje \cite{test-bdo}. V této kapitole nejprve srovnám manuální a automatizované testování, poté se zaměřím na strukturu samotných testů -- do jakých vrstev se dělí a kolik testů by v těchto vrstvách mělo být. Některé metodiky softwarového vývoje jsou zaměřené na způsob testování, proto také uvedu hlavní principy těchto metodik a s nimi související nástroje, které umožňují tyto metodiky zavést. Uvedu i další nástroje pro testování UI.
\section{Srovnání manuálního a automatizovaného testování}
Dříve, když trval vývojový cyklus několik měsíců až let, se obvykle testovalo převážně pouze manuálně \cite{test-kitner}. Tedy na základě scénářů testeři prováděli testy \cite{test-bdo}. Dnes, v době agilního vývoje a rychlých dodávek, je potřeba větší část testování provádět automatizovaně \cite{test-kitner}. Tedy naprogramovat testy a poté je automaticky spouštět testovacím nástrojem \cite{test-bdo}. Díky tomu se týmy mohou dozvědět o chybě v řádu sekund a minut místo dnů a týdnů \cite{test-fowler}.
\textbf{Výhodou} automatizovaného testování je:
\begin{itemize}
\item šetří čas, je rychlejší, umožní rychleji vydávat nové verze (kompletní manuální testování bylo úzkým hrdlem v životním cyklu vývoje softwaru) \cite{test-kitner, test-genez, test-cd},
\item odhalí chyby v dřívějších fázích, tedy snižuje náklady \cite{test-kitner},
\item dělá testování \enquote{zábavnější} a umožní efektivnější manuální testování -- odstraňuje běžnou neustále opakující se rutinu při manuálním testování \cite{test-kitner, test-perfecto},
\item dochází ke zpřesnění testů a vyšší spolehlivosti, protože se tester při neustálém opakování na všech operačních systémech a prohlížečích může splést nebo něco přehlédnout \cite{test-kitner, test-genez},
\item možnost vyššího pokrytí kódu testy a odhalení více chyb díky jednoduchému zavedení více permutací různých zařízení a operačních systémů \cite{test-perfecto},
\item umožňuje zavést průběžnou integraci a dodávání \cite{test-kitner2}.
\end{itemize}
\textbf{Nevýhodou} automatizovaných testů je:
\begin{itemize}
\item při nesprávném rozhodnutí o oblasti, kterou budeme optimalizovat, můžeme stovky hodin strávit při vytváření testů, které nakonec nebudou vůbec nacházet podstatné chyby \cite{test-kitner},
\item nevhodně napsané testy mohou dát falešnou naději, že vše funguje, ačkoliv se v aplikaci vyskytují závažné chyby \cite{test-devqa},
\item nikdy zcela nenahradí lidské pozorování (při manuálním testování) a nemohou garantovat přívětivost k uživateli či pozitivní uživatelský prožitek \cite{test-genez},
\item vyšší pravděpodobnost falešně pozitivních výsledků, následná analýza problému je náročná, protože je třeba zjistit, zda se jedná o chybu aplikace či testu \cite{test-perfecto},
\item nutnost neustálé údržby testů -- při zavedení změny v aplikaci je třeba vše co nejdříve (ideálně okamžitě) projevit do testů \cite{test-swsrovnani}.
\end{itemize}
Jak je vidět ze shrnutí výhod a nevýhod automatizovaného testování, manuální testování má v softwarovém vývoji stále své místo. Zejména kvůli lidskému faktoru a v případech, kdy se konkrétní test nemá spouštět opakovaně kvůli časové náročnosti vytvoření automatizovaného testu \cite{test-bdo}.
Na možnosti aplikace manuálního a automatizovaného testování lze také nahlížet z hlediska různých testovacích cyklů softwaru \cite{test-bdo}, tedy manuální testování je vhodné na počátku vývoje/iterace a na závěr při testech použitelnosti, kde je důležitý lidský faktor. Automatizované testování je pak vhodné pro fázi testování výkonu a také pro fázi regresních testů \cite{test-bdo}, ty se využívají při opětovném testování stávajících funkcí a vlastností aplikace při provádění změn, například rozšiřování jiných oblastí či opravě chyb \cite{test-regresni}.
Jak uvádí \cite{test-bdo}, je třeba nalézt pomyslný \enquote{rovnovážný bod}, který reprezentuje optimální poměr manuálních a automatizovaných testů vzhledem k ceně jejich vytvoření a počtu běhů testu -- cena vytvoření automatizovaného testu je vysoká, pokud poběží jednou, ale rychle se snižuje s počtem opakování, naproti tomu manuální testování je levné, ale s každým během se cena zvyšuje kvůli délce běhu testu.
Díky vytvoření automatizovaných testů lze aplikaci průběžně testovat na integračním serveru při každé revizi \cite{test-kitner}, to umožní ještě rychlejší zpětnou vazbu, rychlejší vydávání verzí a spokojenost zákazníka \cite{test-perfecto}. Aplikace je totiž prakticky připravená na nasazení v každé revizi \cite{test-atlassian}.
\section{Struktura automatizovaných testů}
Automatizované testování prostupuje více úrovněmi softwarového projektu \cite{test-kitner2} a je důležité na počátku tvorby testů stanovit, kde se bude automaticky testovat \cite{test-kitner}. Jednou z častých strategií zejména agilních týmů je strategie tzv. \enquote{testovací pyramidy} \cite{test-smartbear}. V této sekci tuto strategii představím a popíši, jak se dle různých zdrojů aplikuje, zaměřím se také na další alternativní přístupy.
\subsection{Testovací pyramida}\label{subsec:testingpyramid}
Testovací pyramida rozděluje automatizované testy do několika oblastí \cite{test-smartbear}, viz obrázek~\ref{fig:testing_pyramid}. Popis pyramidy vychází z \cite{test-kitner2, test-smartbear}. Obvykle by měly být jádrem automatizovaných testů unit testy, které ověřují, zda jednotlivé dílčí části kódu odpovídají požadavkům. Těchto testů by měla být většina. Následují testy komponent (např. přihlášení uživatele, tvorba účtu, objednávky) a integrační testy (ověří, že jednotlivé komponenty spolu interagují tak, jak bylo zamýšleno, např. data zákazníka jsou napříč celým procesem objednávky korektně přenášena). Jak je vidět na obrázku~\ref{fig:testing_pyramid}, vrstvy nejsou pevně definované a často některé splynou v jednu \cite{test-fowler}. Pod vrcholem pyramidy se nalézají API testy a na vrcholu jsou UI testy (někdy nazývané End-to-End, funkční či E2E), které by měly typicky mít nejmenší podíl ze všech automatizovaných testů vzhledem k jejich náročnosti na tvorbu a křehkosti při změnách UI. Mimo pyramidu, případně na úplný vrchol, lze pak zařadit samotné manuální testy UI.
\begin{figure}[ht]\centering
\includegraphics[width=1\textwidth]{img/ext/testing_pyramid.png}
\caption[Srovnání strategie \enquote{testovací pyramidy} a \enquote{zmrzlinového kornoutu}]{Srovnání strategie \enquote{testovací pyramidy} (vlevo) a \enquote{zmrzlinového kornoutu} (vpravo) \cite{test-fishman}}\label{fig:testing_pyramid}
\end{figure}
Konkrétní aplikace této strategie závisí na vlastnostech projektu, týmu a požadavcích. Přesto se pokusím uvést obecná doporučení různých autorů. Čím níže z pohledu test pyramidy se podaří vývojářům dostat, tím lépe pro budoucí práci -- lépe začít např. s API, než s UI -- případně lze pracovat ve více lidech na více úrovních paralelně \cite{test-kitner}. Pokud ale aplikace už běží a postrádá jakékoliv testy, je ideální začít s tvorbou testů na vrcholu pyramidy pro kritické klíčové části byznysu \cite{test-atlassian}. Pro zbytek je vhodné využít nižší úrovně testů \cite{test-atlassian2}.
Mnoho organizací má i přes testovací pyramidu většinu automatizovaných testů postavených nad UI vrstvou \cite{test-devqa}, výhodou je dohled nad výsledným produktem, který je pak používán, nevýhodou křehkost a nesnadné dohledávání původu chyb zachycených při testech UI, v případě použití AJAX (Asynchronous JavaScript and XML) je také mnohem složitější vytvořit deterministické UI testy \cite{test-timothy}. Testovací pyramida je pak obrácená a obvykle se tomuto přístupu vzhledem k tvaru obrácené pyramidy říká \enquote{zmrzlinový kornout} \cite{test-mf1}, viz opět obrázek~\ref{fig:testing_pyramid}.
Při volbě správné části k testování je třeba se řídit tím, která část je pro byznys zákazníka důležitá \cite{test-kitner}, nikoliv pouze například co nejvyšším pokrytím kódu testy \cite{test-devqa}. V případě, že se UI testy použijí pro klíčové funkce aplikace, můžeme zajistit, že i přes případné drobnější chyby funguje ta nejdůležitější část aplikace korektně, a to včetně všech vrstev jako např. napojení na API a databázi, to umožní častější dodávání nových verzí zákazníkovi s větší jistotou fungování, to vše je ale třeba dělat s vědomím jednotlivých úrovní testovací pyramidy a důsledků použití UI testů \cite{test-novanet}. Je tedy vhodné ve vyšší vrstvě testovat dva typy průchodů -- nejhorší a nejideálnější -- a pro zbytek hraničních případů využít vrstvy nižší \cite{test-dzone}.
Strategie testovací pyramidy je často špatně interpretována a může například vyústit v napsání naprosto všech možných unit testů a poté přesunutí do vyšší vrstvy atd., což pro některé týmy může být vhodné, pro jiné ale zbytečně komplexní a drahé \cite{test-cucumber2}. Principem pyramidy je naznačit, že testů na vyšší vrstvě má být méně než na nižší \cite{test-cucumber2}. Ačkoliv se princip testovací pyramidy stává standardem pro agilní týmy, je třeba rozumět principům, se kterými tento přístup přichází, a na základě toho zavést způsoby testování pro konkrétní projekt \cite{test-cucumber2}. Na závěr je třeba říci, že veškeré zmíněné termíny, názvy a definice nejsou rigorózní a často panují různé názory např. na rozdělení testovací pyramidy, definici UI testování (někdy synonymum end-to-end testování, jindy UI testy jednotlivých částí pomocí unit testů) a mnoho dalšího, při tvorbě testů v rámci softwarového produktu je tedy vždy třeba jasně vymezit a definovat rozsah testů, sjednotit terminologii a na všem se domluvit \cite{test-fowler}.
\subsection{Alternativní přístupy}\label{subsec:testingtrophy}
Alternativním přístupem pro testování klientské části je strategie tzv. \enquote{testovací trofeje} \cite{test-trophy}, která se skládá ze 4~částí, od té nejnižší: statické testy (založené na statickém typování a linterech, viz sekce \ref{sec:statickaanalyzakodu} a \ref{sec:staticketypovani}), unit testy (cílené na kritické části aplikace), integrační testy (ověřující, že vše spolu korektně spolupracuje) a end-to-end funkční testy (simulace chování uživatele při důležitých průchodech aplikací prostřednictvím automatizovaného klikání -- tedy UI testy z testovací pyramidy). Jak ale uvádí \cite{test-roth}, tento přístup opět může pro některé týmy a aplikace být vhodný, pro některé nikoliv a bez dostatečné znalosti konkrétního kódu aplikace a problematiky může následování nejen tohoto vzoru vyústit ve slepou uličku.
\begin{figure}[h]\centering
\includegraphics[width=0.4\textwidth]{img/ext/testing_trophy.png}
\caption[Strategie \enquote{testovací trofeje}]{Strategie \enquote{testovací trofeje} \cite{test-trophy}}\label{fig:testing_trophy}
\end{figure}
\section{Metodiky a nástroje pro automatizované testování}
Svět testování je ovlivňován několika metodikami vývoje softwaru, především TDD (Test-Driven development) a BDD (Behaviour-Driven development) \cite{test-swtestinghelp1}. S těmito metodikami souvisí také různé nástroje pro automatizované testování podporující příslušný způsob vývoje, o nich se též zmíním. Na závěr uvedu ještě další nástroje pro UI testování.
\subsection{TDD}
Základním principem TDD je napsat nejprve testovací případy (přímo v programovacím jazyce) a až poté implementovat kód, který zařídí splnění těchto případů \cite{test-swtestinghelp2}. Výsledkem je vyšší kvalita a flexibilita kódu (tím pádem lze pak jednoduše provádět např. refaktoring) a také vysoké pokrytí kódu \cite{test-swtestinghelp2}. Nevýhodou TDD je, že změny ve fungování aplikace mohou mít velký dopad na testovací případy, testovacím případům také rozumí pouze lidé se znalostí programovacích jazyků \cite{test-swtestinghelp2}. Vzhledem k zaměření testů na konkrétní implementaci a nikoliv chování je ale snadnější najít v případě TDD testů konkrétní chybu \cite{test-swtestinghelp2}. TDD testy se zaměřují zejména na nejnižší vrstvu v testovací pyramidě, tedy unit testy \cite{test-swtestinghelp1}, principy TDD se ale mohou aplikovat napříč všemi vrstvami \cite{test-dzone}.
Mezi nástroje pro podporu TDD patří xUnit frameworky, např. \href{https://junit.org/}{JUnit}, \href{https://testng.org/}{TestNG}, \href{https://nunit.org/}{NUnit} \cite{test-swtestinghelp2}. Pro \textbf{JS} se dle \cite{test-chart-js2} a \cite{test-chart-js1} nejvíce používá \href{https://jestjs.io/}{Jest} a \href{https://mochajs.org/}{Mocha}, pro \textbf{Python} se používá \href{https://docs.pytest.org/en/latest/}{PyTest} nebo \href{https://docs.python.org/3/library/unittest.html}{unittest} \cite{test-chart-python}.
\subsection{BDD}\label{subsec:bdd}
BDD rozšiřuje TDD a místo psaní testovacích případů se zapisují požadované scénáře chování, později je opět implementován samotný kód aplikace zařizující její předem specifikované chování \cite{test-swtestinghelp2}. Díky zápisu scénářů v jazyce Gherkin, který vychází z přirozeného jazyka, je možná jednoduchá spolupráce mezi vývojáři, testery, analytiky a zákazníkem (i bez znalosti programovacích jazyků) \cite{test-swtestinghelp2, test-cucumber1}, vytvořené scénáře tvoří prakticky základ pro dokumentaci funkcí aplikace \cite{test-smartbear2}. Při vývoji aplikace totiž často dochází k nedorozuměním ohledně výkladu různých požadavků \cite{test-smartbear2}. Výhodou BDD je také zaměření na samotné chování aplikace, nikoliv na přemýšlení o implementaci v kódu -- chování aplikace je hlavní prvek, na který se vývojáři a testeři zaměřují, to umožňuje držet se lépe požadavků zákazníka \cite{test-swtestinghelp2}. BDD testy se zaměřují zejména na prostřední vrstvy v testovací pyramidě, tedy API testy \cite{test-swtestinghelp1}.
Mezi nástroje pro podporu BDD patří frameworky jako \href{https://specflow.org/}{SpecFlow}, \href{https://cucumber.io/}{Cucumber}, \href{https://github.com/machine/machine.specifications}{MSpec} \cite{test-swtestinghelp2}. Pro \textbf{JS} se používá \href{https://cucumber.io/docs/installation/javascript/}{Cucumber.js}, pro \textbf{Python} se používá \href{https://behave.readthedocs.io/en/latest/}{Behave} \cite{test-chart-bdd}. Ze scénářů lze také vytvářet vždy aktuální dokumentaci a reporty díky nástrojům jako \href{https://smartbear.com/product/testcomplete/overview/}{TestComplete} \cite{test-smartbear2}.
BDD se často používá spolu s TDD, protože dokáže na vyšší úrovni prověřit korektní fungování aplikace a poskytnout tak vyšší důvěru ve výsledný produkt \cite{test-cucumber1} -- takové testy tedy prověří nějaké chování aplikace a doplněním o TDD testy na nižších úrovních se dotestují specifické části.
\subsection{Další nástroje}
Jak jsem již zmínil v předchozí podsekci, BDD se zaměřuje na vyšší vrstvy testovací pyramidy, pro UI testování se tedy často používá s nástroji jako \href{https://www.selenium.dev/}{Selenium} \cite{test-dzone}. Selenium je sada nástrojů a knihoven pro automatizované testování webových aplikací \cite{test-seleniumdocs}. Prostřednictvím tzv. WebDriveru, který je implementován jednotlivými tvůrci prohlížečů, je možné interagovat s webovou stránkou prostřednictvím běžných prohlížečů přímo z kódu (a to nejen v běžném módu, ale také tzv. \enquote{headless} módu, kde prohlížeč běží bez GUI) \cite{test-hackernoon1, test-seleniumdocs}. Pro \enquote{headless} mód byl do nedávné doby nejpopulárnější volbou \href{https://phantomjs.org/}{PhantomJS}, vzhledem k postupné implementaci této funkce do předních webových prohlížečů byl ale jeho vývoj zastaven a přechází se na běžné prohlížeče, protože právě v těch koncový uživatel pracuje \cite{test-fowler, test-phantomjs}.
Selenium je mocný nástroj, nevýhodou je ale poměrně zdlouhavý zápis skriptů pro výběr elementů, práci s výjimkami a časováním, proto se často volí nadstavby zaobalující Selenium, které umožňují jednodušší zápis a práci, např. \href{https://selenide.org/}{Selenide} \cite{test-hackernoon1}. Také je možné využít komplexní testovací frameworky, které nabízí mnohem více nástrojů pro práci s testy, z nichž některé jsou také postavené na Seleniu, z mnohých používaných například \href{https://www.katalon.com/}{Katalon Studio} či \href{https://robotframework.org/}{Robot framework} \cite{test-selenium3, test-katalon}.
Selenium se postupem času stalo průmyslovým standardem pro UI testování, a to zejména díky jednoduchosti použití, kompatibilitě (s mnoha prohlížeči, možnost použití s mnoha programovacími jazyky) a popularitě \cite{test-selenium1}. Jak ale uvádí \cite{test-cypress1}, v případě asynchronních aplikací je Selenium složitější používat vzhledem k principu jeho fungování, protože je třeba vždy explicitně čekat na objevení elementu na stránce, problémem ale je, že nevíme, jak dlouho čekat. I z toho důvodu zde autor nabízí alternativu v podobě novějšího \href{https://www.cypress.io/}{Cypress}, který nabízí mnohem lepší práci s asynchronními aplikacemi, problémem ale je možnost použití pouze s JS, malá komunita a popularita a méně návodů \cite{test-cypress1}. Další nevýhodou Cypress byla podpora výhradně prohlížeče Google Chrome, to se ale v únoru~2020 změnilo \cite{test-cypress2}, naopak výhodou uváděnou např. v \cite{test-cypress3} byla lepší dokumentace oproti Seleniu, dokumentace Selenia ale byla přepsána a na podzim roku~2019 nasazena \cite{test-selenium2}.
\chapter{Nástroje pro usnadnění vývoje a údržby}\label{chap:nastrojeprousnadnenivyvojeaudrzby}
Postupem času se v rámci dalšího vývoje a rozšiřování aplikace ukázalo, že je třeba použít pokročilé nástroje pro usnadnění samotného vývoje a údržby. Cílem této sekce je nastínit způsob jejich výběru. Jedním z hlavních požadavků je, aby vše potřebné bylo zdarma, neuvažuji zde tedy nástroje nenabízející alespoň nějakou formu bezplatného používání na dobu neurčitou (tedy nikoliv jen pro studenty). Při procházení ceníků budu brát také v úvahu fakt, že repozitář s projektem je open-source (to je jeden z cílů této práce).
Nejprve se zaměřím na nástroje pro monitorování chyb a správu logů. Při volbě těchto nástrojů budou případně specifikovány další požadavky. Na základě průzkumu pak uvedu nalezené nástroje, jejich vlastnosti a seřadím je orientačně podle popularity na základě stránky \href{https://stackshare.io/}{StackShare}, která poskytuje \cite{stackshare} možnost sdílet používané nástroje a technologie firem a jednotlivců pro jejich projekty, nástroje a technologie srovnávat, hodnotit, řadit dle popularity apod.
Poté se zaměřím na výhody a nevýhody statického a dynamického typování jazyků a možnosti zavedení anotací typů v projektu ÚP. V poslední kapitole se pak zaměřím na možnosti statické analýzy kódu projektu, rozdělení jednotlivých možných nástrojů a popsání jejich vlastností. Obě tyto kapitoly ukazují další možnosti usnadnění vývoje a údržby aplikace.
Některé řešené oblasti souvisí také s respektováním metodiky s názvem \enquote{The Twelve-Factor App} doporučované (a také vytvořené) v rámci Heroku metodikou. Tato metodika se zabývá stavěním webových aplikací, které nabízejí deklarativní způsob spouštění, jsou maximálně přenosné mezi prostředími, minimalizují rozdíl mezi vývojovým a produkčním prostředím a nasazují se do cloudových platforem \cite{12factor}.
\section{Monitorování chyb}\label{sec:monitorovanichyb}
Pro každou aplikaci je důležité monitorovat chyby, díky tomu (nehledě na to, zda uživatel nahlásí problém a bude jakkoliv konkrétní) je možné pak chyby snadněji reprodukovat a opravit \cite{tools-exception}. Nástroje pro monitorování chyb umožňují upozornit vývojáře na výskyt chyby, poskytnout mu kompletní informace o chybě a kontextu, ve kterém nastala \cite{tools-exception}.
Minimální požadavky na nástroje jsou:
\begin{itemize}
\item zdarma pro použití na neomezenou dobu jak na Heroku (aplikace v rámci této práce), tak mimo Heroku (další aplikace např. v rámci ÚP) -- tento požadavek je zde kvůli existenci nástrojů jako např. \href{https://airbrake.io/}{Airbrake}, který na Heroku nabízí plán zdarma \cite{airbrake-heroku}, ale ve svém ceníku jej nenabízí \cite{airbrake-pricing}, tedy takové nástroje neuvažuji,
\item SaaS (Software as a Service) -- tedy aplikace hostovaná provozovatelem služby \cite{oracle-saas},
\item možnost použití pro klientskou (JS s Reactem) i serverovou část (Python s Djangem).
\end{itemize}
Pro monitorování chyb existuje mnoho nástrojů, podle StackShare \cite{stackshare-exception} volím 4~nejpoužívanější, které splňují všechny požadavky. I přes mnoho dalších funkcionalit těchto nástrojů se zde zaměřuji na primární účel, tedy monitorování chyb -- nehledě na to, jaké další integrace a funkce jsou poskytnuty zdarma.
Nejpoužívanější nástroje podle StackShare (řazeno od nejpoužívanějšího) \cite{stackshare-exception} splňující zmíněné požadavky:
\begin{enumerate}
\item \href{https://sentry.io/}{\textbf{Sentry}}: zdarma nabízí 5~000 událostí/měsíc pro neomezený počet projektů, 7~dní historie dat \cite{sentry-pricing}, podporuje React i Django \cite{sentry-platforms},
\item \href{https://rollbar.com/}{\textbf{Rollbar}}: zdarma nabízí 5~000 událostí/měsíc pro neomezený počet projektů, 30~dní historie dat \cite{rollbar-pricing}, podporuje React i Django \cite{rollbar-platforms},
\item \href{https://www.bugsnag.com/}{\textbf{Bugsnag}}: zdarma nabízí 7~500 událostí/měsíc pro neomezený počet projektů, 7~dní historie dat \cite{bugsnag-pricing}, podporuje React i Django \cite{bugsnag-platforms},
\item \href{https://www.honeybadger.io/}{\textbf{Honeybadger}}: zdarma nabízí 12~000 událostí/měsíc pro neomezený počet projektů, 15~dní historie dat \cite{honeybadger-pricing}, podporuje React \cite{honeybadger-react} i Django \cite{honeybadger-django}.
\end{enumerate}
Jiný přístup k monitorování chyb na klientské části nabízí nástroje jako \href{https://logrocket.com/}{LogRocket} -- ten k zachyceným chybám přidá i nahrané video s kroky uživatele vedoucími k dané chybě (ve videu je obrazovka zachycující přesně to, co uživatel viděl) \cite{logrocket}. LogRocket nabízí zdarma 1~000 nahraných sezení uživatelů/měsíc (sezení je jedno kontinuální používání aplikace daným uživatelem) \cite{logrocket-pricing}, 14~dní historie dat, podporuje React \cite{logrocket-react}.
\section{Správa logů}\label{sec:spravalogu}
Nasazené aplikace generují mnoho logů z různých procesů, v případě Heroku jsou všechny tyto logy agregovány do jednoho kanálu a nabízí možnost uchování posledních 1~500 logů nejdéle 1~týden \cite{tools-logs1}. V případě, že chceme přístup k většímu počtu logů či ke starším (zde je především problém s limitem pro počet logů, který je nízký), je třeba využít buď možnost napojení logů na některý z doplňků na Heroku, případně logy rovnou přímo přesměrovávat do jiné služby \cite{tools-logs1}. Tyto nástroje pro správu logů pak umožňují spravovat velké množství agregovaných logů generovaných z mnoha typů zařízení a serverů -- nad nimi provádět mj. různé dotazy, vyhledávání, pohledy, případně i analýzy či upozornění na nějaké události \cite{tools-logs2}. Uvedený způsob řešení práce s logy též odpovídá jednomu z pravidel metodiky \enquote{The Twelve-Factor App} \cite{12factor}.
Minimální požadavky na nástroje jsou:
\begin{itemize}
\item zdarma pro použití na neomezenou dobu pro logy z Heroku,
\item SaaS -- tedy aplikace hostovaná provozovatelem služby \cite{oracle-saas},
\item upozorňování na události e-mailem,
\item historie logů alespoň na 7~dnů.
\end{itemize}
Pro správu logů existuje mnoho nástrojů, podle StackShare \cite{stackshare-log} volím 2~nejpoužívanější, které splňují všechny požadavky. I přes mnoho dalších funkcionalit těchto nástrojů se zde zaměřuji na primární účel, tedy ukládání logů, vyhledávání a upozorňování -- nehledě na to, jaké další funkce jsou poskytnuty zdarma (během hledání se ukázalo, že právě požadavek upozorňování většina nástrojů zdarma neposkytuje, filtrem dle požadavků tedy nakonec prošly pouze 2~nástroje).
Nejpoužívanější nástroje podle StackShare (řazeno od nejpoužívanějšího) \cite{stackshare-log} splňující zmíněné požadavky:
\begin{enumerate}
\item \href{https://www.papertrail.com/}{\textbf{Papertrail}}: zdarma nabízí 50~MB logů/měsíc, 7~dní historie logů (vyhledávání ale jen pro poslední 2~dny), nastavitelná upozornění \cite{papertrail-pricing}, možnost použít Heroku doplněk pro jednoduché nastavení (nabízí dokonce více uložených logů -- 10~MB logů/den) \cite{heroku-papertrail},
\item \href{https://logentries.com/}{\textbf{Logentries}}: zdarma nabízí 5~GB logů/měsíc, 7~dní historie logů \cite{logentries-pricing}, nastavitelná upozornění \cite{logentries-pricing2}, možnost použít Heroku doplněk pro jednoduché nastavení \cite{heroku-logentries}.
\end{enumerate}
\section{Statické typování}\label{sec:staticketypovani}
V programovacích jazycích zajišťuje typový systém, že se v kódu pracuje s očekávanými hodnotami -- existují dva typové systémy, dynamický a statický \cite{types-study}. V následující podsekci se zaměřím na jejich srovnání a výhody zavedení typových anotací pro jazyky s dynamickým typováním. Poté se v dalších podsekcích zaměřím na možnosti přidání těchto anotací na klientskou a serverovou část ÚP.
\subsection{Srovnání s dynamickým typováním}
Staticky typované jazyky provádějí typovou kontrolu při kompilaci, dynamicky typované až při běhu \cite{types-study}. Jak uvádí autoři \cite{types-study}, vedou se neustálé debaty o nákladech a přínosech jednoho či druhého typu. Zastánci statického typování argumentují detekováním chyb před spuštěním, rychlejším během, větší srozumitelností kódu, možností pokročilých optimalizací kompilátorem \cite{types-study} a také údržbu kódu v dlouhodobém horizontu \cite{types-developerhowto}. Dynamicky typované jazyky jsou naopak vyzdvihovány pro svou vhodnost při procesu tvorby prototypů (umožní rychle psát a spustit kód bez vynaloženého úsilí psaním typových anotací), nenutí programátory explicitně omezovat produkované/konzumované hodnoty výrazů, to usnadňuje psaní flexibilního kódu s využitím dynamického chování (např. reflexe) \cite{types-study}.
V rámci aplikace ÚP se používá JavaScript a Python, oba tyto jazyky jsou dynamicky typované \cite{bp}. V rámci následujících podsekcí se zaměřím na možné způsoby zavedení statického typování v obou těchto jazycích, nejprve se zde ale budu věnovat dalším výhodám zavedení typových anotací do dynamicky typovaných jazyků.
JS je v současné době základem mnoha webových projektů a jsou zde tři firmy, které statické považování považovaly za natolik důležité, že se rozhodly investovat do statických typových systémů právě pro JS: nejprve Google vydal \href{https://developers.google.com/closure/compiler/}{Closure}, pak Microsoft vydal \href{https://www.typescriptlang.org/}{TypeScript} a nakonec Facebook vydává \href{https://flow.org/}{Flow} \cite{types-study}.
Na výhody zavedení zmíněných nástrojů se lze dívat z několika stran. Jeden z pohledů nabízí studie \enquote{\textit{To Type or Not to Type: Quantifying Detectable Bugs in JavaScript}} \cite{types-study}, kde se její autoři zaměřují na zodpovězení otázky, kolik procent veřejných chyb v kódech dokáží Flow (verze~0.30) a TypeScript (verze~2.0) odhalit. Pro práci zvolili vzorek opravených chyb z veřejných GitHub repozitářů (na základě statistických metod), každou chybu doplnili o anotace a testovali, zda tyto nástroje chybu odhalí -- ta by pak vůbec nemusela být do veřejného repozitáře zanesena. Ukázalo se, že oba nástroje naleznou významné procento veřejných chyb, oba totiž odhalily shodně 15~\%~chyb (každý nástroj odhalil 60 z 400~chyb, z toho oba odhalily 57~stejných chyb). K tomu je potřeba dodat několik faktů, které sami autoři uvádějí -- vzhledem k povaze studie, jež je zaměřená pouze na veřejné chyby v repozitářích, dochází k podcenění některých dopadů těchto nástrojů (kvůli kterým jsou mj. také používány). Mnoho z chyb, které tyto nástroje odhalí, se děje během samotného privátního vývoje, naproti tomu zvolené veřejné chyby plynou převážně z nedorozumění při specifikaci požadavků, což typové systémy nemohou detekovat. Statické typování také vylepšuje srozumitelnost programu, umožňuje lepší navigaci v kódu a inteligentní doplňování kódu, slouží jako dokumentace. Jak autoři sami uvádějí, je třeba brát také ale v úvahu fakt, že anotování si bere svou cenu za práci (v rámci studie se zabývali měřením této ceny a srovnáním obou nástrojů, vzhledem k tomu, že oba nástroje od té doby prošly mnoha změnami, konkrétní výsledky zde nebudou zmíněny). Autoři zde také vyzdvihávají projekt DefinitelyTyped (viz následující podsekce~\ref{subsec:types-frontend}) obsahující definice typů pro mnoho knihoven, ten se využívá pro TypeScript.
Dodání těchto typových anotací, jak již bylo zmíněno, stojí čas a může mírně snížit na počátku produktivitu týmu, jak ale uvádí \cite{types-developerhowto}, omezení v podobě typů je z dlouhodobého horizontu zejména pro větší aplikace velmi žádoucí.
\subsection{Klientská část}\label{subsec:types-frontend}
ECMAScript, jakožto standard, ze kterého vychází JavaScript, nijak nestandardizuje statické typování, ačkoliv v minulosti bylo několik pokusů o to jej zavést, není ale vyloučeno, že se v budoucnu do standardu typy dostanou \cite{types-ecma}. Pro typovou kontrolu v JS se nejvíce používá TypeScript (z dílny Microsoftu) a Flow (Facebook) \cite{types-objectcomputing}. Nejedná se ale o stejné typy nástrojů.
Flow je pouze nástroj pro typovou kontrolu, kde se pomocí definované syntaxe typy zapisují do běžného JS a výsledný kód se transpiluje (překládá pomocí nástroje Babel) do čistého JS, TypeScript je přímo jazyk postavený jako rozšíření běžného JS (mj. o statické typování) a pomocí TypeScript kompilátoru (resp. transpileru) se překládá do JS \cite{types-mariusschulz, types-objectcomputing}.
Výhodou Flow oproti TS je jeho pokročilé odvozování typů (\enquote{type inference}) pomocí analýzy datových toků (\enquote{data flow analysis}) -- TS sice odvozování nabízí také, ale nikoliv tak pokročilé, ve výsledku tedy u Flow není potřeba uvádět všechny typy a přesto dostaneme korektní chybová hlášení \cite{types-objectcomputing, types-medium}. To znamená, že s menším úsilím získáme v případě Flow větší pokrytí kódu typovou kontrolou \cite{types-jamie}. Jak ale autor \cite{types-medium} uvádí, přesto má smysl věnovat čas explicitnímu psaní typů pro striktnější kontrolu tak, aby Flow nějaký problém neminul.
Výhodou TS je rozsáhlá databáze typových definicí pro JS knihovny \href{https://github.com/DefinitelyTyped/DefinitelyTyped}{DefinitelyTyped} oproti velmi malé databázi \href{https://github.com/flow-typed/flow-typed}{flow-typed} -- tyto definice knihoven třetích stran se používají v případě, že knihovna sama o sobě nepoužívá anotace typů \cite{types-objectcomputing}.
Protože je Flow z dílny Facebooku, nabízí vestavěnou podporu pro React \cite{types-objectcomputing}. V TypeScriptu je naopak napsaný celý populární framework Angular a jedná se o primární jazyk při vývoji v tomto frameworku \cite{types-angular}.
Poměrně nedávnou novinkou je možnost transpilovat TS do čistého JS také pomocí nástroje Babel (jako Flow), ale s několika omezeními: všechny anotace typů se smažou a při transpilaci se neprovádí žádná typová kontrola, také není podporováno několik jazykových konstruktů TS, které se ale dají nahradit alternativami \cite{types-iamturns}. Babel tedy stejně jako kompilátor TS transpiluje kód do čistého JS (i když bez typové kontroly), ale navíc nabízí obrovské množství doplňků \cite{types-iamturns}. V případě, že chtěl dříve vývojář Babel použít, bylo možné Babel (nikoliv úplně jednoduše) začlenit do vývojového procesu a výstup TS kompilátoru zaslat do Babelu \cite{types-iamturns}. Nyní, s novým Babel~7, může využívat během vyvíjení jednoduché a rychlé transpilování do JS (rychlejší než TS kompilátor, který ještě musí provést typové kontroly) a typovou kontrolu pomocí TS kompilátoru vyvolat, až bude chtít \cite{types-iamturns}.
Na závěr je třeba říci, že se v poslední době objevuje mnoho firem, týmů a projektů včetně např. \href{https://jestjs.io/}{Jest} či \href{https://yarnpkg.com/}{Yarn} přecházejících právě z již zaběhnutého Flow na projektu na TypeScript -- zejména kvůli rozsáhlé databázi DefinitelyTyped a naopak malé databázi flow-typed (případně také způsobu použití jednotlivých definicí, v případě DefinitelyTyped se instalují jako běžné knihovny pomocí balíčkovacího systému, kdežto u flow-typed se stahují definice přímo do repozitáře jako soubory), pomalému vývoji samotného Flow, pomalé integraci Flow do editoru (a naproti tomu výborné podpoře editorů v případě TS) či obecně problémům se spouštěním a prací s Flow \cite{types-flow1, types-flow2, types-flow3}. Jak ale uvádí vývojáři Flow \cite{types-flow4}, na některé ze zmíněných problémů se v tomto roce~2020 budou zaměřovat.
\subsection{Serverová část}\label{subsec:staticketypovani-serverovacast}
Situace pro Python je v mnohém odlišná od té v JS. Poměrně nedávno (na konci roku~2016) získal Python~3.6 kompletní nativní podporu pro typové anotace, a to včetně různých pokročilých datových typů díky modulu \href{https://docs.python.org/3/library/typing.html}{typing} ze standardní knihovny \cite{types-python-bernat}. Není tedy třeba řešit jako v případě JS různé přístupy, způsoby anotace, rozšíření jazyka apod.
Anotace tedy máme, pro samotnou typovou kontrolu je třeba použít jeden z nástrojů pro typovou kontrolu v Pythonu -- referenčním nástrojem pro tuto typovou kontrolu je \href{http://mypy-lang.org/}{mypy} (ještě ale není stabilní, je v beta verzi, ale již několik let používán na produkci např. v Dropboxu \cite{mypy}) \cite{types-python-bernat}. Tým ze zmíněného Dropboxu (jehož členem je i autor samotného Pythonu Guido van Rossum) stojí za nástrojem mypy a přispívá i do dalších projektů týkajících se statického typování v Pythonu, Dropbox postupně anotuje serverovou část svého kódu v Pythonu čítající dnes přes 4~miliony anotovaných řádků kódu \cite{types-python-dropbox}. Alternativou k mypy je např. nástroj \href{https://github.com/facebook/pyre-check}{Pyre} (Facebook) či \href{https://github.com/google/pytype}{pytype}, liší se např. v rychlosti či podpoře odvozování typů z kódu bez anotací \cite{types-python-bernat, types-python-realpython}. Další možností je použít vestavěnou typovou kontrolu pro Python v IDE (Integrated Development Environment), např. v PyCharm (nebo Atom pomocí doplňku), jak ale doporučují autoři \cite{types-python-bernat, types-python-medium}, je vhodné tuto kontrolu doplnit i o některý z již zmíněných nástrojů pro typovou kontrolu -- protože se liší v implementaci typové kontroly a mohou tedy zachytit různé problémy.
Vývoj typových anotací v Pythonu pokračuje, přišlo se např. na dva problémy: nemožnost používat v anotacích typy, jejichž definice byla ve zdrojovém kódu později a také fakt, že přítomnost samotných anotací má negativní vliv na dobu spouštění programu, opravy přišly v Pythonu~3.7, chování je ale třeba explicitně povolit, ve výchozím stavu bude povolené až od Pythonu~4.0 \cite{python3.7}.
Co se týče typových anotací pro knihovny třetích stran, používá se projekt \href{https://github.com/python/typeshed}{typeshed}, kde jsou jak definice typů (nazývané \enquote{stubs}) pro standardní knihovny Pythonu, tak i pro některé knihovny třetích stran (pokud je tyto knihovny nemají již rovnou zabudované přímo v sobě), pro knihovny třetích stran může být definice také distribuována zvlášť jako balíček pro instalaci \cite{types-python-realpython, mypy-docs}. Definice z typeshed jsou automaticky přibaleny jako součást nástrojů pro typovou kontrolu (mypy, pytype a dokonce i PyCharm) \cite{typeshed}. Pro automatickou základní definici typů lze použít nástroje, které zvládnou vygenerovat různě pokročilé definice -- nástroje jako \href{https://github.com/dropbox/pyannotate}{PyAnnotate}, \href{https://github.com/Instagram/MonkeyType}{MonkeyType} či přímo mypy (příkazem \verb|stubgen|) -- generování probíhá na základě samotného kódu, testů či dokonce přímo z běhu programu \cite{types-python-bernat}.
Existují také nástroje jako \href{https://github.com/Stewori/pytypes}{pytypes} či \href{https://github.com/samuelcolvin/pydantic/}{pydantic}, které typy validují za běhu a umožňují tak např. zobrazit uživateli srozumitelnou chybu \cite{types-python-bernat, pydantic}.
\section{Statická analýza kódu}\label{sec:statickaanalyzakodu}
Statická analýza kódu je efektivní nástroj pro posouzení kvality kódu softwarového projektu (např. konzistence, čitelnost, zranitelnosti, rychlost, pokrytí testy) a předvídání potenciálně vznikajících problémů (tzv. \enquote{code smells}) bez spuštění samotného kódu \cite{medium-devgurus, static-overops}. Samotný kód je analyzován vůči sadě pravidel a standardů \cite{static-overops}.
Na základě vlastního průzkumu nástrojů zde zavádím vlastní dělení na nástroje představující vyšší a nižší vrstvu statické analýzy kódu, vysvětlení důvodů vedoucích k tomuto dělení následuje vzápětí.
V první podsekci se zaměřím na rešerši nástrojů na vyšší vrstvě, které umožňují průběžnou kontrolu kvality kódu. Jak je vidět z \cite{guru-codereview, gh-awesomecodereview, medium-devgurus,stackshare-codereview, gh-awesomecodereview2}, v této oblasti není úplně jednoznačná terminologie -- těmto nástrojům se často též říká nástroje pro posuzování kvality kódu, zaměřují se třeba i na pokročilou práci s manuálním posuzováním kódu ad., někdy se též nazývají nástroje pro \textit{automatické} posuzování kvality kódu, což už je k této sekci bližší. V této první podsekci se tedy zaměřím na ty nástroje, které poskytují právě automatickou průběžnou kontrolu kvality kódu a dávají poté zpětnou vazbu pro kód aplikace.
Ve druhé podsekci se zaměřím na nástroje z nižší vrstvy (tzv. lintery), na kterých často nástroje z vyšší vrstvy stavějí (proto také dělení na vyšší a nižší vrstvu pro lepší orientaci). Tyto nástroje se používají při samotném vývoji na lokálním zařízení a poté se mohou spouštět např. na integračním serveru.
\subsection{Průběžná kontrola kvality kódu}\label{subsec:prubeznakontrolakvalitykodu}
Na zmíněné vyšší vrstvě se nalézají nástroje, které jsou provozované jako služby automaticky kontrolující kvalitu kódu. Obvykle jsou to služby typu SaaS, případně On-Premise (tedy opak SaaS \cite{globema-onpremise}) \cite{codebeat-engines}. Tyto nástroje lze do procesu vývoje zapojit a zlepšovat tak kvalitu kódu už od počátku -- např. nastavit hranice pro kvalitu kódu vzhledem k pokrytí kódu testy a nulovému počtu nalezených problémů, na základě toho se pak může třeba PR (Pull Request) změn automaticky označit jako úspěšný nebo nikoliv \cite{medium-devgurus}. To pak snižuje množství diskuzí mezi vývojáři, protože je zavedeno objektivní hodnocení kódu \cite{medium-devgurus}. Nejprve uvedu minimální požadavky na nástroje pro zúžení výběru:
\begin{itemize}
\item zdarma pro použití na neomezenou dobu,
\item integrace s GitHub,
\item podpora JS, TS (TypeScript) a Python (ne nutně všech naráz),
\item SaaS -- tedy aplikace hostovaná provozovatelem služby \cite{oracle-saas}.
\end{itemize}
Při průzkumu nástrojů na této vyšší vrstvě jsem zjistil, že se prakticky dají dále rozdělit na dva typy podle nabízených možností:
\begin{enumerate}
\item Nástroje založené z valné většiny především na integraci mnoha různých nástrojů z nižší vrstvy (lintery, viz podsekce~\ref{subsec:lintery}), případně pouze na základních pravidlech pro kontrolu kódu jako např. délka metod, počet řádků souboru, složitost metod, duplikace apod. Jak uvádí \cite{globema-onpremise}, některé nástroje upřednostňují použití předvytvořených pravidel z jejich dílny místo integrace nástrojů kvůli lepší rozšířitelnosti a správě pravidel, ve výsledku pak tedy nabízejí alternativu ke službám integrující všechny standardní nástroje. Možná je také kombinace obou přístupů nebo funkce pro vytváření vlastních jednoduchých pravidel na míru projektu.
\item Nástroje založené na pokročilé hloubkové analýze kódu různými způsoby. Ty mohou být doplněné o možnost vytváření vlastních stejně pokročilých pravidel na míru projektu. Také mohou nabízet volitelnou integraci nástrojů z nižší vrstvy.
\end{enumerate}
Zde je na místě okomentovat, proč je toto rozdělení důležité. Nástroje prvního typu prakticky jen sdružují mnoho různých nástrojů na jednom místě, jejichž výsledky agregují a třídí přehledně na jednom místě. Právě toto sjednocení různých nástrojů do jedné služby je jejich přidaná hodnota oproti tomu, kdy by vývojář tyto nástroje spouštěl jednotlivě (nebo by ani u sebe nic pustit nemohl, protože se jedná pouze o pravidla z dílny dané služby). Nástroje druhého typu nabízejí pokročilou hloubkovou kontrolu kódu způsobem, jakým to běžné lintery, na kterých stojí nástroje prvního typu, nezvládnou (plyne to ze způsobu jejich fungování naznačeného v \ref{subsec:lintery}) \cite{deepscan-lintercompare}. Díky tomu umožňují vyhledat velmi závažné problémy, chyby či zranitelnosti, které by jinak mohly být opomenuty \cite{deepscan-lintercompare, deepsource2}. To zvládnou díky vlastním pokročilým pravidlům a analýzám založených např. na umělé inteligenci \cite{deepsource2}. Jejich výhodou také je, že obvykle najdou reálné problémy místo mnoha nedůležitých, které mohou poskytnout nástroje prvního typu -- tuto myšlenku vystihují autoři DeepSource \cite{deepsource2}: \enquote{\textit{DeepSource is designed to understand the context of your code and filter out the noise from the results. This prevents warning blindness and encourages developers to take action on issues that matter.}}
Nástroje prvního typu splňující minimální požadavky:
\begin{itemize}
\item \href{https://www.codacy.com}{\textbf{Codacy}}: zdarma \cite{codacy-pricing}, podporuje JS, TS i Python \cite{codacy-langs}, GitHub integrace pro PR i commity \cite{codacy-gh}, založeno na integraci mnoha nástrojů do jedné služby \cite{codacy-engines},
\item \href{https://codeclimate.com}{\textbf{Code Climate}}: zdarma \cite{codeclimate-pricing}, podporuje JS, TS i Python \cite{codeclimate}, GitHub integrace pro PR i commity \cite{codeclimate-gh}, založeno na integraci mnoha nástrojů do jedné služby a dalších základních pravidel \cite{codeclimate-engines},
\item \href{https://www.codefactor.io}{\textbf{CodeFactor}}: zdarma \cite{codefactor-pricing}, podporuje JS, TS i Python \cite{codefactor}, GitHub integrace pro PR i commity \cite{codefactor}, založeno na integraci mnoha nástrojů do jedné služby a dalších základních pravidel \cite{codefactor-engines},
\item \href{https://www.code-inspector.com}{\textbf{Code Inspector}}: zdarma \cite{codeinspector-pricing}, podporuje JS, TS i Python \cite{codeinspector}, GitHub integrace pro PR i commity \cite{codeinspector}, založeno pouze na základních pravidlech \cite{codeinspector, codeinspector-engines},
\item \href{https://codebeat.co}{\textbf{codebeat}}: zdarma \cite{codebeat-pricing}, podporuje JS, TS i Python \cite{codebeat}, GitHub integrace pro PR i commity \cite{codebeat}, založeno pouze na základních pravidlech \cite{codebeat-engines},
\item \href{https://houndci.com}{\textbf{HoundCI}}: zdarma \cite{houndci}, podporuje JS, TS i Python \cite{houndci}, GitHub integrace jen pro PR \cite{houndci}, založeno na integraci mnoha nástrojů do jedné služby \cite{houndci-engines},
\item \href{https://sider.review}{\textbf{Sider}}: zdarma \cite{sider-pricing}, podporuje JS, TS i Python \cite{sider-engines}, GitHub integrace jen pro PR \cite{sider}, založeno na integraci mnoha nástrojů do jedné služby a vytváření vlastních pravidel na míru projektu \cite{sider-engines}.
\end{itemize}
Nástroje druhého typu splňující minimální požadavky:
\begin{itemize}
\item \href{https://deepsource.io/}{\textbf{DeepSource}}: zdarma \cite{deepsource}, podporuje jen Python \cite{deepsource}, GitHub integrace pro PR i commity \cite{deepsource-docs}, založeno na pokročilé hloubkové analýze kódu \cite{deepsource2},
\item \href{https://deepscan.io}{\textbf{DeepScan}}: zdarma \cite{deepscan-pricing}, podporuje jen JS a TS (podporuje i React) \cite{deepscan}, GitHub integrace pro PR i commity \cite{deepscan}, založeno na pokročilé hloubkové analýze kódu \cite{deepscan}, možnost integrace ESLint \cite{deepscan-eslint},
\item \href{https://lgtm.com}{\textbf{LGTM}}: zdarma \cite{lgtm}, podporuje JS, TS i Python \cite{lgtm-faq}, GitHub integrace pro PR i commity (PR analyzuje vždy okamžitě, commity analyzuje jednou denně) \cite{lgtm-faq}, založeno na pokročilé hloubkové analýze kódu, možnost vytváření pokročilých pravidel na míru projektu \cite{lgtm},
\item \href{https://sonarcloud.io/}{\textbf{SonarCloud}}: zdarma \cite{sonarcloud}, podporuje JS, TS (podporuje i React \cite{sonarcloud-js}) i Python \cite{sonarcloud}, GitHub integrace pro PR i commity \cite{sonarcloud-gh}, založeno na pokročilé hloubkové analýze kódu \cite{sonarcloud2}, možnost připojit i vygenerované reporty z externích nástrojů (linterů) \cite{sonarcloud-engines},
\item \href{https://www.deepcode.ai/}{\textbf{DeepCode}}: zdarma \cite{deepcode}, nezávislé na jazyku \cite{deepsource2}, GitHub integrace pro PR i commity \cite{deepcode}, založeno na pokročilé hloubkové analýze kódu (používá rozsáhlé strojové učení) \cite{deepcode2}.
\end{itemize}
\subsection{Lintery}\label{subsec:lintery}
V předchozí sekci jsem uváděl, že některé nástroje (z vyšší vrstvy) z valné většiny staví na integraci mnoha drobnějších nástrojů (z nižší vrstvy), tzv. linterů. Smyslem této sekce je vysvětlit vlastnosti linterů a jejich fungování a poté prozkoumat možnosti použití pro aplikaci ÚP.
Lintery jsou nástroje provádějící statickou analýzu kódu \cite{linter-medium1}. V případě dynamicky typovaných jazyků můžeme říci, že z hlediska samotné statické analýzy nahrazují kompilátor staticky typovaných jazyků \cite{linter-medium1}. Pomáhají vyvarovat se mnoha (samozřejmě ne všech) chyb, které se mohou projevit až při běhu aplikace \cite{linter-medium1}.
Lintery pracují s uživatelem definovanou množinou pravidel a dohlíží na jejich splnění, pravidla jsou jak obecnějšího rázu, tak vytvořená na míru některým frameworkům/knihovnám (např. Reactu) \cite{linter-medium1}. Některá z pravidel umožňují lintery automaticky opravit bez manuálního zásahu programátora, některá pravidla opravit nelze (např. komplexní problémy jako použití zastaralého API ad.) a programátor musí kód opravit manuálně \cite{linter-medium1}. Pravidla lze rozdělit do dvou skupin -- logická (chyby v kódu, potenciální problémy, špatné vzory v kódu) a stylistická (kód podle konvencí) -- lintery pak podporují pravidla z jedné či obou skupin \cite{linter-realpython}.
Nástroje pro statickou analýzu kódu obvykle stojí na konceptu AST (Abstract Syntax Tree) -- ten reprezentuje zdrojový kód jako stromovou strukturu, kořen stromu je tvořen samotným souborem, jeho potomci jsou konstrukty z nejvyšší úrovně tohoto souboru atd. V případě linterů je pak AST použit pro kontrolu splnění všech definovaných pravidel napříč uzly stromu (případně pak i pro automatickou opravu přímo v daném místě) \cite{linter-medium1, linter-medium2}.
Než uvedu nejběžnější lintery používané pro jazyky v aplikaci ÚP, je třeba říci, že některé lintery prakticky jen zaobalují několik linterů dohromady (např. Flake8) \cite{linter-realpython}.
Pro \textbf{JS} je nejpopulárnější linter \href{https://eslint.org/}{ESLint}, je vysoce konfigurovatelný a nabízí integraci s mnoha různými nástroji, mnoho z pravidel lze automaticky opravit \cite{linter-medium1}. Mimo jiné nabízí možnost nakonfigurovat používání různých standardů (např. Airbnb) \cite{linter-restishistory} či dalších doplňků pro různé knihovny (např. pro React) \cite{react-eslint}. Před vznikem ESLint byl populární také \href{https://jshint.com/}{JSHint}, který vzešel z \href{https://jslint.com/}{JSLint} \cite{linter-restishistory}.
Pro \textbf{TS} byl používaný \href{https://palantir.github.io/tslint/}{TSLint}, ale v roce~2019 bylo oznámeno utlumení jeho vývoje ve prospěch rozvoje podpory TS pod jednou střechou v ESLint \cite{linter-eslintts}.
Pro \textbf{CSS} je velmi populární \href{https://stylelint.io/}{stylelint} \cite{stylelint, linter-css}, alternativou je \href{http://csslint.net/}{CSSLint}, který se ale už dle \cite{linter-css} moc nepoužívá a není udržovaný.
Pro \textbf{Python} je na výběr více linterů lišících se zaměřením definovaných pravidel -- na logická pravidla se zaměřuje \href{https://github.com/PyCQA/pyflakes}{Pyflakes} a \href{https://github.com/PyCQA/bandit}{Bandit}, na stylistická pravidla se zaměřuje \href{https://github.com/PyCQA/pycodestyle}{pycodestyle} a na obojí se zaměřuje \href{https://www.pylint.org/}{Pylint} (ten je používaný nejvíce \cite{linter-python}) \cite{linter-realpython}. Také se používají lintery, které zaobalují několik linterů dohromady -- \href{https://flake8.pycqa.org/en/latest/}{Flake8} (mj. Pyflakes, pycodestyle) a \href{https://github.com/klen/pylama}{Pylama} (mj. pycodestyle, Pyflakes, Pylint) \cite{linter-realpython}.
\subsection{Formattery}
Formattery jsou nástroje, které zajistí konzistentní formátování kódů -- to umožní jednodušší čitelnost, srozumitelnost a vyšší efektivitu při práci v týmu \cite{linter-medium1}. Umožní zaměřit se na to nejdůležitější -- co kód dělá, už není třeba řešit konkrétní způsob formátování kódu jednotlivými členy týmu \cite{linter-restishistory}.
Vzhledem k tomu, že formattery také pracují nad samotným kódem a provádějí jeho analýzu, lze je též řadit do této kapitoly \cite{linter-medium1}. Stejně jako lintery pracují nad AST -- soubor převedou do AST, ignorují nedůležité informace související s původním formátováním a výsledný upravený AST zapíšou zpět do souboru, konzistentně \cite{linter-medium1}. Díky tomuto přegenerování AST jsou v oblasti formátování kódu mnohem mocnější než samotné lintery, které, jak již bylo zmíněno v podsekci~\ref{subsec:lintery}, aplikují opravu pouze v daném místě AST, AST nepřegenerovávají celý -- proto se vyplatí používat lintery i formattery zároveň a nechat je pracovat v oblastech, kde excelují, tedy formatter pro komplexní formátování kódu a linter pro pravidla týkající se např. syntaxe, problémů a nových vlastností jazyka \cite{linter-medium2}. Tato kombinace umožní psát v týmu konzistentní kód, tedy kód, kde nelze prakticky poznat, kdo jej psal, nevyskytují se v něm špatné vzory a má méně chyb \cite{linter-restishistory}.
Pro \textbf{JS, TS a CSS} je nejpopulárnější formatter \href{https://prettier.io/}{Prettier} \cite{linter-medium1}.
Pro \textbf{Python} se používají 3~formattery: \href{https://github.com/psf/black}{Black}, \href{https://github.com/google/yapf}{YAPF}, \href{https://github.com/hhatto/autopep8}{autopep8} \cite{formatter-python, linter-realpython}. Liší se zejména konfigurovatelností a mírou splnění Python standardu PEP~8, Black se dá přirovnat svou ideologií k Prettier -- oba dva jsou totiž založeny na co nejmenší míře konfigurovatelnosti (tím pádem se snižuje diskuze ohledně zavedení jednotlivých konfigurací, protože není moc na výběr) \cite{linter-realpython}.
\chapter{Zvolené technologie}\label{chap:zvolenetechnologie}
V této kapitole uvedu, které nástroje a technologie zvolím pro použití a mj. je budu zavádět v následující praktické části. Volba bude obsahovat argumenty vycházející z provedených rešerší v rámci celé teoretické části.
\section{Testování}\label{sec:zvolenetechnologie-testovani}
V souladu se zadáním práce bude implementováno automatizované testování API a UI (v případě UI konkrétně E2E testování). Vzhledem k tomu, že v současné verzi aplikace chybělo testování úplně (resp. bylo zde několik jen velmi základních testů prakticky na smoke úrovni, viz sekce~\ref{sec:prostreditestovaninasazovani}), byl zvolen přístup orientace API a UI testů na klíčové funkce a průchody v aplikaci, aby bylo zajištěno, že obvykle používané části aplikace budou vždy za jakékoliv situace funkční. Vzhledem ke křehkosti UI testů bude při jejich implementaci kladen důraz na co nejvyšší nezávislost na detailech UI, aby při změnách nebylo třeba do testů zasahovat vůbec, nebo v co nejmenší míře. Výhodou zavedení testů API, které jsou v \enquote{testovací pyramidě} (viz sekce~\ref{fig:testing_pyramid}) na nižší úrovni než UI testy je právě větší stabilita API oproti UI a mnohem větší rychlost samotných testů. Navíc, pokud neprojdou API testy, není se třeba ani zatěžovat s UI testováním (klientská část totiž stojí na používání REST API). Ze strategie \enquote{testovací trofeje} (viz sekce~\ref{fig:testing_trophy}) bude vycházet použití nástrojů pro statické typování a statickou analýzu kódu (tedy nejnižší úroveň této strategie), jejichž volbu uvedu v následujících sekcích -- to umožní i bez tvorby dalších testů na nižších úrovních testovací pyramidy kontrolovat v přiměřené míře problémy a kvalitu kódu.
Manuální testování stále bude mít stále své místo v akceptační části, testech použitelnosti a při samotném vývoji.
Co se týče implementace samotného testování, bude kompletně provedeno v jazyce Python. Zde samozřejmě mohla padnout volba prakticky na jakýkoliv jazyk, smysl ale dává testování psát v jednom z již používaných jazyků v rámci projektu ÚP, tedy Python či JS. Python byl zvolen především z důvodu možnosti jednoduché integrace s Djangem a také proto, že celá část implementace testů byla vytvářena jako semestrální práce v rámci předmětu \textit{\href{https://courses.fit.cvut.cz/MI-PYT/}{MI-PYT}}. Pro testování bude využit nástroj behave založený na BDD -- tedy budou sepsány v prakticky přirozeném jazyce (Gherkin) scénáře, ke kterým budou implementovány testy. Kromě jasně definovaných scénářů tyto soubory díky zápisu v přirozeném jazyce poslouží jako dokumentace, což se hodí jak pro účely samotného projektu ÚP, tak i pro zmíněnou semestrální práci, kde tímto může být jednoduše splněn požadavek dokumentace bez jakékoliv práce navíc a vyučující pak má přehled o splnění úkolu. Pro UI testování bude využito Selenium, a to především díky faktu, že se jedná prakticky o standard v oblasti UI testování, je nejpoužívanější a rozšíří to i mé obzory v této mně dosud neznámé oblasti.
\section{Nástroje pro usnadnění vývoje a údržby}
V této sekci uvedu a oargumentuji zvolené nástroje nejprve pro monitorování chyb, pak správu logů a na závěr pro statické typování a statickou analýzu kódu. V některých případech bude volba ponechána z udaných důvodů až na praktickou část.
\subsection{Monitorování chyb}
Jako nástroj, který bude mít na starost monitorování chyb na serverové i klientské části aplikace jsem zvolil Sentry. Dle zjištěných informací (v sekci~\ref{sec:monitorovanichyb}) se jedná o nejpoužívanější nástroj v této oblasti a splňuje všechny vytyčené požadavky. Dále bude prozkoumána možnost použití LogRocket.
\subsection{Správa logů}
Pro správu logů, tedy nástroj, který bude z Heroku přebírat všechny logy, ukládat je a umožní v nich vyhledávat v historii a upozorňovat na zvolené události, byl zvolen nástroj Logentries. Dle zjištěných informací (v sekci~\ref{sec:spravalogu}) se sice jedná až o druhý nejpoužívanější nástroj v této oblasti splňující vytyčené požadavky, v porovnání s nejpoužívanějším nástrojem Papertrail ale nabízí více prostoru pro logy a umožní vyhledávat v záznamech starších než 2~dny.
\subsection{Statické typování}
Vzhledem k výhodám typových anotací (viz sekce~\ref{sec:staticketypovani}) budou zavedeny na serverové části (Python) i na klientské části (JS).
Na serverové části bude využita standardizovaná syntaxe zápisu anotací a pro kontrolu typů bude použit referenční nástroj mypy, protože je oficiální, a také vestavěná typová kontrola IDE PyCharm. Volba nástrojů pro typovou kontrolu není nevratný krok a v případě zjištěných nedostatků je lze jednoduše nahradit za jiné nalezené alternativy.
Na klientské části napsané v JS, který nenabízí standardizovanou syntaxi pro anotaci typů (viz podsekce~\ref{subsec:types-frontend}), se nabízí volba mezi Flow a TypeScript. Použití Flow dává smysl z hlediska architektury klientské části, která je postavena na Reactu -- oba nástroje pochází z dílny Facebooku -- Flow nabízí nativní podporu Reactu a je jednoduché jej začlenit do stávajícího projektu (nevyžaduje např. kompilátor apod.). Použití TypeScriptu naopak dává smysl z hlediska lepší podpory typových definicí knihoven třetích stran, lepší integraci s IDE a časté migraci i větších projektů právě z Flow na TS. I přes poměrně rozsáhlou rešerši ale volbu mezi těmito dvěma nástroji neprovedu rovnou zde v teoretické části a přenechám ji do části praktické, kde provedu zkušební zavedení Flow i TS do projektu a až na základě vlastních zkušeností (a ověření pravdivosti výroků zjištěných v rešerši) a zvážení provedu finální volbu a kompletní migraci.
\subsection{Statická analýza kódu}
V rámci rešerše jsem zjistil, že se nástroje pro statickou analýzu dají rozdělit na několik částí. Lze na ně nahlížet podle vrstev -- na nástroje z vyšší vrstvy pro průběžnou kontrolu kvality kódu a z nižší vrstvy, což jsou prakticky lintery.
Nástroje z vyšší vrstvy jsem dále dělil do dvou typů podle dalších nabízených možností -- vzhledem k velké podobnosti nástrojů na této vyšší vrstvě budou v praktické části otestovány všechny nalezené nástroje a na základě jejich funkčnosti, nalezených problémů, nabízených funkcí a přívětivosti pak budou zvoleny ty vhodné pro tento projekt.
Linter (nástroj z nižší vrstvy) pro klientskou část bude ESLint, který je v této oblasti nejpopulárnější. Pro CSS se použije též nejpoužívanější stylelint. Vzhledem k tomu, že kód serverové části oproti té klientské není tolik rozsáhlý, nebude prozatím zaváděn linter pro Python, využije se služeb pouze formatteru a nástrojů pro statickou analýzu kódu z vyšší vrstvy.
Formatter pro JS (případně TS) a CSS bude Prettier, který je v této oblasti nejpopulárnější. Pro Python bude použit jeho ekvivalent Black (ekvivalent z hlediska faktu, že oba nabízejí minimální možnost konfigurovatelnosti), protože pokročilá konfigurovatelnost nebude potřeba.