Testaussuunnitelma Populous Helsinki 10.11.2004 Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos
Kurssi 581260 Ohjelmistotuotantoprojekti ( ov) Projektiryhmä Heli Borg Markus Heinonen Ville Luolajan-Mikkola Olli Orajärvi Asiakas Petteri Hintsanen Johtoryhmä Juha Taina Turjo Tuohiniemi Kotisivu http://www.cs.helsinki.fi/group/populous Versiohistoria Versio Päiväys Tehdyt muutokset 0.1 18.10.2004 Ensimmäinen versio 1.0 10.11.2004 Hyväksytty versio
Sisältö i 1 Johdanto 1 1.1 Dokumentin rakenne............................ 1 1.2 Terminologia................................ 1 2 Testausstrategia 2 2.1 Testiraportti................................. 3 3 Testauksen vaiheet 3 3.1 Yksikkötestaus............................... 3 3.2 Integrointitestaus.............................. 4 3.3 Järjestelmätestaus.............................. 5 4 Toteuttamatta ja testaamatta jäävä toiminta 5 5 Testausympäristö 5 6 Järjestelmätestauksen testitapaukset 5 6.1 Järjestelmää käyttävän tutkijan käyttötapaukset.............. 6 6.2 Järjestelmän ylläpitäjän käyttötapaukset.................. 7
1 Johdanto 1 Tässä dokumentissa esitetään Populous -ohjelmistotuotantoprojektin testaussuunnitelma. Populous on syksyn 2004 aikana Helsingin yliopiston Tietojenkäsittelytieteen laitoksella Ohjelmistotuotantoprojekti -kurssin puitteissa toteutettava projekti. Projektissa tuotetaan populaation kehityksen simulointiin käytettävän ohjelmiston osa. Testauksen tavoitteena on taata ohjelmiston virheettömyys ja ohjelmistolle esitettyjen vaatimusten toteutuminen. Kaikkien ohjelmiston tarjoamien palvelujen pitää toimia suunnitellusti eikä ohjelmistosta saa puuttua mitään määrittelydokumentissa esitettyä korkeimman, prioriteetin 1 toimintoa. Testauksen yhteydessä ei yleensä löydetä kaikkia ohjelmiston virheitä, mutta tarkoituksena on, että ohjelmiston keskeiset toiminnot olisi mahdollista suorittaa virheettömästi. Siksi testaus keskittyy erityisesti ohjelmiston yleisimmin käytettäviin osiin. 1.1 Dokumentin rakenne Luvussa kaksi kuvataan testaussuunnitelmaa yleisesti ja testauksen raportointi. Luku kolme käsittää tarkemman kuvauksen testauksen osavaiheista: yksikkö-, integrointi ja järjestelmätestauksesta. Luvussa neljä esitetään ne osa-alueet, joihin ei projektiin varatun rajallisen ajan vuoksi ole mahdollista paneutua tämän projektin puitteissa. Viidennessä luvussa määritellään ympäristöt, joissa järjestelmän toimivuutta testataan. Kuudes luku sisältää listan järjestelmätestauksessa suoritettavista testeistä. 1.2 Terminologia Dokumentissa käytetyt termit ja lyhenteet: Alipopulaatio: Populaatio voi jakautua useisiin populaatioisolaatteihin. Alipopulaatioiden välillä pariutumistodennäköisyys on pienempi kuin alipopulaation sisällä. Markkeri: Kromosomissa paikka, jossa esiintyy yksilöiden välistä vaihtelua. Ncurses: Yleisesti käytössä oleva kirjasto tekstitilaisen terminaali-ikkunan sisällön ja toimintojen määrittelyyn. Tässä projektissa NCURSES:lla on tarkoitus toteuttaa yksinkertainen ikkunamainen käyttöliittymä, jolla voidaan suorittaa rinnakkaista ajoa lukuunottamatta samat käyttötapaukset kuin Javalla toteutettava käyttöliittymä. Perustajajäsen: Populaation ensimmäisen sukupolven edustaja, jonka perimästä simulaatio lähtee liikkeelle. Populaatio: Joukko saman lajin yksilöitä, jotka elävät samalla alueella. Populaatioisolaatti: Eristäytynyt populaatio, jossa ei geenivaihtoa ulkopuolelta. Rekombinaatio: Tekijäinvaihtojen määrästä riippuva jälkeläisen geeniperimä.
Siirtolainen: Muualta populaatioon tuleva yksilö, jonka geeniperimä poikkeaa ko. populaatioisolaatin perimästä. SNP -mutaatio: Lajin sisäinen, nukleotidisekvenssin tietyssä kohdassa esiintyvä vaihtelu. Muutokset tapahtuvat ainoastaan yhdessä emäsparissa.(engl. SNP = Single Nucleotide Polymorphism). STR-markkerit: Lyhyellä peräkkäisellä kromosomijaksolla toistuvat markkerit. Vaihtelu muodostuu jakson toistojen lukumäärästä. (engl. STR = Short Tandem Repeat). Tekijäinvaihto: Kromosomien risteäminen jakautumisen yhteydessä. (engl. cross-over). TERM: Kts. UNIX -signaalit. UNIX-signaalit: Prosessien väliseen kommunikaatioon käytetty menetelmä, jolla prosessille voidaan antaa signaali. Signaalin tyyppejä ovat mm. INT, TERM ja HUP, joihin reagoiminen voidaan ohjelmassa säätää halutunlaiseksi. 2 2 Testausstrategia Tässä luvussa kuvataan Populous -projektin testausstrategia. Testaus jaetaan yleisesti kolmeen vaiheeseen: yksikkötestaukseen, integraatiotestaukseen ja järjestelmätestaukseen. Yksikkötestauksessa testataan yksittäisten luokkien toimintaa erillään muista luokista, ja integraatiotestauksessa yksikkötestattujen luokkien yhteistoimintaa. Järjestelmätestauksessa testattavana on koko ohjelmisto. Järjestelmätestauksessa tuotettua ohjelmistoa testataan testiaineistolla ja testauksen suorittaa projektiryhmä itse. Ohjelman komponenttikaavio aiheuttaa poikkeamia normaalista testaushierarkiasta. Integraatiotestaus jätetään tietoisesti käytännössä tekemättä, sillä yksikkötestaukseen kuuluu yksittäisten komponenttien testaaminen ja toisaalta järjestelmätestauksessa käydään läpi käyttötapaukset, jotka huomioivat jokaisen ohjelman suorituspolun. Näin ohjelman eri osien välisen yhteistoiminnan testaus lankeaa lähes kokonaan järjestelmätestauksen alle. Poikkeuksen tähän tekee integraatiotestauksen alle sijoitettava asiakas-palvelin yhteistoiminta. Testaamiseen käytetään Java-puolella JUnit-kirjastoa ja sen tarjoamia palveluita. C++koodi testataan JUnitin C++-versiolla, CppUnitilla. Molempien käyttö on samanlaista. Käyttö on selitetty kohdassa yksikkötestaus. Testaaminen ei vaikuta ohjelmakoodiin; testimetodit rakennetaan erillisiin ohjelmakomponenteista itsenäisiin yksiköihin. Testimetodit sijoitetaan ohjelman debug-käännöksessä muun koodin kanssa samaan paikkaan. Lopullisessa ohjelmassa (release) testiluokat on poistettu koodin seasta. Testauksen tuloksista raportoidaan testausdokumentissa. Yksittäisistä testeistä kerrotaan testaajan nimi, suorituspäivämäärä, testattava asia, kuvaus testistä, odotettu tulos sekä loppupäätelmä. Testauksessa löydetyt virheet pyritään korjaamaan mahdollisuuksien mukaan. Mikäli jokin vika havaitaan vasta testauksen loppuvaiheessa ja sen korjaaminen olisi
mahdotonta käytettävissä olevan ajan puitteissa, virhe jätetään korjaamatta ja dokumentoidaan. Kukin projektin jäsen testaa ja toteuttaa oman komponenttinsa, joten testaamalla löydetyt virheet voidaan korjata välittömästi. Koko ohjelmaa koskevia ja erityisen haastavia virheitä ja puutteita varten on bugit-niminen tekstitiedosto, jonne em. seikkoja voidaan listata. 3 2.1 Testiraportti Testauksen tuloksista raportoidaan määritellyn formaatin mukaisesti testausraportissa. Samaa formaattia käytetään sekä yksikkötestauksessa metodien tai luokkien testauksen raportointiin sekä järjestelmätestauksessa käyttötapausten testaukseen. Ainoastaan Testauksen kohde vaihdetaan Käyttötapaus :ksi. 1. Testaaja 2. Päivämäärä 3. Testauksen kohde Käyttötapaus Yksikkötestauksessa luokka tai yksittäinen metodi, järjestelmätestauksessa käyttö/testitapaus. 4. Testauksen kuvaus Kuvataan miten testattiin, millaisia parametreja syötettiin ja mahdollisesti mitä muita luokkia/metodeita käytettiin testissä. 5. Odotettu tulos Kuvataan, mitä tuloksia testistä oletettiin syntyvän. 6. Lopputulos "OK"riittää kertomaan, ettei virheitä esiintynyt. Virheet tai puutteet mainitaan, mikäli niitä löytyi. 3 Testauksen vaiheet Testaus koostuu kolmesta osavaiheesta: yksikkö-, integrointi ja järjestelmätestauksesta. Vaiheet seuraavat ajallisesti toisiaan esitetyssä järjestyksessä. Tässä kappaleessa kerrotaan kunkin vaiheen toteutuksesta yksityiskohtaisesti. 3.1 Yksikkötestaus Yksikkötestauksessa keskitytään yhden ohjelman yksikön toiminnan tarkasteluun. Vaiheessa varmistetaan, että kukin yksikkö (luokka tai komponentti) toimii virheettömästi ja
suunnitteludokumentissa kuvatulla tavalla. Jokainen ohjelmoija suorittaa yksikkötestauksen itse ohjelmoimalleen komponentille. Yksikkötestauksessa käytetään yleisesti lasilaatikkotestauksen (white-box) menetelmiä eli testauksessa käytetään hyväksi yksikön lähdekoodia. Lähdekoodin avulla suunnitelluilla testitapauksilla pyritään paikallistamaan mahdolliset virheet yksikön sisällä. Yksikkötestauksessa käytetään mahdollisuuksien mukaan myös ns. tynkiä eli tyhjiä luokkia, joiden tehtävänä on simuloida muita testauksessa mahdollisesti tarvittavia moduuleja. Testejä ajetaan ohjelmoinnin kanssa rinnakkain, jolloin aina jonkin toiminnallisuuden toteutuksen jälkeen sen toiminta testataan. Jokaisen yksikön toiminta pyritään erottamaan muusta koodista ja ympäristöstä niin, että testin läpimeno ei riipu muusta koodista. Tällöin säästetään aikaa testiä kirjoitettaessa ja nopeutetaan mahdollisten virheiden löytämistä. Yksikkötestaus suoritetaan kaikille ohjelman luokille riippumatta toteutuskielestä. Javalla toteutetuille ohjelman osille yksikkötestaustyökaluna käytetään JUnit- kirjastoa, ja C++:lla toteutetuille osille JUnitin C++-kielistä käännöstä CppUnit:ia. Tekstit rakennetaan seuraavalla tavalla, esimerkit Java-kielisiä: 1. Jokaista testattavaa luokkaa kohden kirjoitetaan TestCase-luokasta periytyvä aliluokka. 2. Ylikirjoitetaan setup() ja teardown() metodit, jotka alustavat ja vapauttavat testatut objektit. 3. Kirjoitetaan testiluokkaan tarvittava määrä testxxx() nimisiä testimetodeita. 4. Kirjoitetaan jokaiseen testimetodiin jokin toiminto ja käytetään JUnit-kirjaston assertxxx()- metodeita tuloksen oikeallisuuden tarkistamiseen. 5. Testiluokkaan tarvitaan myös staattinen suite()-metodi, joka luo testimetodeista testisarjan. 6. Testit voidaan ajaa esimerkiksi luomalla Testiluokkaan main()-metodi, joka käynnistää testauksen kutsumalla JUnit-kirjaston TestRunner.run()-metodia edellisessä kohdassa mainitun suite()-metodin paluuarvo parametrinä. Testiesimerkit liitteenä. 4 3.2 Integrointitestaus Integrointitestauksessa testataan komponenttien välisten rajapintojen toimintaa. Toisin sanoen testaus kohdistuu erillisten komponenttien väliseen vuorovaikutukseen ja kommunikointiin sekä niiden väliseen toiminnallisuuteen. Integroitavien yksiköiden yksikkötestauksen täytyy olla hyväksyttävästi suoritettu ennen niiden integrointitestauksen aloittamista.
Ainoa integrointitestaukseen kuuluva kohde on palvelimen ja asiakkaan välinen kommunikointi. Testataan aidossa ympäristössä lähettää asiakkaalta kaikki mahdolliset komennot erilaisin kombinaatioin. Myös vääriä ja virheellisiä paketteja lähetetään palvelimelle. Testissä keskitytään tiedonsiirtoon ja molemmissa päissä pakettien ja parametrien parserointiin, sekä että syöte- ja tulostetiedostot sijaitsevat oikeissa paikoissa. 5 3.3 Järjestelmätestaus Järjestelmätestauksessa testataan ohjelmistoa sille määriteltyjen vaatimusten suhteen. Ohjelmiston toimintaa testataan kaikissa vaatimusmäärittelyssä esitetyissä käyttötapauksissa käyttäen testiaineistona suunnitteludokumentissa esittettyjä tavoitepohjaisia käyttötapauksia ja komentorivikäyttöliittymän yhteydessä esitettyjä käyttötapauksia. Järjestelmän ylläpitäjän testitapaukset suunnitellaan erikseen. Testaus suoritetaan järjestyksessä komentorivi-, teksti-, Swingkäyttöliittymä. Tällöin ensimmäisenä suoritettava komentorivitestaus sisältää koko systeemin kattavan simulaation testauksen, jonka jälkeen voidaan testata muita käyttöliittymiä varmoina, että simulaatio suoritetaan oikein. Järjestelmätestaus kuvataan tarkemmin luvussa 6. 4 Toteuttamatta ja testaamatta jäävä toiminta Täysin kattavasti testataan järjestelmän toiminnan kannalta keskeiset komponentit: Ydin, Pedigree ja Marker. Asiakas- ja Palvelin-komponentit testataan siinä määrin kuin käytettävissä olevan ajan puitteissa on mahdollista. Ohjelman ulkoiset osat, markertool ja simco, oletetaan testatuiksi. 5 Testausympäristö Järjestelmän toimintaa testataan määrittelydokumentissa kuvattujen toimintaympäristöstä esitettyjen vaatimusten mukaisesti. Ohjelma testataan laitoksen CS Linux ympäristössä, Java-client testataan sekä CS Linuxissa että Windows-ympäristössä, kuitenkin niin, että varsinainen testaus suoritetaan vain toisessa, ja ohjelman toimivuus varmistetaan molemmissa. Palvelinta testataan vain laitoksen verkossa. 6 Järjestelmätestauksen testitapaukset Tässä kuvataan ohjelmistolle suoritettavat testitapaukset. Testien tuloksista raportoidaan testausdokumentissa tämän dokumentin toisessa luvussa, Testausstrategia, kuvatulla ta-
valla. Testitapaukset on jaoteltu vaatimusmäärittelydokumentin mukaisesti tutkijan ja järjestelmän ylläpitäjän käyttötapauksiin. 6 6.1 Järjestelmää käyttävän tutkijan käyttötapaukset Järjestelmää käyttävän tutkijan tavoitepohjaiset käyttötapaukset ovat: Käyttötapaus 1: Sokeritaudin periytymisen tutkiminen Käyttötapaus 2: Aineistoa artikkelia varten Käyttötapaus 3: Sokeritautigeenitutkimuksen uusiminen Käyttötapaus 4: Geeniparametrien toimivuuden testaus Käyttötapaus 5: Väärät tutkimustiedot Käyttötapaus 6: Ämmänsaaren väestön kehittyminen Käyttötapaus 7: Siirtolaisten vaikutus Ämmänsaaren geeniperimään Nämä käyttötapaukset on kuvattu tarkemmin suunnitteludokumentissa luvussa Graafinen käyttöliittymä (Java Swing) ja sen liitteenä olevassa käyttötapauskuvasarjassa. Käyttöliittymästä tarkastetaan käyttötapauksissa esitettyjen toiminnallisuuksien lisäksi käyttöliittymän ulkoasuun liittyviä seikkoja seuraavasti: Käyttöliittymäelementtien yhtenäisyys eri näkymissä. Käytettyjen Swing elementtien toiminnan yhtenäisyys. Käyttöliittymän reagointi syötteisiin ja mahdollinen vaikutus muihin elementteihin. Testattavat komentorivikäyttöliittymään liittyvät käyttötapaukset ovat seuraavat: populous start-server Käynnistää palvelimen. populous load-params params21-7-2004.param Lataa parametrit tiedostosta. populous simulation-mode tree founders 100 last- generation 2000 generations 10 result-dir MyDir Ajetaan vain sukupuun luonti annetuin parametrein. Sukupuu tallennetaan MyDirhakemistoon vakionimellä pedigree_10.
populous simulation-mode pedigree founders 200 last- generation 3500 generations 15 result-dir OtherDir sub-populations 3 sub-population- sizes 50,50,100 sub-population-migratations (1,0,0)(0.1,0.8,0.1)(0.3,0.4,0.3) savegenerations 12,13 save-params MunParametrit Ajetaan vain sukupuun ja kromosomitiedostojen luonti. Talletataan sukupolvet 12,13 ja 15 (viimeinen) OtherDir-hakemistoon vakionimillä tree_12, pedigree_12 jne. Lisäksi generoidaan sukupuut käyttäen alipopulaatioita, tässä 3 alipopulaatiota. Alipopulaatiosta A ei siirrytä ikinä muihin alipopulaatioihin, B:stä siirrytään C:hen ja A:han 10% todennäköisyydellä ja C:stä siirrytään pois sekä B:hen että A:han 30% todennäköisyydellä. Talletataan vielä kaikki annetut parametrit parameters/munparametrithakemistoon. Ilman MunParametrit-määrettä olisi talletettu oletustiedostoon, joka tässä tapauksessa olisi ollut "OtherDir", koska resultdir on määritelty. Ilman sitä se olisi ollut muotoa YYYY-MM-DD_ID.param. populous simulation-mode marker load-pedigree pedigree_20 iterations 50 chrom-length 100000000 snp-rate 0.000001 recomb-rate 0.000001 effectivepop-size 15000 disease-mut-freq 0.08 min-minor-allele-freq 0.12 markers 4000 sample-size 300 prevalence 0.05 penetrance 0.19 sample-type affected reportfile marker-mapfile Ei ajeta sukupuun generointia tai kromosomien periytymistä, vaan otetaan ne valmiiksi tiedostosta. Ajetaan 50 iteraatiota, ja "chrompedigreeonce"on automaattisesti päällä, eli iteroidaan vain markertoolia ja simcoa. Raportti ja markkerikartta talletetaan vakiotiedostoihin (markermap ja report). populous simulation-mode full save-params 28-8-2004ajo3 founders 100 lastgeneration 2000 generations 20 iterations 100 pedigree-once savepedigrees save-generations 15,16 chrom-length 100000 snp-rate 0.00003 recomb-rate 0.00002 effective-pop-size 10000 disease-mut-freq 0.04 minminor- allele-freq 0.12 markers 2000 sample-size 100 prevalence 0.05 penetrance 0.19 parents-in-results Tallennetaan annetut parametrit, iteroidaan 100 kertaa, mutta vain markertoolia ja simcoa, talletetaan sukupolvet 15, 16, 19, 20 (15 ja 16 annettu, 20 on viimeinen ja 19 tulee -parentsinresult:sta). Ei tallenna sukupuutiedostoja, vain kromosomitiedostot. Kaikissa käyttötapauksissa tarkastetaan, että ne toimivat annetuilla parametreilla, ja että niiden tuloksena saatavat tulostiedostot ovat oikeanlaiset ja ne sijaitsevat niille suunnitellussa hakemistossa. 7 6.2 Järjestelmän ylläpitäjän käyttötapaukset Järjestelmän ylläpitoon liittyviä käyttötapauksia testataan kokeilemalla toimintoja esim. seuraavilla tavoilla: 1. Käynnistetään ohjelma. Käynnistyykö?
8 2. Käynnistetään ohjelma uudelleen. Mitä tapahtuu? 3. Testataan yhteyttä koneeseen, jonka IP-osoite on annettu. Toimiiko yhteys?
0 import junit.framework.test; import junit.framework.testcase; import junit.framework.testsuite; public class TreeTest extends TestCase { private Tree tree; private Leaf leaf; //Konstruktori. Parametri on testitapauksen nimi. public TreeTest(String name) { super(name); //Tätä kutsutaan aina ennen jokaista testimetodia. protected void setup() { tree = new Tree(); leaf = new Leaf(); tree.addleaf(leaf); //Tätä kutsutaan jokaisen testimetodin jälkeen. protected void teardown() { tree = null; leaf=null; //Testataan lehden lisääminen. public void testaddleaf() { Leaf leaf2 = new Leaf(); tree.addleaf(leaf2); //assertcondition(message, expected, actual); assertequals("lehtien määrä", 2, tree.leafcount()); //Testataan puun tyhjennys. public void testemptytree() { tree.empty(); asserttrue(tree.isempty()); //Kootaan testisarja. public static Test suite() { TestSuite suite = new TestSuite(TreeTest.class); // Vaihtoehtoinen tapa on lisätä kaikki käsin. // TestSuite suite = new TestSuite(); // suite.addtest(new TreeTest("testAddLeaf")); // suite.addtest(new TreeTest("testEmptyTree")); return suite; //Ajetaan testitapaus. public static void main(string args[]) { junit.textui.testrunner.run(suite()); Ohjelmalistaus 1: Testiluokka Javalla.
1 import junit.framework.test; import junit.framework.testsuite; public class TreeTestSuite { //Kootaan testisarjat. public static Test suite() { TestSuite suite = new TestSuite(); suite.addtest(pinetreetest.suite()); suite.addtest(oaktreetest.suite()); return suite; //Ajetaan testisarjat. public static void main(string args[]) { junit.textui.testrunner.run(suite()); Ohjelmalistaus 2: Testit kokoava luokka Javalla.