Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Hej Habr!

Jag heter Maxim Ponomarenko och är utvecklare på Sportmaster. Jag har 10 års erfarenhet inom IT-området. Han började sin karriär inom manuell testning och gick sedan över till databasutveckling. Under de senaste 4 åren har jag, med ackumulering av den kunskap jag fått inom testning och utveckling, automatiserat testning på DBMS-nivå.

Jag har varit med i Sportmaster-teamet i drygt ett år och håller på att utveckla automatiserade tester på ett av de stora projekten. I april talade killarna från Sportmaster Lab och jag på en konferens i Krasnodar, min rapport hette "Enhetstester i ett DBMS", och nu vill jag dela den med er. Det blir mycket text, så jag bestämde mig för att dela upp rapporten i två inlägg. I den första kommer vi att prata om autotester och testning i allmänhet, och i den andra kommer jag att uppehålla mig mer i detalj vid vårt enhetstestsystem och resultaten av dess tillämpning.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Först en lite tråkig teori. Vad är automatiserad testning? Detta är tester som utförs med hjälp av mjukvara och inom modern IT används det allt mer i mjukvaruutveckling. Detta beror på att företagen växer, deras informationssystem växer och följaktligen ökar mängden funktionalitet som behöver testas. Att genomföra manuella tester blir allt dyrare.

Jag arbetade för ett stort företag vars releaser kommer ut varannan månad. Samtidigt ägnades en hel månad åt att låta ett dussin testare manuellt kontrollera funktionaliteten. Tack vare implementeringen av automatisering av ett litet team av utvecklare kunde vi minska testtiden till 2 veckor på ett och ett halvt år. Vi har inte bara ökat testhastigheten, utan också förbättrat dess kvalitet. Automatiserade tester lanseras regelbundet och de utför alltid hela loppet av kontroller som ingår i dem, det vill säga vi utesluter den mänskliga faktorn.

Modern IT kännetecknas av att en utvecklare kan behöva inte bara skriva produktkod, utan även skriva enhetstester som kontrollerar denna kod.

Men vad händer om ditt system huvudsakligen är baserat på serverlogik? Det finns ingen universell lösning eller bästa praxis på marknaden. Som regel löser företag detta problem genom att skapa ett eget självskrivet testsystem. Detta är vårt eget självskrivna automatiserade testsystem som skapades på vårt projekt och jag kommer att prata om det i min rapport.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Testar lojalitet

Låt oss först prata om projektet där vi implementerade ett automatiserat testsystem. Vårt projekt är Sportmasters lojalitetssystem (förresten, vi har redan skrivit om det i den här posten).

Om ditt företag är tillräckligt stort, kommer ditt lojalitetssystem att ha tre standardegenskaper:

  • Ditt system kommer att vara mycket belastat
  • Ditt system kommer att innehålla komplexa datorprocesser
  • Ditt system kommer att förbättras aktivt.

Låt oss gå i ordning... Totalt, om vi tar hänsyn till alla Sportmaster-märken, så har vi mer än 1000 butiker i Ryssland, Ukraina, Kina, Kazakstan och Vitryssland. Cirka 300 000 köp görs i dessa butiker varje dag. Det vill säga, varannan 3-4 kontroller kommer in i vårt system. Naturligtvis är vårt lojalitetssystem mycket laddat. Och eftersom det används aktivt måste vi tillhandahålla de högsta standarderna för dess kvalitet, eftersom alla fel i programvaran innebär stora monetära, anseende och andra förluster.

Samtidigt kör Sportmaster mer än hundra olika kampanjer. Det finns en mängd olika kampanjer: det finns produktkampanjer, det finns de som är dedikerade till veckodagen, det finns de som är knutna till en specifik butik, det finns kampanjer för mängden av kvittot, det finns för antalet varor. I allmänhet inte dåligt. Kunder har bonusar och kampanjkoder som används vid köp. Allt detta leder till det faktum att att beräkna vilken ordning som helst är en mycket icke-trivial uppgift.

Algoritmen som implementerar orderhantering är verkligen fruktansvärd och komplicerad. Och alla ändringar av denna algoritm är ganska riskabla. Det verkade som om de mest till synes obetydliga förändringarna kunde leda till ganska oförutsägbara effekter. Men det är just sådana komplexa datorprocesser, särskilt de som implementerar kritisk funktionalitet, som är de bästa kandidaterna för automatisering. Att kontrollera dussintals liknande fall för hand är mycket tidskrävande. Och eftersom ingången till processen är oförändrad, efter att ha beskrivit den en gång, kan du snabbt skapa automatiska tester och vara säker på att funktionaliteten kommer att fungera.

Eftersom vårt system används aktivt kommer verksamheten att vilja något nytt av dig, leva med tiden och vara kundorienterad. I vårt lojalitetssystem kommer utgåvor varannan månad. Det betyder att vi varannan månad behöver genomföra en fullständig regression av hela systemet. Samtidigt går naturligtvis inte utvecklingen direkt från utvecklare till produktion, som i all modern IT. Det har sitt ursprung i utvecklarens krets, passerar sedan successivt genom testbänken, släpper, accepteras och hamnar först sedan i produktion. Som ett minimum, på test- och frigöringskretsarna, måste vi utföra en fullständig regression av hela systemet.

De beskrivna egenskaperna är standard för nästan alla lojalitetssystem. Låt oss prata om funktionerna i vårt projekt.

Tekniskt sett är 90 % av logiken i vårt lojalitetssystem serverbaserad och implementerad på Oracle. Det finns en klient exponerad i Delphi, som utför funktionen som en automatiserad arbetsplatsadministratör. Det finns exponerade webbtjänster för externa applikationer (till exempel en webbplats). Därför är det väldigt logiskt att om vi distribuerar ett automatiserat testsystem kommer vi att göra det på Oracle.

Lojalitetssystemet i Sportmaster har funnits i mer än 7 år och skapades av enstaka utvecklare... Det genomsnittliga antalet utvecklare på vårt projekt under dessa 7 år var 3-4 personer. Men under det senaste året har vårt team vuxit avsevärt och nu är det 10 personer som arbetar med projektet. Det vill säga att människor kommer till projektet som inte är bekanta med typiska uppgifter, processer och arkitektur. Och det finns en ökad risk att vi missar misstag.

Projektet kännetecknas av frånvaron av dedikerade testare som stabsenheter. Det finns givetvis testning, men testning utförs av analytiker, utöver deras övriga huvudansvar: att kommunicera med företagskunder, användare, utveckla systemkrav osv. etc... Trots det faktum att testning utförs av mycket hög kvalitet (detta är särskilt lämpligt att nämna, eftersom några av analytikerna kan fånga ögat av denna rapport), har effektiviteten av specialisering och koncentration på en sak inte upphävts .

Med tanke på allt ovan, för att förbättra kvaliteten på den levererade produkten och minska utvecklingstiden, verkar idén att automatisera testning på ett projekt väldigt logisk. Och i olika skeden av lojalitetssystemets existens gjorde enskilda utvecklare ansträngningar för att täcka sin kod med enhetstester. Sammantaget var det en ganska osammanhängande process, där alla använde sin egen arkitektur och sina metoder. De slutliga resultaten var gemensamma för enhetstester: tester utvecklades, användes under en tid, lagrades i en versionerad fillagring, men vid något tillfälle slutade de att köras och glömdes bort. Först och främst berodde detta på att testerna var mer knutna till en specifik utförare, och inte till projektet.

utPLSQL kommer till undsättning

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Vet du något om Stephen Feuerstein?

Det här är en smart kille som ägnat en lång del av sin karriär åt att arbeta med Oracle och PL/SQL och har skrivit ett ganska stort antal verk om detta ämne. En av hans berömda böcker heter: "Oracle PL/SQL. För proffs." Det var Stephen som utvecklade utPLSQL-lösningen, eller, som det står för, Unit Testing framework för Oracle PL/SQL. UtPLSQL-lösningen skapades 2016, men det fortsätter att arbetas aktivt på och nya versioner släpps. Vid tidpunkten för rapporteringen går den senaste versionen tillbaka till den 24 mars 2019.
Vad är det. Detta är ett separat projekt med öppen källkod. Den väger ett par megabyte, inklusive exempel och dokumentation. Rent fysiskt är det ett separat schema i ORACLE-databasen med en uppsättning paket och tabeller för att organisera enhetstestning. Installationen tar några sekunder. En utmärkande egenskap hos utPLSQL är dess användarvänlighet.
Globalt sett är utPLSQL en mekanism för att köra enhetstester, där ett enhetstest förstås som vanliga Oracle-batchprocedurer, vars organisation följer vissa regler. Förutom lansering lagrar utPLSQL en logg över alla dina testkörningar, och har även ett internt rapporteringssystem.

Låt oss titta på ett exempel på hur enhetstestkoden ser ut, implementerad med denna teknik.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Så, skärmen visar koden för en typisk förpackningsspecifikation med enhetstester. Vilka är de obligatoriska kraven? Paketet måste ha prefixet "utp_". Alla procedurer med tester måste ha exakt samma prefix. Paketet måste innehålla två standardprocedurer: "utp_setup" och "utp_teardown". Den första proceduren anropas genom att starta om varje enhetstest, den andra - efter lanseringen.

"utp_setup", som regel, förbereder vårt system för att köra ett enhetstest, till exempel skapa testdata. "utp_teardown" - tvärtom, allt återgår till de ursprungliga inställningarna och återställer startresultaten.

Här är ett exempel på det enklaste enhetstestet som kontrollerar normaliseringen av det angivna kundtelefonnumret till standardformuläret för vårt lojalitetssystem. Det finns inga obligatoriska standarder för hur man skriver rutiner med enhetstester. Som regel görs ett anrop till en metod i systemet som testas, och resultatet som returneras av denna metod jämförs med referensen. Det är viktigt att jämförelsen av referensresultatet och det erhållna resultatet sker genom vanliga utPLSQL-metoder.

Ett enhetstest kan ha hur många kontroller som helst. Som framgår av exemplet ringer vi fyra på varandra följande samtal till den testade metoden för att normalisera telefonnumret och utvärdera resultatet efter varje samtal. När du utvecklar ett enhetstest måste du ta hänsyn till att det finns kontroller som inte påverkar systemet på något sätt, och efter några behöver du rulla tillbaka till systemets ursprungliga tillstånd.
Till exempel, i det presenterade enhetstestet formaterar vi helt enkelt det inmatade telefonnumret, vilket inte påverkar lojalitetssystemet på något sätt.

Och om vi skriver enhetstester med metoden att skapa en ny klient, kommer en ny klient att skapas i systemet efter varje test, vilket kan påverka den efterföljande lanseringen av testet.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Så här körs enhetstester. Det finns två möjliga startalternativ: köra alla enhetstester från ett specifikt paket eller köra ett specifikt enhetstest i ett specifikt paket.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

Så här ser ett exempel på ett internt rapporteringssystem ut. Baserat på resultaten från enhetstestet bygger utPLSQL en liten rapport. I den ser vi resultatet för varje specifik kontroll och det övergripande resultatet av enhetstestet.

6 regler för autotest

Innan vi började skapa ett nytt system för automatiserad testning av lojalitetssystemet bestämde vi tillsammans med ledningen vilka principer som våra framtida automatiserade tester ska följa.

Enhetstester i ett DBMS - hur vi gör i Sportmaster, del ett

  1. Autotester måste vara effektiva och måste vara användbara. Vi har underbara utvecklare, som definitivt behöver nämnas, för några av dem kommer förmodligen att se den här rapporten, och de skriver underbar kod. Men även deras underbara kod är inte perfekt och har, har och kommer att fortsätta att innehålla fel. Autotester krävs för att hitta dessa fel. Om så inte är fallet så skriver vi antingen dåliga autotester, eller så har vi kommit till ett dött område som i princip inte utvecklas. I båda fallen gör vi något fel, och vårt tillvägagångssätt är helt enkelt inte vettigt.
  2. Autotester bör användas. Det är ingen mening att lägga mycket tid och ansträngning på att skriva en mjukvaruprodukt, lägga den i ett förråd och glömma det. Tester bör köras och köras så regelbundet som möjligt.
  3. Autotester ska fungera stabilt. Oavsett tid på dygnet, startstativ och andra systeminställningar bör testkörningar leda till samma resultat. Detta säkerställs i regel genom att autotester arbetar med speciella testdata med fasta systeminställningar.
  4. Autotester bör fungera med en hastighet som är acceptabel för ditt projekt. Denna tid bestäms individuellt för varje system. Vissa människor har råd att arbeta hela dagen, medan andra tycker att det är viktigt att göra det på några sekunder. Jag kommer att berätta lite senare vilka hastighetsstandarder vi uppnådde i vårt projekt.
  5. Autotestutveckling bör vara flexibel. Det är inte tillrådligt att vägra testa någon funktion bara för att vi inte har gjort det tidigare eller av någon annan anledning. utPLSQL lägger inga restriktioner på utvecklingen, och Oracle låter dig i princip implementera en mängd olika saker. De flesta problem har en lösning, det är bara en fråga om tid och ansträngning.
  6. Utplacerbarhet. Vi har flera montrar där vi behöver köra tester. Vid varje monter kan en datadump uppdateras när som helst. Det är nödvändigt att genomföra ett projekt med automatiska tester på ett sådant sätt att du smärtfritt kan utföra hela eller delar av installationen.

Och i det andra inlägget om ett par dagar ska jag berätta vad vi gjorde och vilka resultat vi uppnådde.

Källa: will.com

Lägg en kommentar