T-76.115 Testiraportti TR-3 ETL-työkalu ExtraTerrestriaLs Versio Päivämäärä Tekijä Kuvaus 1.0 14.03.05 Risto Kunnas Ensimmäinen versio 1.1 15.03.05 Risto Kunnas Korjauksia Sivu 1 / 14
Sisällysluettelo 1Yhteenveto... 2 2Muutokset testaussuunnitelmaan... 2 3Testauksen kattavuus... 2 4Yhteenveto tuloksista...3 5Tulosten arviointi...3 Liite A Virheraportti Jirasta... 5 Liite B Testiprosessit... 6 Liite C Testausohje ryhmälle... 10 1 Yhteenveto Testausta suoritettiin testaussuunnitelman mukaisesti käyttäen hyväksi kuvauskielellä luotavia prosessikuvauksia ja testitauluja. Prosessikuvaukset ja testitaulut löytyvät ryhmän versionhallintajärjestelmästä. Testaus ajoittui iteraation loppupuolelle, joten Testaus suoritettiin WindowsNT ympäristössä MySQL kannassa. 2 Muutokset testaussuunnitelmaan Testauksen kattavuustavoitteesta on tingitty, koska ETL-työkalu on luonteeltaan selkeästi prototyyppimäinen. Pääpainon on tällaisessa projektissa oltava erilaisten ratkaisujen kokeilu, ei niinkään vikasietoisen järjestelmän rakentaminen. Erityisesti suunniteltujen ominaisuuksien (positiivinen) testaaminen on tärkeämpää kuin pikkuvirheiden metsästys. Testiprosesseihin oli tarkoitus erikseen lisätä testit eri tietokantayhdistelmille, mutta tämä olisi vaikeuttanut testien ylläpidettävyyttä. Eri tietokantayhdistelmät on mahdollista testata muuttamalla tietokantakonfiguraatiota. 3 Testauksen kattavuus Tässä iteraatiossa saavutettiin edellistä iteraatiota huomattavasti suurempi kattavuus. Testattavia toimenpiteitä olivat: Join ImportSQL ImportCSV Export Filter Pivot Aggregate Sivu 2 / 14
Append Copy Osassa toimenpiteitä keskityttiin käytännön syistä ainoastaan positiiviseen testaukseen. Testauksen kattavuutta rajoitti osittain puutteellinen dokumentaatio, sillä kaikkia ominaisuuksia ei ole täydellisesti dokumentoitu, jolloin testausta ei voi kovin järjestelmällisesti suorittaa. Testauksen yhteydessä jouduttiin joissain kohdin miettimään, että onko kyseessä ominaisuus vai bugi. Tästä voi päätellä, että kaikkia toteutettuja ominaisuuksia ei ollut testaajan tiedossa. Lisäksi kaikilla olemassa olevilla ominaisuuksilla on tehty ad-hoc testausta, joilla on lähinnä pyritty demoamaan ominaisuutta, ei niinkään löytämään mahdollisimman paljoa virheitä. 4 Yhteenveto avoimista virheistä Komponentti /(testi sarja) Blocker Critical Major Minor Trivial Yht. Filter 0 0 0 0 0 0 ImportSQL 0 0 0 1 0 1 Export 0 0 0 0 0 0 Join 0 0 0 0 0 0 Pivot 0 0 0 0 0 0 ImportCSV 0 0 0 0 0 0 Copy 0 0 0 0 0 0 Append 0 0 1 0 0 1 Aggregate 0 0 0 0 1 1 Delete 0 0 0 0 0 0 Muut 0 1* 0 0 0 1 Yhteensä 0 1* 1 1 1 4 Luvut sisältävät myös edellisissä iteraatioissa avoimiksi jääneet virheet. *Vaikka satunnaisesti esiintyvä virhe (Jiran tunnus ETL-153) on vakavuudeltaan kriittinen, sen korjaamista ei pidetä kiireellisenä. Virheen paikallistamista on yritetty, mutta siinä ei ole onnistuttu. 5 Tulosten arviointi Filter Komponentti Kuvaus Kattavuus /Fail Toimii määritelmän mukaisesti osana prosessia Hyvä Sivu 3 / 14
Komponentti Kuvaus Kattavuus /Fail ImportSQL Export Join Pivot Toimii määritelmän mukaisesti osana prosessia, osa erikoistilanteista aiheuttaa prosessin keskeytymisen Toimii määritelmän mukaisesti osana prosessia, osa erikoistilanteista aiheuttaa prosessin keskeytymisen Toimii määritelmän mukaisesti osana prosessia, osa erikoistilanteista aiheuttaa poikkeuksen, jota ei ole määritelty tarkemmin Toimii määritelmän mukaisesti osana prosessia Hyvä Hyvä Hyvä Hyvä ImporCSV Toimii rajoitetusti Välttävä - Copy Append Aggregate Toimii määritelmän mukaisesti osana prosessia Toimii rajoitetusti, duplikaatit aiheuttavat poikkeuksen Toimii määritelmän mukaisesti osana prosessia, osa erikoistilanteista aiheuttaa poikkeuksen Kattavuus on arvioitu asteikolla Hyvä, Tyydyttävä ja Välttävä. Erinomainen Hyvä Hyvä Sivu 4 / 14
Liite A Virheraportti Jirasta Avain on viite Jiran tarkempaan virhekuvaukseen Sivu 5 / 14
Liite B Testiprosessi Testiprosessista on kommentoitu ulos ne kohdat, jotka pysäyttävät prosessin. Nämä eivät välttämättä ole virheitä. <?xml version="1.0" encoding="utf-8"?> <etl xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="d:/temp/source/com/aureolis/etltool/test/skema.x sd"> Test case collection for ETL-tool <etlprocess name="myynnit1" workingdatabaseid="tyokanta"> <operations> Test cases for operation ImportCSV <importcsv name="tuotteet" url="http://www.hut.fi/u/tnousia/monimutkainen.csv" separator=","> <destinationtableformat name="tuotteet"> <column name="tkoodi" type="int" iskey="true"/> <column name="kuvaus" type="varchar(128)" /> <column name="hinta" type="decimal (5,2)" /> </destinationtableformat> <destinationtableindices> <index name="test"> <column name="kuvaus" order="asc"/> <column name="tkoodi" order="asc"/> </index> </destinationtableindices> </importcsv> Test cases for operation Join <importsql name="osasto" sourcetable="osasto" <importsql name="tyossa" sourcetable="tyossa" <importsql name="tyhja2" sourcetable="tyhjataulu" sourcedatabaseid="tyokanta"/> source1="osasto"/> <join name="osastoittain1" type="left"> <table source="tyossa"></table> <table source="osasto"></table> <equals source2="tyossa" column2="ot" column1="nimi" </join> Sivu 6 / 14
source1="osasto"/> source2="osasto"/> source1="osasto"/> source1="osasto"/> <join name="osastoittain2" type="right"> <table source="tyossa"></table> <table source="osasto"></table> <equals source2="tyossa" column2="ot" column1="ot" </join> <join name="osastoittain3" type="left"> <table source="osasto"></table> <table source="tyossa"></table> <equals source1="tyossa" column1="ot" column2="ot" </join> <join name="samat" type="right" errortable="error2"> <table source="tyossa"></table> <table source="osasto"></table> <equals source2="tyossa" column2="ot" column1="nimi" </join> <join name="samatleft" type="left" errortable="error3"> <table source="tyossa"></table> <table source="osasto"></table> <equals source2="tyossa" column2="ot" column1="nimi" </join> <export source ="samat" destinationdatabaseid="tietovarasto" destinationtable="joinresult1"/> <export source ="error2" destinationdatabaseid="tietovarasto" destinationtable="joinerrorresult1"/> <export source ="samatleft" destinationdatabaseid="tietovarasto" destinationtable="joinresult2"/> <export source ="error3" destinationdatabaseid="tietovarasto" destinationtable="joinerrorresult2"/> <export source ="osastoittain1" destinationdatabaseid="tietovarasto" destinationtable="joinresult3"/> <export source ="osastoittain2" destinationdatabaseid="tietovarasto" destinationtable="joinresult4"/> <export source ="osastoittain3" destinationdatabaseid="tietovarasto" destinationtable="joinresult5"/> Test cases for operations Import and Export <importsql name="osasto7" sourcetable="osasto" <export source="osasto7" destinationdatabaseid="tietovarasto" destinationtable="exporttest1"/> <export source="osasto7" destinationdatabaseid="tietovarasto" destinationtable="exporttest1"/> Sivu 7 / 14
<importsql name="osasto9" sourcetable="helvetiniso2" sourcedatabaseid="tyokanta"/> <export source="osasto9" destinationdatabaseid="tietovarasto" destinationtable="exporttest2"/> NOT SUCCESFUL <importsql name="osasto8" sourcetable="invalidosasto" <export source="osasto8" destinationdatabaseid="tietovarasto" destinationtable="exporttest3"/> NOT SUCCESFUL <importsql name="osasto10" sourcetable="invalidosasto" sourcedatabaseid="tyokanta"/> <export source="osasto10" destinationdatabaseid="tietovarasto" destinationtable="exporttest4"/> Test cases for operation Copy <importsql name="osasto2" sourcetable="osasto" <copy/> destinationtable="copytest1"/> <copy name="copytest2" source="osasto2"/> <export source="copytest2" destinationdatabaseid="tietovarasto" destinationtable="copytest2"/> NOT SUCCESFUL <copy name="copytest3" source="invalidosasto"/> <export source="copytest2" destinationdatabaseid="tietovarasto" destinationtable="copytest3"/> Test cases for operation Filter <importsql sourcetable="helvetiniso" destinationtable="filtertest"/> <importsql sourcetable="helvetiniso" <filter where="id > 5015"></filter> destinationtable="filtertest1"/> <importsql name="testi1" sourcetable="helvetiniso" <filter source="testi1" where="id > 1015"></filter> destinationtable="filtertest2"/> Sivu 8 / 14
<importsql sourcetable="helvetiniso" <filter name="testi2" where="id > 1015"></filter> <export source="testi2" destinationdatabaseid="tietovarasto" destinationtable="filtertest3"/> <importsql sourcetable="helvetiniso" <filter where="id > 5015"></filter> <filter where="id > 1015"></filter> destinationtable="filtertest4"/> NOT SUCCESFUL <importsql sourcetable="helvetiniso" <filter where="id > 1015"></filter> <filter where="tyhja > 5015"></filter> <filter where="id > 1015"></filter> destinationtable="filtertest5"/> Test cases for operation Pivot <importsql name="importti" sourcetable="pivotorginal" <pivot name="pivot1" locatorcolumn="month" locatorcolumntype="char (3)" valuecolumn="monthly_sales" valuecolumntype="double"> <transform locator="jan" expression="m1" /> </pivot> <transform locator="feb" expression="m2" /> <transform locator="mar" expression="m3" /> <transform locator="apr" expression="m4" /> <export source ="pivot1" destinationdatabaseid="tietovarasto" destinationtable="pivotresult1"/> <pivot source="importti" locatorcolumn="month" locatorcolumntype="char (3)" valuecolumn="monthly_sales" valuecolumntype="double"> <transform locator="jan" expression="m1" /> </pivot> destinationtable="pivotresult2"/> NOT SUCCESFUL <pivot source="importti" locatorcolumn="month" locatorcolumntype="char (3)" valuecolumn="monthly_sales" valuecolumntype="double"> <transform locator="inv" expression="invalid" /> Sivu 9 / 14
</pivot> destinationtable="pivotresult3"/> NOT SUCCESFUL <pivot source="importti" locatorcolumn="month" locatorcolumntype="char (3)" valuecolumn="monthly_sales" valuecolumntype="double"> <transform locator="too BIG" expression="m1" /> </pivot> destinationtable="pivotresult4"/> Test cases for operation Aggregate <importsql name="tyontekija" sourcetable="tyontekija" <aggregate name="aggregatetest1" groupby="etunimi"> <column name="etunimi" expression="etunimi"/> <column name="palkka" expression="sum(palkka)"/> destinationtable="aggregateresult1"/> groupby="etunimi"> NOT SUCCESSFUL <aggregate name="aggregatetest2" source="tyontekija" <column name="etunimi" expression="etunimi"/> <column name="palkka" expression="invalid EXPRESSION"/> <export source ="aggregatetest2" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult2"/> <aggregate name="aggregatetest3" source="tyontekija" groupby="etunimi"> <column name="etunimi" expression="etunimi"/> <column name="palkka" expression="count(*)"/> <export source ="aggregatetest3" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult3"/> NOT SUCCESSFUL, ACCORDING TO THE PEER GROUP THE FUNCIONALITY SHOULD BE LIKE THIS <aggregate name="aggregatetest4" source="tyontekija"> <column name="etunimi" expression="etunimi"/> <column name="palkka" expression="count(*)"/> <export source ="aggregatetest4" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult4"/> <aggregate name="aggregatetest5" source="tyontekija" Sivu 10 / 14
groupby="etunimi" having="sum(palkka)>2000"> <column name="etunimi" expression="etunimi" /> <column name="palkka" expression="sum(palkka)"/> <export source ="aggregatetest5" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult5"/> <aggregate name="aggregatetest6" source="tyontekija" groupby="etunimi" having="sum(palkka)>2000"> <column name="etunimi" expression="etunimi" /> <column name="palkka" expression="palkka"/> <column name="kokonaispalkka" expression="sum (palkka)"/> <export source ="aggregatetest6" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult6"/> NOT SUCCESFUL (Stops the process) <aggregate name="aggregatetest7" source="tyontekija" groupby="etunimi" having="sum(palkka)>2000"> <column name="etunimi" expression="invalidetunimi" /> <column name="palkka" expression="palkka"/> <column name="kokonaispalkka" expression="sum (palkka)"/> <export source ="aggregatetest7" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult7"/> NOT SUCCESFUL (No column names are automatically created) <aggregate name="aggregatetest8" source="tyontekija" groupby="etunimi" having="sum(palkka)>2000"> <column expression="etunimi" /> <column name="palkka" expression="palkka"/> <column name="kokonaispalkka" expression="sum (palkka)"/> <export source ="aggregatetest8" destinationdatabaseid="tietovarasto" destinationtable="aggregateresult8"/> Test cases for operation Append <importsql name="append1" sourcetable="tyontekija" <filter name="f1" where="palkka > 2200"></filter> <importsql name="append2" sourcetable="tyontekija" <filter name="f2" where="palkka > 2800"></filter> <append name="appendtest1" destinationtable ="f1"/> <export source="appendtest1" destinationdatabaseid="tietovarasto" destinationtable="appendresult1"/> NOT SUCCESFUL <filter name="f12" where="palkka > 2200" Sivu 11 / 14
source="append1"></filter> <filter name="f22" where="palkka > 1000" source="append2"></filter> <append name="appendtest2" destinationtable ="f12"/> <export source="appendtest2" destinationdatabaseid="tietovarasto" destinationtable="appendresult2"/> <importsql name="tyhja" sourcetable="tyhjataulu" <append name="appendtest2" destinationtable ="tyhja"/> <export source="appendtest2" destinationdatabaseid="tietovarasto" destinationtable="appendresult2"/> </operations> </etlprocess> </etl> Sivu 12 / 14
Liite C Testausohje ryhmälle Hakemistohierarkia Testaukseen käytettävä materiaali sijaitsee hakemiston com/aureolis/etltool/test alla. Tässä hakemistossa sijaitsee xml-skeema skema storm.xsd, johon viitataan kaikista prosessikuvaustiedostoista relatiivisesti (eli tyyliin../skema storm.xsd ). testhakemistoon tulevat vain testeille yhteiset tiedostot. Yksittäisen testin (tai testiryppään) tiedostot tulevat omaan alihakemistoonsa (kuten test/join). Toimenpiteiden testaus Testattaessa yksittäisiä toimenpiteitä, suoritetaan testaus järjestelmätestauksena, koska toimenpiteiden toiminan oikeellisuuden arvioimiseen, on niiden toimintaa seurattava koko järjestelmän yhteydessä. Toisaalta järjestelmätestaus on helppo tapa testata toimenpiteitä monipuolisesti. Hakemistorakenne Jokaiselle toimenpiteelle luodaan testausta varten oma alihakemisto, kuten test/join. Hakemisto sisältää esim. seuraavat tiedostot: configuration.xml Paikalinen, ei versionhallinnassa join1.xml Prosessikuvaus logging.properties Paikallinen, ei versionhallinnassa project.xml Projektikuvaus, jossa viittaukset prosessikuvaukseen ja konfiguraatioon setup1.sql Testausympäristön pysytykseen käytettävä tiedosto Xml-tiedostoissa olevat viittaukset skeemaan ovat../skema storm.xsd. Konfiguraatio Koska jokaisessa kehitystyöasemalla tietokannat poikkeavat hieman toisistaan, täytyy konfiguraatiotiedostojen olla paikallisia. Tämän vuoksi tietokannoissa käytetään nimeämisstandardia, jossa käytettäviä tietokantoja on kolme erillistä: lahdekanta Lähdekanta, josta taulut haetaan importilla työkantaan tyokanta Työkanta, jossa tiedon jalostus tapahtuu tietovarasto Tietovarasto, jonne ETL-prosessin tulokset talletetaan Tyypillinen konfiguraatio tiedosto on tyyliä: <?xml version="1.0" encoding="utf-8"?> <etl xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nonamespaceschemalocation="../skema strom.xsd"> <configuration> <database id="tyokanta"> <url>jdbc:mysql://circkeli.nnet/test2</url> Sivu 13 / 14
<type>mysql</type> <username>etl</username> <password>kekkula</password> </database> <database id="lahdekanta"> <url>jdbc:mysql://circkeli.nnet/test</url> <type>mysql</type> <username>etl</username> <password>kekkula</password> </database> <database id="tietovarasto"> <url>jdbc:mysql://circkeli.nnet/test3</url> <type>mysql</type> <username>etl</username> <password>kekkula</password> </database> </configuration> </etl> Testausympäristön pystytys Testauksen automatisoimiseksi jokaista testiä varten luodaan testausympäristön setupskripti, jossa määritellään kantaan luotavat taulut ja niihin sisällytettävä testidata. Setupskriptissä määritellään myös kannan nimi, johon taulut ja data luodaan. Yhdellä skriptillä voidaan alustaa useita tietokantoja. Skirptin alussa on rivi :kannannimi, joka kertoo missä kannassa seuraavat SQL-lauseet suoritetaan. Kukin SQL-lause on oltava omalla rivillään, ts. esim. CREATE TABLE-lausetta ei saa jakaa useammalle riville. Esimerkki: :lahdekanta CREATE TABLE Tyontekija (sotu CHAR(11), sukunimi VARCHAR(15), etunimi VARCHAR (10), palkka INTEGER, PRIMARY KEY (sotu)); CREATE TABLE Osasto (ot INTEGER, nimi VARCHAR(20), PRIMARY KEY (ot)); CREATE TABLE Tyossa (ot INTEGER, sotu CHAR(11), PRIMARY KEY (ot, sotu)); INSERT INTO Tyontekija VALUES ('301162-132G', 'Silakka', 'Seppo', 2630); INSERT INTO Tyontekija VALUES ('210380-321R', 'Kankkunen', 'Kalle', 1800); INSERT INTO Tyontekija VALUES ('240685-1234', 'Kesà mies', 'Keijo', 2370); INSERT INTO Tyontekija VALUES ('251083-1234', 'Vilkas', 'Ville', 2030); INSERT INTO Osasto VALUES (1, 'Hallinto'); INSERT INTO Osasto VALUES (2, 'Tuotanto'); INSERT INTO Osasto VALUES (3, 'Myynti'); INSERT INTO Osasto VALUES (4, 'Markkinointi'); INSERT INTO Osasto VALUES (5, 'Foobar'); INSERT INTO Tyossa VALUES (1, '301162-132G'); INSERT INTO Tyossa VALUES (1, '240685-1234'); INSERT INTO Tyossa VALUES (2, '210380-321R'); INSERT INTO Tyossa VALUES (3, '251083-1234'); INSERT INTO Tyossa VALUES (2, '251083-1234'); INSERT INTO Tyossa VALUES (8, '123456-1234'); Sivu 14 / 14