View
287
Download
2
Category
Preview:
Citation preview
MUTASJONSTESTING
LAG BUGS FOR Å FÅ BEDRE KODEFilip van Laenen — Testdagen Odin 2015
1https://www.flickr.com/photos/cskk/3759544397
Hvem er jeg?
2
● 18 år i IT-bransjen– Utvikler (Java/Smalltalk/Ruby)
– Arkitekt/teknisk ansvarlig
– (Tester/QA)
● Flere års erfaring med mutasjonstesting
http://www.slideshare.net/filipvanlaenen/
Mutation Testing – The Book
https://leanpub.com/mutationtesting
3
Mutation Testing – The Book
https://leanpub.com/mutationtesting
4
$0.00
SJEKK PRISEN!
HVA ER MUTASJONSTESTING?
5https://www.flickr.com/photos/cskk/3759544397
6http://thedailywtf.com/Articles/Seeking-The-Summoner.aspx
7
8
9
Mutasjonen i kildekoden
10
int max(int a, int b) { return (a < b) ? b : a;}
int max(int a, int b) { return (a ≥ b) ? b : a;}
11
12
13
14
Ekvivalente mutasjoner
15
int max(int a, int b) { return (a < b) ? b : a;}
int max(int a, int b) { return (a ≤ b) ? b : a;}
MUTASJONSOPERATORER
16https://www.flickr.com/photos/cskk/3759544397
Mutasjonsoperatorer
17
● Aritmetikk (+, -, ×, ÷, …)
● Boolske operatorer ( , , ¬, …)∧ ∨
● Sammenligninger (=, <, >, ≤, ≥, ≠, …)
● Kortslutning av grener
● Konstanter (tall, tekst, …)
● Fjerning av linjer
● Nullstilling av returverdier
https://www.flickr.com/photos/ynse/1531699476/
Eksempel
18
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: ≥ → >
19
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: + → -
20
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: endring av tallverdi
21
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: kortslutning av if-løkke
22
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: kortslutning av if-løkke
23
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: fjerning av en kodelinje
24
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: nullstilling av returverdi
25
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;}
https://www.flickr.com/photos/ynse/1531699476/
Mutasjonsoperatorer
26
● Regulære uttrykk
● Samtidighet
● Avhengigheter
● API-endringer
● Arv
● …
https://www.flickr.com/photos/ynse/1531699476/
Utfordringer
27
● Evige løkker/rekursjon
● Syntaksfeil
● Tilstandslekkasje
● Segmentation faults
● Ekvivalente mutasjoner
https://www.flickr.com/photos/ynse/1531699476/
Ekvivalente mutasjoner
● To forskjellige systemer som alltid gir samme output for samme input
● Vanskelig å oppdage automatisk● Vanskelig å verifisere manuelt
28https://www.flickr.com/photos/cq-biker/15606327367/
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;
}
}
29https://www.flickr.com/photos/cq-biker/15606327367/
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;
}
}
30https://www.flickr.com/photos/cq-biker/15606327367/
HVORFOR VIRKER MUTASJONSTESTING?
31https://www.flickr.com/photos/cskk/3759544397
“Hvorfor virker mutasjonstesting?
32
Generated mutants are similar to real faults.
Andrews, Briand, Labiche, ICSE 2005
“Hvorfor virker mutasjonstesting?
33
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
“Hvorfor virker mutasjonstesting?
34
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
“Hvorfor virker mutasjonstesting?
35
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
““
Virker mutasjonstesting?
36
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
MUTASONSTESTING OG TESTING
37https://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
40
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;}
https://www.flickr.com/photos/ynse/1531699476/
Eksempel: ≥ → >
41
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en 12 i testsettet ditt
Eksempel: + → -
42
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en ≥12 i testsettet ditt
Eksempel: endring av tallverdi
43
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en 12 i testsettet ditt
Eksempel: kortslutning av if-løkke
44
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en <12 i testsettet ditt
Eksempel: fjerning av en kodelinje
45
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en ≥12 i testsettet ditt
Eksempel: nullstilling av returverdi
46
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;}
https://www.flickr.com/photos/ynse/1531699476/
⇒ Ha en ≥12 i testsettet ditt
HVIS MUTASJONSTESTING ER SÅ BRA,
HVORFOR BLIR DET IKKE BRUKT?
47https://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 1970-tallet:
– 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
– TDD
● Ineffektive implementasjoner
– Lange prosesseringstider
● Integrasjon med utviklingsverktøy
49
50
YTELSE
51https://www.flickr.com/photos/cskk/3759544397
Kildekode eller binærkode?
● Kildekode– Tekstmanipulasjon
– Krever kompilering
● Binærkode– Raskt
– Krever dekompilering
● AST-tre– Gylden middelvei?
52https://www.flickr.com/photos/grant_subaru/9306928331
Utvelgelse av enhetstester
● Mål: finne enhetstesten som «dreper» mutanten
53https://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
57https://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
58https://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
59https://www.flickr.com/photos/grant_subaru/9306928331
VERKTØY
60https://www.flickr.com/photos/cskk/3759544397
Anbefalte verktøy
● Java:– PIT
● Ruby:– Mutant
● PHP:
– Humbug
● JavaScript:– Grunt-mutation-testing
61https://www.flickr.com/photos/ianturk/18577725240/
PIT
62
● Java
● JUnit & TestNG
● Maven & kommandolinje
● Muterer bytekode
● Konfigurerbart sett med mutatorer
http://pitest.org/
PIT
63
● Java
● JUnit & TestNG
● Maven & kommandolinje
● Muterer bytekode
● Konfigurerbart sett med mutatorer
http://pitest.org/
http://www.javaadvent.com/2014/12/mutation-testing-in-java-with-pit-and.html
PIT
64
● Java
● JUnit & TestNG
● Maven & kommandolinje
● Muterer bytekode
● Konfigurerbart sett med mutatorer
http://pitest.org/
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
65https://www.youtube.com/watch?v=awVUqUxhx8M
HVORDAN KOMME I GANG?
66https://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 feil67
OPPSUMMERING
68https://www.flickr.com/photos/cskk/3759544397
Er mutasjonstesting nyttig?
69
● Enkle prinsipper
● Veldig kraftig verktøy
● Utfordringer rundt ytelse
● Verktøyene blir bedre og bedre
Ja , forutsatt at enhetstesting er på plass
Er mutasjonstesting nyttig?
70
● Enkle prinsipper
● Veldig kraftig verktøy
● Utfordringer rundt ytelse
● Verktøyene blir bedre og bedre
Ja , forutsatt at enhetstesting er på plass
Er mutasjonstesting nyttig?
71
● Enkle prinsipper
● Veldig kraftig verktøy
● Utfordringer rundt ytelse
● Verktøyene blir bedre og bedre
Ja , forutsatt at enhetstesting er på plass
Takk for din oppmerksomhet!
72
Contact information:
@filipvanlaenen
fvl@computas.com / f.a.vanlaenen@ieee.org
https://no.linkedin.com/in/filipvanlaenen
https://leanpub.com/mutationtesting http://www.slideshare.net/filipvanlaenen/
Recommended