Ahoj, Habr!
Jmenuji se Maxim Ponomarenko a jsem vývojář ve Sportmasteru. Mám desetiletou zkušenost v IT oblasti. Kariéru jsem začal v oblasti manuálního testování, poté jsem se přeorientoval na vývoj databází. Poslední čtyři roky, s využitím znalostí získaných při testování a vývoji, se zabývám automatizací testování na úrovni DBMS.
V týmu Sportmasteru jsem už něco málo přes rok a na jednom z velkých projektů se zabývám vývojem automatizovaného testování. V dubnu jsme s kluky z Sportmaster Lab vystupovali na konferenci v Krasnodaru, můj příspěvek se nazýval „Unit testy v DBMS“, a nyní se s vámi o něj chci podělit. Textu bude hodně, proto jsem se rozhodl rozdělit příspěvek na dva. V první části si povíme o automatizovaných testech a testování obecně, a ve druhé se podrobněji zaměřím na náš systém unit testování a výsledky jeho použití.
Na začátku trochu nudné teorie. Co je to automatizované testování? Je to testování, které se provádí pomocí softwarových prostředků, a v moderním IT se stále častěji používá při vývoji softwaru. Je to způsobeno tím, že společnosti rostou, rostou jejich informační systémy a tím pádem roste i množství funkcionality, kterou je nutné testovat. Provádět manuální testování se stává stále nákladnějším a obtížnějším.
Pracoval jsem v jedné velké společnosti, jejíž verze vycházejí každé dva měsíce. Přičemž celý měsíc se věnoval deseti testerům, kteří manuálně ověřovali funkčnost. Díky zavedení automatizace s malým týmem vývojářů se nám podařilo za rok a půl zkrátit dobu testování na 2 týdny. Nejenže jsme zvýšili rychlost testování, ale také jsme zlepšili jeho kvalitu. Automatizované testy se spouštějí pravidelně a vždy provádějí celý soubor předem stanovených kontrol, tedy vylučujeme lidský faktor.
Pro moderní IT je charakteristické, že od vývojáře se očekává nejen psaní kódu produktu, ale také psaní unit testů, které tento kód ověřují.
Co však dělat, pokud je váš systém převážně založen na serverové logice? Na trhu neexistuje žádné univerzální řešení ani nejlepší postupy. Obvykle společnosti tuto problematiku řeší vytvářením vlastního testovacího systému. Takovýto vlastní automatizovaný testovací systém byl vytvořen v našem projektu, o kterém se zmíním ve své prezentaci.

Testujeme loajalitu
Nejprve si povíme o projektu, kde jsme nasadili systém automatizovaného testování. Náš projekt je systém loajality Sportmasteru (mimochodem, již jsme o něm psali v ).
Pokud je vaše společnost dostatečně velká, má váš systém loajality tři standardní vlastnosti:
- Váš systém bude vysoce zatížený
- Váš systém bude obsahovat složité výpočetní procesy
- Váš systém bude aktivně rozšiřován.
Pojďme to vzít chronologicky... Souhrnně, pokud zohledníme všechny značky Sportmasteru, máme na území Ruska, Ukrajiny, Číny, Kazachstánu a Běloruska více než 1000 obchodů. V těchto obchodech se denně uskuteční kolem 300 000 nákupů. To znamená, že každou sekundu k nám přicházejí 3-4 účty. Samozřejmě, náš systém loajality je vysoce zatížený. A protože je aktivně používán, musíme poskytovat nejvyšší standardy její kvality, protože jakákoliv chyba v softwaru přináší velké finanční, reputační a další ztráty.
Současně v Sportmasteru funguje více než sto různých akcí. Akce jsou různé: existují zbožové akce, akce podle dne v týdnu, akce vázané na konkrétní obchod, akce na výši účtu, akce na počet zboží. Zkrátka, není to jednoduché. Zákazníci mají bonusy, existují promo kódy, které se používají při nákupech. To vše vede k tomu, že vyhodnocení jakékoli objednávky je poměrně složitý úkol.
Algoritmus, který realizuje zpracování objednávek, je opravdu hrozný a složitý. Jakékoli úpravy tohoto algoritmu představují značné riziko. I zdánlivě nevýznamné změny mohou vést k velmi nepředvídatelným efektům. A přitom jsou právě takové složité výpočetní procesy, zejména ty, které realizují kritickou funkcionalitu, nejlepšími kandidáty na automatizaci. Kontrola desítek shodných případů ručně je časově nákladná. A protože vstupní bod do procesu zůstává nezměněn, lze jej jednou popsat a poté rychle vytvořit automatické testy a mít jistotu v bezchybnosti funkčnosti.
Naše systém je aktivně využíván, takže podnik bude očekávat od vás něco nového, držet krok s dobou a být orientován na klienty. V našem systému věrnosti vycházejí vydání každé dva měsíce. To znamená, že každé dva měsíce musíme provádět úplný regres celého systému. Samozřejmě, stejně jako v každém moderním IT, vývoj neprochází okamžitě na produkci. Začíná na vývojové lince, poté postupně prochází testovacím prostředím, releasovým, akceptačním a až poté se dostává na produkci. Minimálně na testovacím a releasovém prostředí musíme provádět úplný regres celého systému.
Popisované vlastnosti jsou standardní pro prakticky jakýkoliv systém věrnosti. Pojďme si promluvit o zvláštnostech našeho projektu.
Technologicky je logika našeho systému věrnosti z 90 % serverová a je implementována na Oracle. Existuje klient vystavený na Delphi, který vykonává funkci APM administrátora. Existují vystavené webové služby pro externí aplikace (například webové stránky). Je tedy docela logické, že pokud budeme zavádět systém automatizovaného testování, budeme to dělat na Oracle.
Loajalitní systém ve Sportmasteru existuje více než 7 let a byl vyvinut jednotlivými vývojáři... Průměrný počet vývojářů na našem projektu v průběhu těchto 7 let činil 3-4 osoby. Avšak v posledním roce se náš tým výrazně rozrostl a nyní na projektu pracuje 10 lidí. To znamená, že do projektu přicházejí lidé, kteří nejsou obeznámeni s běžnými úkoly, procesy a architekturou. A existuje zvýšené riziko, že přehlédneme chyby.
Pro projekt je charakteristické, že neexistují vyčlenění testovací prostředky jako stálé jednotky. Testování samozřejmě probíhá, ale testováním se zabývají analytici vedle svých dalších hlavních povinností: komunikace s obchodními zákazníky, uživateli, zpracovávání požadavků na systém atd. a tak dále... I přes to, že testování probíhá velmi kvalitně (což je důležité zmínit, protože se to může dostat k některému z analytiků), efektivita specializace a soustředění na jednu věc nikdo nezrušil.
Vzhledem k uvedenému se pro zvýšení kvality dodávaného produktu a zkrácení doby vývoje je myšlenka automatizace testování v projektu velmi logická. V různých etapách existence loajalitního systému se jednotliví vývojáři snažili pokrýt svůj kód jednotkovými testy. Celkově to byl poměrně roztržený proces, kde každý používal svou architekturu a metody. Společným výsledkem pro jednotkové testy bylo, že testy byly vyvíjeny, nějakou dobu používány, ukládány do verzovacího úložiště souborů, ale v určitém okamžiku přestaly běžet a byly zapomenuty. V první řadě se to stalo proto, že testy byly více vázány na konkrétního provádějícího, než na projekt.
Pomoci přichází utPLSQL

Vííte něco o Stephenovi Feuersteinovi?
Toto je chytrý chlapík, který značnou část své kariéry věnoval práci s Oracle a PL/SQL, napsal o tom dost velké množství prací. Jedna známá jeho kniha se dokonce jmenuje: „Oracle PL/SQL. Pro profesionály“. Právě Stephen je autorem řešení utPLSQL, což je zkratka pro Unit Testing framework for Oracle PL/SQL. Řešení utPLSQL bylo vytvořeno v roce 2016, ale nadále se na něm aktivně pracuje a vydávají se nové verze. K datu přednášky byla poslední verze datována k 24. březnu 2019.
Co to vlastně je? Je to samostatný open source projekt. Váží pár megabajtů i s příklady a dokumentací. Fyzicky představuje samostatné schéma v databázi ORACLE se sadou balíčků a tabulek pro organizaci jednotkového testování. Instalace trvá jen pár sekund. Vynikající vlastností utPLSQL je jednoduchost používání.
Globálně utPLSQL představuje mechanismus pro spouštění jednotkových testů, přičemž pod jednotkovým testem rozumíme běžné balíčkové procedury Oracle, jejichž organizace vyhovuje určitým pravidlům. Kromě spuštění v utPLSQL se uchovává log všech vašich testovacích běhů a také zde je interní systém reportování.
Podívejme se na příkladu, jak vypadá kód jednotkového testu implementovaného podle této metodiky.

Na obrazovce je zobrazen kód typické specifikace balíčku s jednotkovými testy. Jaké jsou povinné požadavky? Balíček musí mít prefix „utp_“. Stejný prefix by měly mít všechny procedury s testy. Balíček musí obsahovat dvě standardní procedury: „utp_setup“ a „utp_teardown“. První procedura se volá před každým jednotkovým testem, druhá — po jeho spuštění.
„utp_setup“ obvykle připravuje náš systém k provedení jednotkového testu, například vytváří testovací data. „utp_teardown“ — naopak, všechno vrací do výchozího nastavení a resetuje výsledky běhu.
Toto je příklad nejjednoduššího unit testu, který ověřuje normalizaci zadaného telefonního čísla klienta na standardní formát naší loajalitní systému. Neexistují žádné závazné standardy, jak psát procedury s unit testy. Obvykle se provádí volání nějaké metody testovaného systému a výsledek vrácený touto metodou se porovnává s referenčním. Je důležité, aby porovnání referenčního a získaného výsledku probíhalo prostřednictvím standardních metod utPLSQL.
V unit testu může být libovolný počet kontrol. Jak je vidět z příkladu, provádíme čtyři sekvenční volání testované metody pro normalizaci telefonního čísla a po každém volání hodnotíme výsledek. Při vývoji unit testu je třeba brát v úvahu, že existují kontroly, které nemají žádný vliv na systém, a po některých je nutné se vrátit do výchozího stavu systému.
Například v uvedeném unit testu pouze formátujeme vstupní telefonní číslo, což nijak neovlivňuje loajalitní systém.
A pokud píšeme unit testy pro metodu vytváření nového klienta, pak po každé kontrole bude v systému vytvořen nový klient, což může ovlivnit další spuštění testu.

Takto se spouští unit testy. Jsou přípustné dvě varianty spuštění: spuštění všech unit testů z konkrétního balíčku nebo spuštění konkrétního unit testu v konkrétním balíčku.

Takto vypadá příklad interního systému reportingu. Na základě výsledků práce unit testu utPLSQL vytváří malou zprávu. V ní vidíme výsledek každé konkrétní kontroly a celkový výsledek provedení unit testu.
6 pravidel automatizovaných testů
Před tím, než jsme začali vytvářet nový systém automatizovaného testování loajalitního systému, jsme společně s vedením stanovili principy, kterým by naše budoucí automatizované testy měly vyhovovat.

- Automatizované testy by měly být efektivní a měly by přinášet prospěch. Máme skvělé vývojáře, o kterých je třeba mluvit, protože někteří z nich toto sdělení určitě uvidí, a píší skvělý kód. Ale i jejich skvělý kód není dokonalý a obsahoval, obsahuje a bude obsahovat chyby. Automatizované testy by měly tyto chyby odhalit. Pokud ne, buď píšeme špatné automatizované testy, nebo jsme se dostali do mrtvé zóny, která se v zásadě nedotahuje. V obou případech děláme něco špatně a náš přístup je jednoduše bezvýznamný.
- Automatizované testy by měly být používány. Je bezvýznamné strávit spoustu času a úsilí na psaní softwarového produktu, uložit jeho repozitář a zapomenout na něj. Testy by měly být spouštěny, a to co nejpravidelněji.
- Automatizované testy by měly fungovat stabilně. Bez ohledu na denní dobu, spouštěcí stanici a další nastavení systému by měly testy vždy přinášet stejný výsledek. Obvykle je to zajištěno tím, že automatizované testy pracují se speciálními testovacími daty s fixními nastaveními systému.
- Automatizované testy by měly pracovat s přijatelnou rychlostí pro váš projekt. Tato doba je určena individuálně pro každý systém. Někdo si může dovolit pracovat celý den, zatímco jiní musí být kriticky rychlí, aby se vešli do sekund. Jakých rychlostních norem jsme dosáhli v našem projektu, povím trochu později.
- Vývoj automatizovaných testů by měl být flexibilní. Není žádoucí se vzdávat testování jakékoli funkce jen proto, že jsme to ještě nedělali nebo z nějakých jiných důvodů. utPLSQL nekladou žádná omezení na vývoj a Oracle v zásadě umožňuje realizovat různé věci. Většina úloh má řešení, otázka je pouze času a vynaloženého úsilí.
- Nasazení. Máme několik stanic, kde je potřeba spouštění testů. Na každé z těchto stanic může být kdykoli aktualizován dump dat. Je třeba vést projekt s automatizovanými testy tak, aby bylo možné bezbolestně provádět jeho úplnou nebo částečnou instalaci.
A ve druhém příspěvku za pár dní povím, co jsme udělali a jakých výsledků jsme dosáhli.
Zdroj: habr.com
