390 likes | 532 Views
H13.2: Testing. Introductie Testing technieken Management aspecten. Noodzaak van testen. We willen betrouwbare software Mensenleven Economische waarde Opsporen van de bron van een error is veel werk ; het wordt duurder als de error later is ontdekt: 0.5 – 3.5 uur op de unitlevel
E N D
H13.2: Testing Introductie Testing technieken Management aspecten
Noodzaak van testen • We willen betrouwbare software • Mensenleven • Economische waarde • Opsporen van de bron van een error is veel werk; het wordt duurder als de error later is ontdekt: • 0.5 – 3.5 uur op de unitlevel • 6 – 10 x duurder op de systeemlevel
Test vroeg, en test vaak! ≥ 30% van totaal ontwikkelingkost (verschillende studies) Systeemrequirement acceptatietesting Systeemspecificaties systeemtesting Systeemontwerp integrationtesting Implementatie unit esting development testing De V-model
V-model • Develomenttest door ontwikkelaar zelf • Aceptatietest (aka functioneeltest) • Opdrachtgever wilt een laaste ronde test dat de product voldoet aan zijn requirement • Meestal uitgevoerd door een 3e partij • V-model ook toepasbaar op meer agile SDLCs • Doe een V per subproject (Parallel Devel.) • Doe een V per versie (RAD)
Terminologie System Under the Test (SUT), testobject Persoon bestel(producten) Product * bestellingen test1() { x = new Persoon(…) V = new Producten[] { appel, peer } x.bestel(V) assertx.bestellingen.contains(appel) ; assertx.bestellingen.contains(peer) ; assertx.bestellingen.size() == 2 ; } • test sequence • test input • test expectation • test case • test suite • faal / failure • error • fout / fault
Test cases maken assert r == 0 • Per test case, twee componenten: • Sequence en inputs • Verwachtingen • Je hebt heel veel test cases nodig! • Meestal handmatig duur • Genereren van sequences/inputs kun je nog (deels) automatiseren • Gebruik dit als complement van manuele testing • Formuleren van testverwachting is niet te automatiseren • Technieken: wit vs zwart, functioneel vs reactief, etc n(y) m(x)
Witte vs zwarte doos testing • ‘testbasis’ : • documentatie • ontwerp en specificaties • broncode • Wit je kan (en wil) de broncode van SUT zien • Zwart andersom. • Developertest is meestal wit, aceptatietest is meestal zwart.
Classificatieboom • Hoe kun je systematisch testen? partitioneer de inputdomein van SUT op een systematische wijze.Hypothese: SUT gedraagt equivalent op inputs uit dezelfde partitie.Voorbeeld: V.isEmpty() • Per partitie minstens 1 waarde (input-combo)(toch equivalent, dus 1x testen is in theorie voldoende, maar … ) V leeg V niet leeg V niet valide negatieve test
Partitie/classificatie techniek • Kan ook hiërarchisch. • Partities op laagste level heten “klassen” • Beschrijf vervolgens de combinaties (over de klassen) die je wil. • Ook geschikt voor zwarte doos testing. addCijfer(student,cijfer) Student Cijfer Invalid Onvoldoende Voldoende Bachelor < 5.0 5.0 ≤ c < 5.5 Master
addCijfer(student,cijfer) Student Cijfer Invalid Invalid Onvoldoende Voldoende Bachelor < 5.0 5.0 ≤ c < 5.5 Master 5.5 ≤ c ≤ 6.0 > 6.0 TC1 TC2 TC3 …
Grenswaarden • In principe, 1 concrete input per partitie is voldoende. • Maar fouten worden vaak gemaakt op de randen van een partitie maak dus ook aparte test cases. • Zwel het aantal van test cases op… Cijfer Onvoldoende < 5.0 5.0 ≤ c < 5.5 0.0 , 4.5, 4.99 5.0, 5.2, 5.49
Combinatorische explosie… partitie < 65 • Inputdomein ABC, totaal #combinaties is • Pragmatischer opties? schijf 1 Persoon leeftijd brutoInkomen nettoInkomen() ≥ 65 schijf 2 schijf 3 > schijf 3 erg veel! #A #B #C
Welke combinaties gaan we testen? • ALL : allemaal te veel. • ONE: elke klasse minimaal 1x getest te weinig. Student Cijfer Invalid Onvoldoende Voldoende Bachelor < 5.0 5.0 ≤ c < 5.5 Master
Welke combinaties gaan we testen? • ONE + random, tot N cases. • Gericht op combinaties-dekking specifier: • @A dek alle klassen van A • A*B dek alle combinaties van klassen uit A en B @Student.Invalid , Student.Bachelor * Cijfer.Voldoende , Student.Master * Cijfer.Onvoledende
Concrete vs spec-based verwachting Product getGoedkoopste(producten) goedkoper(producten) Persoon brutoInkomen nettoInkomen() test() { x = new Persoon(“Bob”, 17878) n = x.nettoInkomen() ; assertn == 10447.90 ; } context Product :: getGoepkoopste(producten) pre: producten null post : result.goedkoper(producten) test() { producten = … result = Product.getGoedkoopste(producten) assertresult.goedkoper(producten) }
Testverwachting • specificatie-based verwachting • Met een stukje code die een post-conditie implementeert en checkt. • Herbruikbaar, en robust! • Er zijn testobjecten waarvan de post-conditie erg moeilijk is om te formuleren (zoals uitrekenen van netto inkomen) • Concreet uitgedrukt in een concrete waarde. • Kost veel moeite om uit te rekennen • Niet generiek • Niet robust!
Dekking / coverage • Testing is in principe onvolledig. Bovendien, je bronnen zijn beperkt je moet beslissen waneer je stopt. • Definieer een kwantificeerbaar doel, zoals: • Coverage : hoeveel (in %) van dit doel bereikt is. • Te weinig coverage impliceert dat je nog niet voldoende toetst. • 100% coverage betekent niet dat je software bugvrij is. Elke regel in SUT wordt ooit uitgeoefend (door een test).
Standaarde dekkingconcepten • Line coverage (vorige slide) • Decision coverage : P(x,y) { if (even(x)) x = x/2 else x-- if (even(y)) y = y/2 else y-- return x+y } even(x) even(x) even(y) even(y) ControlFlowGraph Elke beslissing in SUT is uitgeoefend.
Standaarde dekkingconcepten • Keuze van dekkingcriterium beïnvloedt hoe grondig je testing is (dus ook de kosten). • Path coverage Hoeveel testcases zijn nodig? even(x) even(x) even(y) even(y) Elke executiepad in SUT is uitgeoefend.
Path-based coverage • Path coverage is sterk.100% path coverage 100% decision coverage 100% statement coverage. • Maar, oneindig als je een loop hebt dek alleen 0 of 1 iteraties. • Dan nog heb je potentieel vele paden exponentieel tov aantal van seriele beslissingpunten. • McCabe: neem alleen lineare onafhankelijke paden aantal is linier met de grote van je CFG.
McCabe Set van lineaire onafhankelijke paden die alle pijltjes dekken: 0 1 { [0,1,0,2] , [0,1,2] } 2 Elke pad heeft een f pijltje die anderen niet hebben.
Andere dekkingconcepten • Dekking over de partities (hebben we al over gehad) • Als je een toestandmachine hebt (later) : • State coverage • Branch coverage • Of de analoog van mcCabe • Mutatietest en mutatie coverage.Injecteert fouten op een systematische wijze ( mutant). Je test suite moet zo alle (niet equivalente) mutanten van de originele SUT kunnen onderscheiden.Duur! Alternatief: gebruik een gereduceerde set van mutatieoperatoren.
Model-based testing • Tot nu toe: we nemen aan dat SUT ‘functioneel’ gedraagt (SUT neemt input, en termineert met outputs). • Reactive systeem: het blijft draaien. • Voorbeeld: wekker, afstandbediening, verkeersysteem • Specificatie in termen van input vs output relatie is minder zinnig • Kan abstract beschreven worden met een toestandmachine model • Het kan erg ingewikkeld zijn. • Model-based testing: gebruikt de TM-model als een bron om test cases te genereren.
Model-based testing uit • Elke pad door de graaf is een test case: • pijltjes events als invoer • wat moet je controleren bij elke pijl en toestand in een pad? • Uit dit model kun je test cases (systematisch) genereren: • random • gericht volgens je dekking criterium • combinatie van deze entry / lampje aan [genoeg water] aan koffie … [niet genoeg] water entry / knippert
Model-based testing • Geschikt voor het testen van een reactief systeem. • Grondig. • Ook geschikt voor zwarte doos testing. • Tools: TorX (Uni. Twente), ARC. • Theorie PV
Overzicht • (complementaire) methodes om test cases af te leiden: input partitie en model based. • Coverage kwantificeerbaar uitdrukking van de grondigheid van je testing. • Problemen: • Persistentie • Concurrentie • GUI • Testen van andere aspecten: • Regressie • Security • Prestatie
Persistentie • DB, files. • Vormt een impliciet deel van de interne toestanden van SUT. • Problemen: • Een testcase doet side effect op DB/files je hebt een mechanisme nodig om de effecten ongedaan te maken. • Interacties met DB/files zijn traag.
Persistentie 2.. 1 • DB is vaak complex, hoe creëer je een representatieve DB populatie? • Copieer data uit productie te groot traag • Genereer hoe definieer je “representatief genoeg” ?Partitioneer, evt in combinatie met grenswaarden. Product ID naam prijs prijs ≤ 1.00 Persoon ID naam bestelt 1.. 0.. prijs > 1.00
Concurrentie • Een concurrent executie is gevoelig voor timing • Probleem • Je kunt een executie niet dupliceren! • Dus als een test case een error vindt, kun je de error misschien niet dupliceren. P doet iets P boekt stoel 33 Q doet iets Q boekt stoel 33 Wie de stoel krijgt is afhankelijk van de snelheid van P,Q, andere processen.
Regressietest • Na productie van een software, moeten we de software nog onderhouden: • bug fixs • nieuwe features • De modificaties mogen bestaande functionaliteiten, voor zover nog relevant, niet stuk maken. • Doe regressietest uitoefenen van de test suite van versie k-1. • TESTALL : voer de hele test suite uit het duurt vaak lang! • persistentie
Regressietest • Je zou een strategie moeten bedenken voor: • testselectie selecteer alleen een subset van je test suite, maar met maximaal fault revealing potentie. • testprioriteit als de selectie nog groot is, en je tijd beperkt is. • Opties: • Neem, per ‘module’, testcases die fouten ontdekten • Random • Mix • Instrumentatie neem test cases die de modificatiepunten passeren effectief, maar niet altijd mogelijk.
Performance testing • Een bedrijf wordt afgerekend als zijn applicatie niet genoeg presteert. • Performance testing: je kijkt hoe de applicatie reageert op toenemende werkbelasting. Elke VG simuleert bepaalde interacties creert dus belasting op App virtueel gebruiker APP DB aparte machine Server
Performance testing verwachte peaks #VBs (belasting) normale belasting tijd • load test: om responstijd op typische werkbelasting te meten. • stress test: wat is de maximale belasting dat de app aankan?
Test management • Groot project management is erg belangrijk. • Belangrijkste TM instrumenten: • testplan • stroomlijnen van je infrastructuur • software en hardware • personeel en organisatie • dagelijks sturing • monitoren van vooruitgang • afhandeling van bevindingen
Testplan, in grote lijn… • Definieer de scope • welke ‘modules’ moet je testen ? • welke aspecten ? (zoals functionaliteit, veiligheid, prestatie) • hoe grondig (per module) ? risico analyse • Som op de bronnen die je mag gebruiken • Beschrijf je aanpak • bijvoorbeeld de gekozen testmethodes • Anticipeer gevaren op je project geef een contigency plan
Risico analyse • Je bronnen zijn beperkt prioriteit stellen, zoals op basis van risico en impact. • Risico de kans dat een module M faalt. • Impact de schade die volgt als M faalt. • Je kunt R & I niet exact kwantificeren! schatting. Scala 1..5 (erg laag, laag, gemiddeld, hoog, erg hoog)
Bevindingen procedure Implementeer een strak en efficiënt bevindingen procedure. Gerapporteerd fix toegewezen gefixed accepteer rapport goedkeur voor fixing herschrijf tester wijst af tester akkoord slecht rapport bekeken afgewezen wijs fixing af herbekeken gesloten probleem keert toch terug uitgesteld Bron: Foundation of Software Testing, 2008.