MUTASJONSTESTING LAG BUGS FOR Å FÅ BEDRE KODE Filip van Laenen Testdagen Odin 2015 1 https://www.flickr.com/photos/cskk/3759544397
Hvem er jeg? 18 år i IT-bransjen Utvikler (Java/Smalltalk/Ruby) Arkitekt/teknisk ansvarlig (Tester/QA) Flere års erfaring med mutasjonstesting http://www.slideshare.net/filipvanlaenen/ 2
Mutation Testing The Book https://leanpub.com/mutationtesting 3
Mutation Testing The Book https://leanpub.com/mutationtesting SJEKK PRIS E N! $0.00 4
HVA ER MUTASJONSTESTING? 5 https://www.flickr.com/photos/cskk/3759544397
http://thedailywtf.com/articles/seeking-the-summoner.aspx 6
7
8
9
Mutasjonen i kildekoden int max(int a, int b) { return (a < b)? b : a; int max(int a, int b) { return (a b)? b : a; 10
11
12
13
14
Ekvivalente mutasjoner int max(int a, int b) { return (a < b)? b : a; int max(int a, int b) { return (a b)? b : a; 15
MUTASJONSOPERATORER 16 https://www.flickr.com/photos/cskk/3759544397
Mutasjonsoperatorer Aritmetikk (+, -,,, ) Boolske operatorer (,,, ) Sammenligninger (=, <, >,,,, ) Kortslutning av grener Konstanter (tall, tekst, ) Fjerning av linjer Nullstilling av returverdier 17 https://www.flickr.com/photos/ynse/1531699476/
Eksempel integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade > 12) { passed passed + 1 return passed; 18 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: > integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade > 12) { passed passed + 1 return passed; 19 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: + integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed - 1 return passed; 20 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: endring av tallverdi integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 13) { passed passed + 1 return passed; 21 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: kortslutning av if-løkke integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (true) { passed passed + 1 return passed; 22 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: kortslutning av if-løkke integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (true) { passed passed + 1 return passed; 23 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: fjerning av en kodelinje integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; 24 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: nullstilling av returverdi integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return 0; 25 https://www.flickr.com/photos/ynse/1531699476/
Mutasjonsoperatorer Regulære uttrykk Samtidighet Avhengigheter API-endringer Arv 26 https://www.flickr.com/photos/ynse/1531699476/
Utfordringer Evige løkker/rekursjon Syntaksfeil Tilstandslekkasje Segmentation faults Ekvivalente mutasjoner 27 https://www.flickr.com/photos/ynse/1531699476/
Ekvivalente mutasjoner https://www.flickr.com/photos/cq-biker/15606327367/ To forskjellige systemer som alltid gir samme output for samme input Vanskelig å oppdage automatisk Vanskelig å verifisere manuelt 28
Ekvivalente mutasjoner number max(a, b) { if (a b) { return a; else { return b; number max(a, b) { if (a > b) { return a; else { return b; https://www.flickr.com/photos/cq-biker/15606327367/ 29
Ekvivalente mutasjoner number max(a, b) { if (a b) { return a; else { return b; number max(a, b) { if (a > b) { return a; else { return b; https://www.flickr.com/photos/cq-biker/15606327367/ 30
HVORFOR VIRKER MUTASJONSTESTING? 31 https://www.flickr.com/photos/cskk/3759544397
Hvorfor virker mutasjonstesting? Generated mutants are similar to real faults. 32 Andrews, Briand, Labiche, ICSE 2005
Hvorfor virker mutasjonstesting? In practice, if the software contains a fault, there will usually be a set of mutants that can only be killed by a test case that also detects that fault. Geist et. al., Estimation and Enhancement of Real-time Software Reliability through Mutation Analysis, 1992 33
Hvorfor virker mutasjonstesting? Complex faults are coupled to simple faults in such a way that a test data set that detects all simple faults in a program will detect most complex faults. K. Wah, Fault Coupling in Finite Bijective Functions, 1995 34
Hvorfor virker mutasjonstesting? Complex faults are coupled to simple faults in such a way that a test data set that detects all simple faults in a program will detect most complex faults. K. Wah, Fault Coupling in Finite Bijective Functions, 1995 35
Virker mutasjonstesting? Mutation testing is more powerful than statement or branch coverage. Walsh, Ph.D. Thesis, State University of New York at Binghampton, 1985 Mutation testing is superior to data flow coverage criteria. Frankl, Weiss, Hu, Journal of Systems and Software, 1997 36
MUTASONSTESTING OG TESTING 37 https://www.flickr.com/photos/cskk/3759544397
Testdekning Vanskelig å jukse Å kjøre gjennom kildekoden er ikke nok Kan peke ut fokusområder for manuell testing 38
Manglende testtilfeller 39 Tips til nye testtilfeller Avhengig av verktøyet Krever tilgang til rapportene Ikke alltid trivielt http://www.javaadvent.com/2014/12/mutation-testing-in-java-with-pit-and.html
Eksempel integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade > 12) { passed passed + 1 return passed; 40 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: > integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 Ha en 12 i return passed; testsettet ditt integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade > 12) { passed passed + 1 return passed; 41 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: + integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 Ha en return passed; 12 i testsettet ditt integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed - 1 return passed; 42 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: endring av tallverdi integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 Ha en 12 i return passed; testsettet ditt integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 13) { passed passed + 1 return passed; 43 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: kortslutning av if-løkke integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 Ha en <12 return passed; i testsettet ditt integer students_passed(grades) { passed 0; foreach (grade grades) { if (true) { passed passed + 1 return passed; 44 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: fjerning av en kodelinje integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; Ha en 12 i testsettet ditt integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; 45 https://www.flickr.com/photos/ynse/1531699476/
Eksempel: nullstilling av returverdi integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 return passed; integer students_passed(grades) { passed 0; foreach (grade grades) { if (grade 12) { passed passed + 1 Ha en 12 i testsettet return 0; 46 ditt https://www.flickr.com/photos/ynse/1531699476/
HVIS MUTASJONSTESTING ER SÅ BRA, HVORFOR BLIR DET IKKE BRUKT? 47 https://www.flickr.com/photos/cskk/3759544397
Mutasjonstesting er gammelt nytt Allerede beskrevet i 1971: R. Lipton, Fault Diagnosis of Computer Programs Videre forskning i løpet av 1970tallet: R. Lipton et. al., Hints on Test Data Selection: Help for the Practicing Programmer, 1978 48
Historiske hindringer Mangel på enhetstestingverktøy Mangel på enhetstestingpraksis Ineffektive implementasjoner TDD Lange prosesseringstider Integrasjon med utviklingsverktøy 49
50
YTELSE 51 https://www.flickr.com/photos/cskk/3759544397
Kildekode eller binærkode? Kildekode Tekstmanipulasjon Krever kompilering Binærkode Raskt Krever dekompilering AST-tre https://www.flickr.com/photos/grant_subaru/9306928331 Gylden middelvei? 52
Utvelgelse av enhetstester Mål: finne enhetstesten som «dreper» mutanten 53 https://www.flickr.com/photos/grant_subaru/9306928331
54
55
56
Utvelgelse av enhetstester Mål: finne enhetstesten som «dreper» mutanten Midler: Testdekning Manuelle hints Konvensjoner (klassenavn, pakkenavn) Caching av testresultater 57 https://www.flickr.com/photos/grant_subaru/9306928331
Kompleksitet Eksempel: 50 klasser 20 enhetstester per klasse 1ms per enhetstest Testrunde: 50 20 1ms = 1s 100 mutanter per klasse: Naiv implementasjon: 100 50 1s = 1h 23m 20s Klassescoping: 100 50 20 1 ms = 1m 40s Idealt: 100 50 1ms = 5s 58 https://www.flickr.com/photos/grant_subaru/9306928331
Kompleksitet Eksempel: 500 klasser 20 enhetstester per klasse 1ms per enhetstest Testrunde: 500 20 1ms = 10s 100 mutanter per klasse: Naiv implementasjon: 100 500 10s = 5,8d Klassescoping: 100 500 20 1 ms = 16m 40s Idealt: 100 500 1ms = 50s 59 https://www.flickr.com/photos/grant_subaru/9306928331
VERKTØY 60 https://www.flickr.com/photos/cskk/3759544397
Anbefalte verktøy Java: Ruby: Humbug JavaScript: https://www.flickr.com/photos/ianturk/18577725240/ Mutant PHP: PIT Grunt-mutation-testing 61
PIT Java JUnit & TestNG Maven & kommandolinje Muterer bytekode Konfigurerbart sett med mutatorer http://pitest.org/ 62
PIT Java JUnit & TestNG Maven & kommandolinje Muterer bytekode Konfigurerbart sett med mutatorer http://pitest.org/ 63 http://www.javaadvent.com/2014/12/mutation-testing-in-java-with-pit-and.html
PIT Java JUnit & TestNG Maven & kommandolinje Muterer bytekode Konfigurerbart sett med mutatorer http://pitest.org/ 64 http://www.javaadvent.com/2014/12/mutation-testing-in-java-with-pit-and.html
Mutant Ruby Rspec Kommandolinje Aktivt prosjekt Grei dokumentasjon https://github.com/mbj/mutant https://www.youtube.com/watch?v=awvuquxhx8m 65
HVORDAN KOMME I GANG? 66 https://www.flickr.com/photos/cskk/3759544397
Hvordan komme i gang Velg riktig verktøy Om mulig, bruk fra dag 1 Avgrens i begynnelsen Kritisk kode Relevante mutatorer Lær å bruke verktøyet Tro på hva det sier Eller bevis at det tar feil 67
OPPSUMMERING 68 https://www.flickr.com/photos/cskk/3759544397
Er mutasjonstesting nyttig? Enkle prinsipper Veldig kraftig verktøy Utfordringer rundt ytelse Verktøyene blir bedre og bedre Ja 69, forutsatt at enhetstesting er på plass
Er mutasjonstesting nyttig? Enkle prinsipper Veldig kraftig verktøy Utfordringer rundt ytelse Verktøyene blir bedre og bedre Ja 70, forutsatt at enhetstesting er på plass
Er mutasjonstesting nyttig? Enkle prinsipper Veldig kraftig verktøy Utfordringer rundt ytelse Verktøyene blir bedre og bedre Ja 71, forutsatt at enhetstesting er på plass
Takk for din oppmerksomhet! Contact information: @filipvanlaenen fvl@computas.com / f.a.vanlaenen@ieee.org https://no.linkedin.com/in/filipvanlaenen https://leanpub.com/mutationtesting 72 http://www.slideshare.net/filipvanlaenen/