20 nov 2012 Inrichten van een Oracle database Deel 3: Genereren van testgegevens Nieuws Het installeren, inrichten en configureren van een Oracle database is een lastige klus. In een serie van drie artikelen laten we zien hoe deze inrichting op een gestructureerde manier vorm kan worden gegeven. In het derde en laatste deel aandacht voor het genereren van testgegevens. In de voorgaande twee delen is beschreven hoe we een database kunnen inrichten voor een ontwikkel-, testof productieomgeving. Voor enkele tabellen is hierbij al een vulling meegekomen. Voor een productieomgeving zal hierna vaak een conversie volgen van de bestaande omgeving of er wordt met een lege situatie begonnen en (voor ons voorbeeld) de artikelen en de eerste klanten en orders worden ingebracht. Voor de ontwikkelomgeving en de testomgeving moeten er nog testgegevens komen. Je kunt hierbij kiezen voor een kopie van een deel van de productiegegevens, maar dat heeft enkele nadelen: Bij een nieuw systeem of bij een pakketleverancier zijn er geen productiegegevens; Vaak staan er privacy gevoelige gegevens in de productieomgeving die men niet naar de testomgeving wil kopiëren. Het anonimiseren van de gegevens is dan soms mogelijk maar er blijven andere nadelen; Productiegegevens bevatten heel vaak de regel en weinig uitzonderingen. Voor die uitzonderingen, die nodig zijn om specifieke takken van de programmatuur te testen moeten toch weer extra testgegevens worden geschreven; Het narekenen van bijvoorbeeld facturen vanuit een kopie van de productiegegevens is veel meer werk dan het narekenen van een factuur vanuit specifiek geschreven of gegenereerde testgegevens. Hieronder volgt een methode om bulk testgegevens te genereren. Ook hierbij zullen zeker niet alle uitzonderingen aanwezig zijn, waarop de programmatuur moet worden getest. Maar het is dan gemakkelijk, mede omdat de range sleutelvelden bekend is, om extra testgegevens toe te voegen voor specifieke programma’s. Het voordeel van deze methode is dat er snel een flinke hoeveelheid gegevens in de database staat waarmee de hoofdlijnen van de programmatuur kunnen worden getest. Ook kan hiermee een grote hoeveelheid data worden gegenereerd, zodat performancetesten kunnen worden uitgevoerd met een database op productiegrootte. Uitgangspunten hierbij zijn de volgende testsoorten: Unittest: Een test van een programma of deel van een programma door de programmeur zelf. Dit is een white box test: De programmeur kent zijn programma, weet welke statements en vooral welke condities er in zitten. Hij kan dus een test uitvoeren waarbij alle statements tenminste één keer zijn uitgevoerd en, beter nog, alle condities eenmaal waar en eenmaal onwaar zijn geweest; Systeemtest: Dit is een test, uitgevoerd door een tester met twee doelen: Heeft de programmeur het ontwerp goed begrepen, is dit volledig geïmplementeerd? En werken alle interfaces tussen de onderdelen goed. De units (programma’s) die door de programmeur zijn opgeleverd worden als een black box beschouwd: onbekend hoe die gebouwd zijn maar wel technisch volledig getest door de programmeur. Het systeem als geheel is nog een white box, dus de interfaces tussen de delen zijn wel bekend en moeten allen en volledig getest worden; Performancetest: Een test waarbij het gaat of het systeem grote hoeveelheden kan verwerken. Variatie in de gegevens is minder belangrijk, in productie zal ook de hoofdlijn van de programma’s het meest gevolgd worden. De test kan een rapport betreffen waarbij veel gegevens uit de database gelezen moeten worden, maar ook een eventueel kleine database die heel veel transacties in een korte tijd moet verwerken; Acceptatietest: Door de gebruikersorganisatie. Het hele syteem is nu een black box. Voldoet het systeem aan de specificaties maar ook aan de verwachtingen van de gebruiker. Dit kan ook met geschreven of gedeeltelijk gegenereerde gegevens maar hier zal vaak een deel van de productiegegevens gebruikt worden om een zo realistisch mogelijke omgeving te creëren en omdat onvoorziene situaties in de bestaande productiegegevens dan ook aan het licht komen. Van de acceptatietest kunnen nog enkele varianten worden genoemd: Acceptatie door de eindgebruiker: Voldoet het systeem en kan ik hiermee uit de voeten? Acceptatie door de beheerorganisatie: Kunnen we dit systeem wel in beheer nemen? Acceptatie door de accountantsdienst: Voldoet het systeem aan onze normen? Zo niet dan is er waarschijnlijk wat mis gegaan in de beginfase van het project, maar toch … Acceptatie door security, etc. De hoeveelheid te genereren data is afhankelijk van het doel. Voor een unittest / programmatest is slechts een kleine hoeveelheid data nodig, bijvoorbeeld 10 klanten, 10 artikelen, etc. De variatie moet voldoende zijn om een groot deel van de coding van het programma te dekken. Extra testgevallen voor specifieke takken in het programma worden door de programmeur toegevoegd. Het zelfde geld voor de systeemtest en de acceptatietest als deze laatste met gegenereerde data wordt uitgevoerd. Voor de performancetest moet een grote hoeveelheid data worden gegenereerd, mogelijk zelfs een hoeveelheid die vergelijkbaar is met de productieomvang van het systeem. Hulptabel De basis van de procedure is een tabelletje met 10 records en met 3 kolommen: Een volgnummer (id) met de numerieke waarde 0 t/m 9; Een code met de tekens ‘0’ t/m ‘9’; Een naam met de strings ‘AAAA’ t/m ‘JJJJ’. Hieronder staat de code voor deze hulptabel (tabel ‘testvulling’) en een hierop gebaseerde view die 1000 records bevat met volgnummers (0 t/m 999), numerieke codes (‘000’ t/m ‘999’), namen (bijvoorbeeld AAAABBBBCCCC bij code 123), een datum, random getallen en nog een random samengestelde string van 6 posities. Deze view wordt gemaakt door van de oorspronkelijke tabel een drievoudig cartesisch product te nemen (zie kader). Maar op dezelfde manier kan, al naar gelang de behoefte, ook een view met 10, 100 of zelfs met 100.000 records gemaakt worden. De view in de coding voorbeelden is wat uitgebreider dan de view in het kader. De view bevat een datum ‘vandaag’ die gelijk is aan de systeemdatum zonder tijd. Het kan zinvol zijn om hier een vaste datum te kiezen om herhaalbaar testen te vergemakkelijken. Hulptabel testvulling create table testvulling ( id number(10) , code varchar2(20 byte) , naam varchar2(20 byte)) ; insert into testvulling values (0, '0', 'AAAA'); insert into testvulling values (1, '1', 'BBBB'); insert into testvulling values (2, '2', 'CCCC'); insert into testvulling values (3, '3', 'DDDD'); insert into testvulling values (4, '4', 'EEEE'); insert into testvulling values (5, '5', 'FFFF'); insert into testvulling values (6, '6', 'GGGG'); insert into testvulling values (7, '7', 'HHHH'); insert into testvulling values (8, '8', 'IIII'); insert into testvulling values (9, '9', 'JJJJ'); commit; exec DBMS_RANDOM.INITIALIZE (12345); create view testvulling_V3 as select 100*t1.ID + 10*t2.ID + t3.ID as id , t1.code || t2.code || t3.code as code -idem als string , t1.naam || t2.naam || t3.naam as naam -AAAAAA BBCCDD JJJJ , mod(id,2) as boolean –waarde is 0 of 1 , trunc(sysdate) as vandaag –datum zonder tijd , mod(dbms_random.random, 100000000) as random8 –integer 8 pos , mod(dbms_random.random, 10000) as random4 –integer 4 pos FROM testvulling t1 , testvulling t2 , testvulling t3; Overzicht van de generator De werkwijze voor het genereren van de testgegevens voor een gegevensmodel als in ons voorbeeld is als volgt: Er wordt een aantal records (bijvoorbeeld 10 records voor de unittest of 1000 voor een performancetest) gegenereerd voor de tabel KLANT. Vervolgens: Voor de klanten met bijvoorbeeld een oneven nummer wordt een record in de tabel zakelijke klant geschreven; voor de andere klanten een record in de tabel particuliere klant; Voor elke klant worden 2 telefoonnummers aangemaakt; Voor de zakelijke klanten worden telkens 1, 2 of 3 contactpersonen gegenereerd; We gaan ervan uit dat de BTW gegevens al bij de installatie zijn gevuld met de BTW code 0, 1 en 2 (nul, laag en hoog tarief) inclusief een percentage; Ook de tabel met systeemconstanten is al gevuld; Net als voor de klanten worden er 10 of 1000 artikelen gegenereerd; Bij elke klant kunnen er 2 orders worden gegenereerd met voor elke order 3 orderregels. Hierbij moet voor het artikelnummer een geldige waarde gebruikt worden. Zie de voorbeeldcode voor de uitwerking. Deze kan hier en daar afwijken van deze beschrijving. De vulling van de artikeltabel Het INSERT statement om de tabel ARTIKEL te vullen met 1000 rijen zou er nu als volgt uit kunnen zien: Hierna brengen we de klanten en orders in. Bij de klanten moeten we nog de telefoon-nummers en subtypes (particuliere of zakelijke klant) vastleggen. Hiervoor hebben we twee mogelijkheden: Een soortgelijk insert statement voor elke tabel, waarbij wordt gelet op de referentiële integriteit; Een PL/SQL procedure of package waarin de betreffende structuur wordt uitgegenereerd. Via een cursor op de view testvulling_V3 wordt telkens een klant met alle bijbehorende gegevens gemaakt waarna met de volgende klant wordt begonnen. Van het eerste alternatief is de performance veel beter, maar van het tweede is de flexibiliteit groter. Van het eerste alternatief is voor alle tabellen een voorbeeld uitgewerkt en beschikbaar in de ZIP file die van de website van Optimize (http://optimize.nl/Het-Blad/Optimize/Extra) kan worden gedownload. Dit voorbeeld kan naar believen met meer variaties worden uitgebreid om een zo breed mogelijke dekking voor de te testen programmatuur te bieden. Maar overdrijf dit niet! Heel specifieke situaties die voor een enkel programma bij de unittest nodig zijn kunnen beter door de programmeur aan de database worden toegevoegd. Samenvattend In dit deel hebben we beschreven hoe de tabellen van een systeem of schema kunnen worden gevuld met een willekeurige hoeveelheid testgegevens en met een grote variatie in de gegevens om ook een groot deel van de programmatuur te kunnen testen. Voor individuele programma’s kan de programmeur extra testgegevens toevoegen. Zoals in het begin is aangegeven heeft het gebruik van testgegevens in de unittest en systeemtest veel voordelen boven het gebruik van een kopie van de productiegegevens. -Toon Loonen Toon Loonen is werkzaam bij Capgemini en gespecialiseerd in (logisch en fysiek) gegevensmodellering. Hij is bereikbaar via e-mail: toon.loonen@capgemini.com of toon.loonen@inter.nl.net. Gerelateerde artikelen Vijfhart: kennispartner in de Digitale Transformatie Java voor testers (met Startgarantie) Help je loopbaan vooruit als MCSA Windows Server 2016