Unit тестове в СУБД — как го правим в Спортмастера, част първа

Здравейте, Хабр!

Казвам се Максим Пономаренко и съм разработчик в Спортмастера. Имам 10 години опит в IT сферата. Започнах кариерата си в областта на ръчните тестове, след което преминах към разработка на бази данни. През последните 4 години, натрупвайки знания от тестовете и разработката, се занимавам с автоматизация на тестовете на ниво СУБД.

В екипа на Спортмастера съм малко повече от година и по един от големите проекти се занимавам с разработка на автоматизирано тестване. През април, заедно с момчетата от Sportmaster Lab, участвахме в конференция в Краснодар, а моята презентация беше на тема „Unit тестове в СУБД“, и сега искам да я споделя с вас. Текста ще бъде много, затова реших да разделя презентацията на два поста. В първия ще говорим за автоматизираните тестове и тестването като цяло, а във втория ще се спра по-подробно на нашата система за unit тестване и резултатите от нейното приложение.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

Първо, малко скучна теория. Какво е автоматизирано тестване? Това е тестване, което се провежда с помощта на софтуерни средства, и в съвременния IT сектор то се използва все по-често при разработката на софтуер. Свързано е с факта, че компаниите растат, информационните им системи нарастват и съответно увеличава и количеството функционалности, които трябва да се тестват. Провеждането на ръчни тестове става все по-скъпо и трудно.

Работил съм в една голяма компания, чийто релизи излизат на всеки два месеца. През целия този месец десетина тестери проверяваха функционалността на ръка. Благодарение на внедряването на автоматизация от малък екип разработчици, успяхме да съкратим времето за тестване до 2 седмици след 1,5 години работа. Не само увеличихме скоростта на тестването, но и повишихме качеството му. Автоматизираните тестове се стартират регулярно и винаги преминават през целия набор проверки, заложени в тях, което елиминира човешкия фактор.

За съвременния IT е характерно, че от разработчици може да се изисква не само да пишат код на продукта, но и да пишат unit тестове, които да проверяват този код.

Но какво да правим, ако вашата система е предимно базирана на серверна логика? Няма универсално решение и добри практики на пазара. Обикновено, компаниите решават този проблем, създавайки собствена система за тестване. Такава собствена система за автоматизирано тестване беше създадена в нашия проект, за който ще говоря в своята презентация.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

Тестиране на лоялността

Първо, да поговорим за проекта, в който внедрихме системата за автоматизирано тестване. Нашият проект е система за лоялност на Спортмастера (между другото, вече писахме за него в този пост).

Ако вашата компания е достатъчно голяма, то вашата система за лоялност ще притежава три стандартни свойства:

  • Вашата система ще бъде с високи натоварвания
  • Вашата система ще съдържа сложни изчислителни процеси
  • Вашата система ще се доразвива активно.

Нека да ги разгледаме по ред... В съвкупност, ако разгледаме всичките брандове на Спортмастера, на територията на Русия, Украйна, Китай, Казахстан и Беларус имаме над 1000 магазина. В тези магазини ежедневно се извършват около 300 000 покупки. Тоест всяка секунда в нашата система постъпват 3-4 фискални документа. Естествено, нашата система за лоялност е с високи натоварвания. И понеже тя активно се използва, трябва да предоставим най-високите стандартни за нейното качество, тъй като всяка грешка в софтуера води до големи финансови, репутационни и други загуби.

В същото време в Спортмастера работят над сто различни акции. Акциите са най-разнообразни: има стокови, има свързани с деня от седмицата, има обвързани с конкретен магазин, има акции за сума на чека, има на брой стоки. В общи линии, доста впечатляващо. Клиентите имат бонуси, имат промокодове, които се използват при покупки. Всичко това води до факта, че обработката на всяка поръчка е доста нетривиална задача.

Алгоритъмът, реализиращ обработка на поръчка, е наистина ужасяващ и сложен. Всяко изменение в този алгоритъм е доста рискова работа. Дори най-добрите на вид изменения могат да доведат до неочаквани ефекти. В крайна сметка, именно такива сложни изчислителни процеси, особено онези, които реализират критична функционалност, са най-добрите кандидати за автоматизация. Проверяването на десетки идентични случаи ръчно отнема много време. А тъй като входната точка в процеса остава непроменена, описвайки я веднъж, можем да създадем автоматизирани тестове доста бързо и да сме сигурни в работата на функционалността.

Тъй като нашата система се използва активно, бизнесът ще иска от вас нещо ново, да бъде в крак с времето и да е ориентирован към клиента. В нашата система за лоялност релизите излизат на всеки два месеца. Следователно, на всеки два месеца трябва да извършваме пълен регрес на цялата система. При това, естествено, както и в всяка съвременна IT среда, разработването не попада директно от разработчика на продукцията. То започва от контурa на разработчика, след което последователно преминава през тестовия, релизния, приемния накрая стига до продукцията. Най-малко на тестовия и релизния контур трябва да проведем пълен регрес на целия система.

Описаните свойства са стандартни за почти всяка система за лоялност. Нека поговорим за особеностите на нашия проект.

Технологично 90% от логиката на нашата система за лоялност е сървърна и е реализирана на Oracle. Има клиент на Delphi, който изпълнява функцията на АРМ-администратора. Съществуват уеб услуга за външни приложения (например уебсайт). Следователно е логично, че ако развиваме система за автоматизирано тестване, това ще бъде направено на Oracle.

Системата за лоялност в Спортмастера съществува повече от 7 години и е разработвана от единични разрабочици… Средното количество разработчици в нашия проект през тези 7 години е било 3-4 човека. Но през последната година нашият екип значително се увеличи и вече над проекта работят 10 човека. Тоест в проекта постъпват хора, които не са запознати с типичните задачи, процеси, архитектура. И има увеличен риск да пропускаме грешки.

За проекта е характерно отсъствието на определени тестери като щатни единици. Тестиране, безусловно, има, но с тестиране се занимават анализатори, в допълнение на своите основни задължения: комуникиране с бизнес-клиенти, потребители, разработване на изисквания за системата и т.н.… Въпреки че тестовете се провеждат с много високо качество (особено важно е да се спомене, тъй като някой от анализаторите може да се натъкне на този доклад), ефикасността на специализацията и концентрацията върху нещо едно не е отменена.

Като вземем предвид всичко казано дотук, за повишаване на качеството на предоставяния продукт и намаляване на сроковете за разработка, идеята за автоматизиране на тестове в проекта изглежда напълно логична. И на различни етапи от съществуването на системата за лоялност отделни разработчици са полагали усилия да покрият своя код с юнит тестове. Това е бил сравнително разпокъсан процес, при който всеки е използвал своята архитектура и методи. Общото за юнит тестовете е, че резултатите от тях: тестовете са били разработвани, използвани за известно време, складирани във версия на архив с файлове, но в един момент са спирали да се стартират и са били забравяни. Първоначално това се е случвало, защото тестовете са били свързани повече с конкретен изпълнител, а не с проекта.

На помощ идва utPLSQL

Unit тестове в СУБД — как го правим в Спортмастера, част първа

Знаете ли нещо за Стивън Фейерштайн?

Това е умен човек, който е посветил значителна част от кариерата си на работа с Oracle и PL/SQL, написвайки доста голямо количество трудове по темата. Една известна негова книга носи заглавието: «Oracle PL/SQL. За професионалисти». Именно на Стивън се дължи разработката на решението utPLSQL, или, както се разшифрова, Unit Testing framework for Oracle PL/SQL. Решението utPLSQL е създадено през 2016 година, но активно се работи по него и се пускат нови версии. Към момента на доклада последната версия е дата от 24 март 2019 година.
Какво е това? Това е отделен open-source проект. Размерът му е няколко мегабайта с вземане предвид на примери и документация. Физически представлява отделна схема в базата данни ORACLE с набор от пакети и таблици за организиране на юнит-тестиране. Инсталацията отнема само няколко секунди. Отличителна черта на utPLSQL е простотата на експлоатация.
Глобално, utPLSQL представлява механизъм за изпълнение на юнит-тестове, където под юнит-тест разбираме обикновени пакетни процедури на Oracle, чието организиране отговаря на определени правила. Освен изпълнението, utPLSQL съхранява лог на всичките ви тестови стартирания, а също така разполага с вътрешна система за отчети.

Нека разгледаме примера, за да видим как изглежда кодът на юнит-тест, реализиран по тази методика.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

И така, на екрана е представен кодът на типова спецификация на пакет с юнит-тестове. Какви са задължителните изисквания? Пакетът трябва да има префикс «utp_». Всички процедури с тестове също трябва да имат същия префикс. В пакета задължително трябва да присъстват две стандартни процедури: «utp_setup» и «utp_teardown». Първата процедура се извиква при рестартиране на всеки юнит-тест, а втората — след изпълнението.

«utp_setup», като правило, подготвя нашата система за изпълнение на юнит-теста, например, създава тестови данни. «utp_teardown» — обратно, възстановява всичко до първоначалните настройки и нулира резултатите от изпълнението.

Ето пример на най-простия unit тест, който проверява нормализацията на въведения номер на телефона на клиента до стандартния формат за нашата система за лоялност. Няма задължителни стандарти за това как да се пишат процедури с unit тестове. Обикновено се извиква метод от тестваната система и резултатът, върнат от този метод, се сравнява с еталонния. Важно е сравняването на еталонния резултат с получения да се извършва чрез стандартни методи на utPLSQL.

В юнит теста може да има произволен брой проверки. Както се вижда от примера, правим четири последователни извиквания на тествания метод за нормализация на номера на телефона и след всяко извикване оценяваме резултата. При разработването на юнит тест трябва да се има предвид, че съществуват проверки, които нямат никакво влияние върху системата, а след някои трябва да се върнем към изходното състояние на системата.
Например, в представения юнит тест просто форматираме входящия номер на телефона, което по никакъв начин не влияе на системата за лоялност.

Ако пишем юнит тестове за метода за създаване на нов клиент, след всяка проверка в системата ще бъде създаден нов клиент, което може да повлияе на последващото изпълнение на теста.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

Така се стартират unit тестовете. Допустими са два варианта на стартиране: стартиране на всички юнит тестове от конкретен пакет или стартиране на конкретен юнит тест в конкретния пакет.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

Така изглежда пример на вътрешната система за отчетност. На базата на резултатите от работата на юнит теста utPLSQL изгражда малък отчет. В него виждаме резултата за всяка конкретна проверка и общия резултат от изпълнението на юнит теста.

6 правила за автоматични тестове

Преди да започнем със създаването на нова система за автоматизирано тестване на системата за лоялност, заедно с ръководството определихме принципите, на които нашите бъдещи автоматични тестове трябва да отговарят.

Unit тестове в СУБД — как го правим в Спортмастера, част първа

  1. Автотестовете трябва да бъдат ефективни и да носят полза. Имаме чудесни разработчици, за които е важно да споменем, защото някой от тях вероятно ще види тази презентация, и те пишат страхотен код. Но дори техният страхотен код не е идеален и съдържа, съдържа и ще съдържа грешки. Автотестовете са длъжни да откриват тези грешки. Ако не е така, то или пишем лоши автотестове, или сме попаднали в мъртва зона, която изобщо не се доразвива. В двата случая правим нещо неправилно и нашият подход е просто безсмислен.
  2. Автотестовете трябва да се използват. Безсмислено е да се изразходва огромно количество време и усилия за написването на продукт, да се създаде репозитория за него и да се забрави. Тестовете трябва да се изпълняват и да се стартират колкото се може по-редовно.
  3. Автотестовете трябва да работят стабилно. Независимо от времето на денонощието, средата за изпълнение и други настройки на системата, изпълненията на тестовете трябва да дават един и същ резултат. Обикновено това се осигурява от факта, че автотестовете работят с специални тестови данни с фиксирани настройки на системата.
  4. Автотестовете трябва да работят с приемлива скорост за вашия проект. Това време се определя индивидуално за всяка система. Някой може да си позволи да работи цял ден, а за друг е критично да се вмести в секунди. Какви скорости постигнахме в нашия проект, ще разкажа малко по-късно.
  5. Разработването на автотестове трябва да бъде гъвкаво. Нежелателно е да се отказваме от проверката на определен функционал само защото не сме го правили досега или по някакви други убеждения. utPLSQL не налага никакви ограничения на разработката, а Oracle в принцип позволява реализирането на най-различни решения. Повечето задачи имат решение, въпросът е само във времето и вложените усилия.
  6. Разгърнатост. Имаме няколко стенда, на които е необходимо да се изпълняват тестове. На всеки от стендовете по всяко време може да бъде обновен дамп с данни. Трябва да управляваме проекта с автотестове по такъв начин, че да можем безболезнено да извършваме неговата пълна или частична инсталация.

А в втория пост след няколко дни ще разкажа какво направихме и какви резултати постигнахме.

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster