The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
MUTANTS KILLER (Revised) - PIT: state of the art of mutation testing system
1. PIT: state of the art of mutation testing system
Revised edition
MUTANTS KILLER
by Tàrin Gamberìni - CC BY-NC-SA 4.0
2. Lavora da sempre con tecnologie
Java-based free e Open Source
presso la Regione Emilia-Romagna
Si interessa di Object Oriented Design,
Design Patterns, Build Automation,
Testing e Continuous Integration
TÀRIN GAMBERÌNI
Partecipa attivamente
al Java User Group
Padova
4. UNIT TESTING & TDD
The proof of working code
Refactor with confidence (regression)
Improve code design
Living documentation
TDD extremely valuable in some context
5. CONTINUOUS INTEGRATION
Maintain a single source repository
Automate the build
Cheap statics for code quality
Automate unit & integration tests
Catch problems fast
6. LINE COVERAGE
Is a measure of tested source code
line, statement, branch, … , coverage
7. LINE COVERAGE 100%
Only able to identify not tested code
Doesn't check tests are able to detect faults
Measures only which code is executed by tests
8. WEAK TESTS
public static String foo( boolean b ) {
if ( b ) {
performVitallyImportantBusinessFunction();
return "OK";
}
return "FAIL";
}
@Test
public void shouldFailWhenGivenFalse() {
assertEquals("FAIL", foo( false ));
}
@Test
public void shouldBeOkWhenGivenTrue() {
assertEquals("OK", foo( true ));
}
The untested side effect
9. WEAK TESTS
public static String foo( boolean b ) {
if ( b ) {
performVitallyImportantBusinessFunction();
return "OK";
}
return "FAIL";
}
@Test
public void shouldFailWhenGivenFalse() {
assertEquals("FAIL", foo( false ));
}
@Test
public void shouldBeOkWhenGivenTrue() {
assertEquals("OK", foo( true ));
}
The untested side effect
10. WEAK TESTS
public static String foo( int i ) {
if ( i >= 0 ) {
return "foo";
} else {
return "bar";
}
}
@Test
public void shouldReturnFooWhenGiven1() {
assertEquals("foo", foo( 1 ));
}
@Test
public void shouldReturnBarWhenGivenMinus1() {
assertEquals("bar", foo( -1 ));
}
The missing boundary test
11. WEAK TESTS
public static String foo( int i ) {
if ( i >= 0 ) {
return "foo";
} else {
return "bar";
}
}
@Test
public void shouldReturnBarWhenGiven1() {
assertEquals("bar", foo( 1 ));
}
@Test
public void shouldReturnFooWhenGivenZero() {
assertEquals("foo", foo( 0 ));
}
@Test
public void shouldReturnFooWhenGivenMinus1() {
assertEquals("foo", foo( -1 ));
}
The missing boundary test
12. WEAK TESTS
public static String foo(Collaborator c, boolean b) {
if ( b ) {
return c.performAction();
}
return "FOO";
} @Test
public void shouldPerformActionWhenGivenTrue() {
foo(mockCollaborator,true);
verify(mockCollaborator).performAction();
}
@Test
public void shouldNotPerformActionWhenGivenFalse() {
foo(mockCollaborator,false);
verify(never(),mockCollaborator).performAction();
}
The myopic mockist
13. WEAK TESTS
public static String foo(Collaborator c, boolean b) {
if ( b ) {
return c.performAction();
}
return "FOO";
} @Test
public void shouldPerformActionWhenGivenTrue() {
String result = foo(mockCollaborator,true);
verify(mockCollaborator).performAction();
assertEquals("MOCK", result);
}
@Test
public void shouldNotPerformActionWhenGivenFalse() {
String result = foo(mockCollaborator,false);
verify(never(),mockCollaborator).performAction();
assertEquals("FOO", result);
}
The myopic mockist
15. MUTATION TESTING
●
originally proposed by Richard Lipton
as a student in 1971
●
1st implementation tool was a PhD
work in 1980
●
recent availability of higher computing
power has led to a resurgence
●
expose weaknesses in tests (quality)
16. MUTATION TESTING
●
originally proposed by Richard Lipton
as a student in 1971
●
1st implementation tool was a PhD
work in 1980
●
recent availability of higher computing
power has led to a resurgence
●
expose weaknesses in tests (quality)
20. MUTANT KILLED
Proof of detected mutated code
Test is testing source code properly
If the unit test fails
21. MUTANT LIVED
Proof of not detected mutated code
If the unit test succeed
Test isn't testing source code
22.
23. PIT: BASIC CONCEPTS
Applies a configurable set of mutators
Generates reports with test results
Manipulates the byte code generated
by compiling your code
28. PIT: MUTATORS
Return Values Mutator Conditionals
public Object foo() {
return new Object();
}
public Object foo() {
new Object();
return null;
}
→
29. PIT: MUTATORS
Void Method Call Mutator
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void
doSomething(int i) {
// does something
}
→
public int foo() {
int i = 5;
return i;
}
public void
doSomething(int i) {
// does something
}
31. PIT: MUTATORS
Application field
Traditional and class
PIT is suitable for "ordinary" java programs because
mutators change "ordinary" java language instructions.
The right mutator for the right application field
Not the best option if you are interesting testing:
●
Aspect Java programs, try AjMutator
●
Concurrent programs, try ExMan
●
Mutators for: reflection, java annotations, generics, … ?
32. HOW PIT WORKS
Running the tests
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
Your program
34. HOW PIT WORKS
Running the tests
Generates mutant by applaying mutators
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
mutant 2
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
mutant 1
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
mutant 3
35. HOW PIT WORKS
Brute force
x = 9
100 tests x 1.2ms = 0.12s
0.12s x 10000 mutants = 20min !!!
1000 class x 10 mutants per class = 10000 mutants
36. HOW PIT WORKS
Running the tests
PIT leverages line coverage to discard tests
that do not exercise the mutated line of code
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
public int foo() {
int i = 5;
doSomething(i);
return i;
}
public void doSomething(int i) {
// does something
}
mutant 3
38. HOW PIT WORKS
Outcomes
● Killed, Lived
● No coverage: the same as Lived except there were no
tests that exercised the mutated line of code
● Non viable: bytecode was in some way invalid
● Timed Out: infinite loop
● Memory error: mutation that increases the amount of
memory used
● Run error: a large number of run errors probably
means something went wrong
48. EXAMPLE
Helps discovering better test data
Well known techniques(1)
for creating data
Input space partitioning, boundary values, error
guessing.
Cartesian product of test data leads to a combinatorial
explosion.
PIT helps but YOU have to find
PIT tells you when a mutant has survived, but you are in
charge to find out the right test data which will kill it.
(1) Introduction to Software Testing, 2008 – by P. Ammann, J. Offutt
58. CREDITS
Minion with gun - by jpartwork (no license available)
https://nanookofthenerd.wordpress.com/2015/01/30/the-magnificent-maddening-marvelous-
minion-episode-032/
Minion Hands on - by Ceb1031 (CC BY-SA 3.0)
http://parody.wikia.com/wiki/File:Bob_minions_hands.jpg
Canon XTi components after disassembly - by particlem (CC BY 2.0)
https://www.flickr.com/photos/particlem/3860278043/
Continuous Integration - by New Media Labs (no license available)
http://newmedialabs.co.za/approach
Rally car - by mmphotography.it (CC BY-NC 2.0)
https://www.flickr.com/photos/grantuking/9705677549/
Crash Test dummies for sale - by Jack French (CC BY-NC 2.0)
https://www.flickr.com/photos/jackfrench/34523572/
Minion (no license available)
http://thisandthatforkidsblog.com/2013/09/17/easy-to-make-diy-minion-halloween-pumpkin/
Images
59. Mutant - by minions fans-d6txvph.jpg (no license available)
http://despicableme.wikia.com/wiki/File:Evil_minions_by_minions_fans-d6txvph.jpg
Mutant killed - by Patricia Uribe (no license available)
http://weheartit.com/entry/70334753
Mutant lived - by Carlos Hernández (no license available)
https://gifcept.com/VUQrTOr.gif
PIT logo - by Ling Yeung (CC BY-NC-SA 3.0)
http://pitest.org/about/
Circled Minions - by HARDEEP BHOGAL - (no license available)
https://plus.google.com/109649247879792393053/posts/ghH6tiuUZni?
pid=6004685782480998482&oid=109649247879792393053
Finger puppets – by Gary Leeming (CC BY-NC-SA 2.0)
https://www.flickr.com/photos/grazulis/4754781005/
Questions - by Shinichi Izumi (CC BY-SA)
http://despicableme.wikia.com/wiki/File:Purple_Minion.png
CREDITS
Images