Slide 1

Slide 1 text

Ralf D. Müller @RalfDMueller Johannes Dienst @JohannesDienst Spock vs Supermutanten Spezifikationstesten trifft auf Mutationstesten

Slide 2

Slide 2 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst Was ist Spock?

Slide 3

Slide 3 text

Was ist Spock? 3 Leonard Brüning Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 4

Slide 4 text

Was ist Spock? 4 private Fibonacci fib; @Before public void setup() { fib = new Fibonacci(); } @Test public void seedValue0() { assertEquals(0, fib.calc(0)); } @Test public void seedValue1() { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 5

Slide 5 text

Was ist Spock? 5 private Fibonacci fib; @Before public void setup() { fib = new Fibonacci(); } @Test public void seedValue0() { assertEquals(0, fib.calc(0)); } @Test public void seedValue1() { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 6

Slide 6 text

Was ist Spock? 6 private Fibonacci fib; @Before public void setup() { fib = new Fibonacci(); } @Test public void seedValue0() { assertEquals(0, fib.calc(0)); } @Test public void seedValue1() { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 7

Slide 7 text

Was ist Spock? 7 Fibonacci fib; @Before void setup() { fib = new Fibonacci(); } void seedValue0() { assertEquals(0, fib.calc(0)); } void seedValue1() { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 8

Slide 8 text

Was ist Spock? 8 Fibonacci fib; @Before void setup() { fib = new Fibonacci(); } void "test the fibonacci generator with input 0"() { assertEquals(0, fib.calc(0)); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Product Owner Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 9

Slide 9 text

Was ist Spock? 9 Fibonacci fib; @Before void setup() { fib = new Fibonacci(); } void "test the fibonacci generator with input 0"() { given: Fibonacci fib = new Fibonacci() when: def result = fib.calc(i) then: assertEquals(0, result); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 10

Slide 10 text

Was ist Spock? 10 void "test the fibonacci generator with input 0"() { given: Fibonacci fib = new Fibonacci() when: def result = fib.calc(i) then: assertEquals(0, result); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 11

Slide 11 text

Was ist Spock? 11 void "test the fibonacci generator with input 0"() { given: "an instance of the fibonacci generator" Fibonacci fib = new Fibonacci() when: "the fib sequence for 0 is calculated" def result = fib.calc(i) then: "the expected number is returned" assertEquals(0, result); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Product Owner Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 12

Slide 12 text

Was ist Spock? 12 void "test the fibonacci generator with input 0"() { given: "an instance of the fibonacci generator" Fibonacci fib = new Fibonacci() when: "the fib sequence for 0 is calculated" def result = fib.calc(i) then: "the expected number is returned" result == 0 } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Product Owner Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 13

Slide 13 text

Was ist Spock? 13 void "test the fibonacci generator with input #i"() { given: "an instance of the fibonacci generator" Fibonacci fib = new Fibonacci() when: "the fib sequence for a given input #i is calculated" def result = fib.calc(i) then: "the expected number #expected is returned" result == expected where: i || expected 0 || 0 2 || 1 11 || 89 } Developer Product Owner Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst

Slide 14

Slide 14 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 14 Reports

Slide 15

Slide 15 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 15 Reports

Slide 16

Slide 16 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 16 Reports Product Owner Developer

Slide 17

Slide 17 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 17 Zeilenabdeckung?

Slide 18

Slide 18 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 18 100% Icons made by Sprang from www.flaticon.com

Slide 19

Slide 19 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 19 Finde den Fehler? public List sort(List coll) { List list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com

Slide 20

Slide 20 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 20 Finde den Fehler? def "test Sort"() { given: "an instance of Sort" def Sort = new Sort() when: "the given list #list is sorted" def result = Sort.sort(list) then: "the result is as #expected" result == expected where: "" list || expected [] || [] [5] || [5] [2,1,3,8] || [1,2,3,8] } Icons made by Sprang from www.flaticon.com

Slide 21

Slide 21 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 21 Finde den Fehler? public List sort(List coll) { List list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com

Slide 22

Slide 22 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 22 Und nun? Icons made by Sprang from www.flaticon.com

Slide 23

Slide 23 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 23 Fehler gezielt provozieren Icons made by Sprang from www.flaticon.com

Slide 24

Slide 24 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 24 Automatisierung Icons made by Sprang from www.flaticon.com

Slide 25

Slide 25 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 25 Mutationstesten Icons made by Sprang from www.flaticon.com

Slide 26

Slide 26 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 26 Mutationstesten - Funktionsweise Icons made by Sprang from www.flaticon.com

Slide 27

Slide 27 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 27 DEMO HTML Report Icons made by Sprang from www.flaticon.com

Slide 28

Slide 28 text

Increments Mutator i++ wird zu i-- Math Mutator + wird zu - * wird zu / Negate Conditionals Mutator == wird zu != <= wird zu > Conditionals Boundary Mutator < wird zu <= <= wird zu < Invert Negs Mutator -i wird zu i Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 28 Default Mutatoren

Slide 29

Slide 29 text

Increments Mutator i++ wird zu i-- Math Mutator + wird zu - * wird zu / Negate Conditionals Mutator == wird zu != <= wird zu > Conditionals Boundary Mutator < wird zu <= <= wird zu < Invert Negs Mutator -i wird zu i Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 29 Default Mutatoren

Slide 30

Slide 30 text

Increments Mutator i++ wird zu i-- Math Mutator + wird zu - * wird zu / Negate Conditionals Mutator == wird zu != <= wird zu > Conditionals Boundary Mutator < wird zu <= <= wird zu < Invert Negs Mutator -i wird zu i Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 30 Default Mutatoren

Slide 31

Slide 31 text

Increments Mutator i++ wird zu i-- Math Mutator + wird zu - * wird zu / Negate Conditionals Mutator == wird zu != <= wird zu > Conditionals Boundary Mutator < wird zu <= <= wird zu < Invert Negs Mutator -i wird zu i Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 31 Default Mutatoren

Slide 32

Slide 32 text

Increments Mutator i++ wird zu i-- Math Mutator + wird zu - * wird zu / Negate Conditionals Mutator == wird zu != <= wird zu > Conditionals Boundary Mutator < wird zu <= <= wird zu < Invert Negs Mutator -i wird zu i Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 32 Default Mutatoren

Slide 33

Slide 33 text

public Object foo() { return new Object(); } Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 33 Code Smells finden mit dem Return Values Mutator public Object foo() { new Object(); return null; }

Slide 34

Slide 34 text

public Object foo() { return new Object(); } Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 34 Code Smells finden mit dem Return Values Mutator public Object foo() { new Object(); return null; }

Slide 35

Slide 35 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 35 Dead Code finden mit dem Void Method Call Mutator public List sort(List coll) { List list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com

Slide 36

Slide 36 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 36 Äquivalente Mutationen public int calc(int i) { if (i == 0) { return 0; } if (i <= 2) { return 1; } return calc(i-1) + calc(i-2); } def "test fibonacci generator"() { given: "fibonacci generator" Fibonacci fib = new Fibonacci() when: "calc sequence for input #i" def result = fib.calc(i) then: "expected number is returned" result == expected where: i || expected 0 || 0 2 || 1 11 || 89 } i < 2 Icons made by Sprang from www.flaticon.com

Slide 37

Slide 37 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 37 Warum PIT? Schnell durch Parallelisierung Arbeitet auf Bytecode Lesbare Reports Tooling

Slide 38

Slide 38 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 38

Slide 39

Slide 39 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 39 Mutationstesten – im größeren Team Icons made by Sprang from www.flaticon.com

Slide 40

Slide 40 text

Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 40 Mutationstesten – im größeren Team Icons made by Sprang from www.flaticon.com

Slide 41

Slide 41 text

41

Slide 42

Slide 42 text

42

Slide 43

Slide 43 text

43

Slide 44

Slide 44 text

Welche zwei Fragen sind noch offen? Johannes.Dienst@DeutscheBahn.com @JohannesDienst Ralf.D.Mueller@DeutscheBahn.com @RalfDMueller

Slide 45

Slide 45 text

DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst 45 https://jaxenter.de/mutant-testing-pit-java-84437 https://m.heise.de/developer/artikel/Mutationstests-mit-PIT-in- Java-3888683.html?seite=all