Spock vs Supermutanten: Spezifikationstesten trifft Mutationstesten

Johannes Dienst
Johannes DienstSoftwarearchitect / Clean Coder um DB Systel GmbH
Ralf D. Müller @RalfDMueller Johannes Dienst @JohannesDienst
Spock vs Supermutanten
Spezifikationstesten trifft auf Mutationstesten
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
Was ist Spock?
Was ist Spock?
3
Leonard
Brüning
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
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
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
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
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
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
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, fib.calc(0));
}
void "test the fibonacci generator with input 1" {
assertEquals(1, fib.calc(1));
}
// …
Developer
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
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, fib.calc(0));
}
void "test the fibonacci generator with input 1" {
assertEquals(1, fib.calc(1));
}
// …
Developer
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
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, 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
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 == expected
}
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
Was ist Spock?
13
void "test the fibonacci generator with input 0"() {
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
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst14
Reports
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst15
Reports
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst16
Reports
Product
Owner
Developer
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst17
100%
Zeilenabdeckung?
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst18
100%
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst19
Finde den Fehler?
public List<Integer> sort(List<Integer> coll) {
List<Integer> list = new ArrayList<>(coll);
Collections.sort(list);
log(list);
return Collections.unmodifiableList(list);
}
public void log(List<Integer> list) {
System.out.println(
list.stream().map(Object::toString)
.collect(Collectors.joining(", ")));
}
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst20
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
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst21
Finde den Fehler?
public List<Integer> sort(List<Integer> coll) {
List<Integer> list = new ArrayList<>(coll);
Collections.sort(list);
log(list);
return Collections.unmodifiableList(list);
}
public void log(List<Integer> list) {
System.out.println(
list.stream().map(Object::toString)
.collect(Collectors.joining(", ")));
}
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst22
Und nun?
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst23
Fehler gezielt provozieren
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst24
Automatisierung
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst25
Mutationstesten
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst26
Mutationstesten - Funktionsweise
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst27
DEMO HTML
Report
Icons made by Sprang from www.flaticon.com
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 @JohannesDienst28
Default Mutatoren
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 @JohannesDienst29
Default Mutatoren
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 @JohannesDienst30
Default Mutatoren
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 @JohannesDienst31
Default Mutatoren
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 @JohannesDienst32
Default Mutatoren
public Object foo() {
return new Object();
}
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst33
Code Smells finden mit dem Return Values Mutator
public Object foo() {
new Object();
return null;
}
public Object foo() {
return new Object();
}
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst34
Code Smells finden mit dem Return Values Mutator
public Object foo() {
new Object();
return null;
}
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst35
Dead Code finden mit dem Void Method Call Mutator
public List<Integer> sort(List<Integer> coll) {
List<Integer> list = new ArrayList<>(coll);
Collections.sort(list);
log(list);
return Collections.unmodifiableList(list);
}
public void log(List<Integer> list) {
System.out.println(
list.stream().map(Object::toString)
.collect(Collectors.joining(", ")));
}
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst36
Ä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
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst37
Warum PIT?
Schnell durch
Parallelisierung
Arbeitet auf
Bytecode
Lesbare
Reports
Tooling
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst38
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst39
Mutationstesten – im größeren Team
Icons made by Sprang from www.flaticon.com
Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst40
Mutationstesten – im größeren Team
Icons made by Sprang from www.flaticon.com
41
42
43
Welche zwei Fragen sind noch offen?
Johannes.Dienst@DeutscheBahn.com
@JohannesDienst
Ralf.D.Mueller@DeutscheBahn.com
@RalfDMueller
DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst45
https://jaxenter.de/mutant-testing-pit-java-84437
https://m.heise.de/developer/artikel/Mutationstests-mit-PIT-in-
Java-3888683.html?seite=all
1 von 45

Recomendados

Real Cross-Platform Workflow UI Automation_JohannesDienst.pdf von
Real Cross-Platform Workflow UI Automation_JohannesDienst.pdfReal Cross-Platform Workflow UI Automation_JohannesDienst.pdf
Real Cross-Platform Workflow UI Automation_JohannesDienst.pdfJohannes Dienst
11 views19 Folien
The Future of UI Testing - Challenges in UI Automation von
The Future of UI Testing - Challenges in UI AutomationThe Future of UI Testing - Challenges in UI Automation
The Future of UI Testing - Challenges in UI AutomationJohannes Dienst
170 views23 Folien
Rock Solid Software Architecture with ADRs, arc42 and Microsites von
Rock Solid Software Architecture with ADRs, arc42 and MicrositesRock Solid Software Architecture with ADRs, arc42 and Microsites
Rock Solid Software Architecture with ADRs, arc42 and MicrositesJohannes Dienst
202 views27 Folien
Stoizismus - Praktische Philosophie für den IT-Alltag (Pecha Kucha) von
Stoizismus - Praktische Philosophie für den IT-Alltag (Pecha Kucha)Stoizismus - Praktische Philosophie für den IT-Alltag (Pecha Kucha)
Stoizismus - Praktische Philosophie für den IT-Alltag (Pecha Kucha)Johannes Dienst
287 views20 Folien
Von Managed-Cloud zu GitOps - Multi Client-Cluster Deployments von
Von Managed-Cloud zu GitOps - Multi Client-Cluster DeploymentsVon Managed-Cloud zu GitOps - Multi Client-Cluster Deployments
Von Managed-Cloud zu GitOps - Multi Client-Cluster DeploymentsJohannes Dienst
133 views24 Folien
Managed Cloud to GitOps: Deploying Several Client Clusters von
Managed Cloud to GitOps: Deploying Several Client ClustersManaged Cloud to GitOps: Deploying Several Client Clusters
Managed Cloud to GitOps: Deploying Several Client ClustersJohannes Dienst
463 views14 Folien

Más contenido relacionado

Más de Johannes Dienst

Lessons Learned: arc42 in einem echten DevOps Team von
Lessons Learned: arc42 in einem echten DevOps TeamLessons Learned: arc42 in einem echten DevOps Team
Lessons Learned: arc42 in einem echten DevOps TeamJohannes Dienst
362 views29 Folien
Work efficiently with Architecture Decision Records von
Work efficiently with Architecture Decision RecordsWork efficiently with Architecture Decision Records
Work efficiently with Architecture Decision RecordsJohannes Dienst
220 views31 Folien
The Dev, The Ops, And The Team: What works in a DevOps Team? von
The Dev, The Ops, And The Team: What works in a DevOps Team?The Dev, The Ops, And The Team: What works in a DevOps Team?
The Dev, The Ops, And The Team: What works in a DevOps Team?Johannes Dienst
155 views27 Folien
Effizient arbeiten mit Architecture Decision Records (ADR) von
Effizient arbeiten mit Architecture Decision Records (ADR)Effizient arbeiten mit Architecture Decision Records (ADR)
Effizient arbeiten mit Architecture Decision Records (ADR)Johannes Dienst
338 views28 Folien
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu... von
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Johannes Dienst
163 views27 Folien
Everything as Code: Pipeline, Infrastructure, Configuration, Documentation von
Everything as Code: Pipeline, Infrastructure, Configuration, DocumentationEverything as Code: Pipeline, Infrastructure, Configuration, Documentation
Everything as Code: Pipeline, Infrastructure, Configuration, DocumentationJohannes Dienst
311 views32 Folien

Más de Johannes Dienst(16)

Lessons Learned: arc42 in einem echten DevOps Team von Johannes Dienst
Lessons Learned: arc42 in einem echten DevOps TeamLessons Learned: arc42 in einem echten DevOps Team
Lessons Learned: arc42 in einem echten DevOps Team
Johannes Dienst362 views
Work efficiently with Architecture Decision Records von Johannes Dienst
Work efficiently with Architecture Decision RecordsWork efficiently with Architecture Decision Records
Work efficiently with Architecture Decision Records
Johannes Dienst220 views
The Dev, The Ops, And The Team: What works in a DevOps Team? von Johannes Dienst
The Dev, The Ops, And The Team: What works in a DevOps Team?The Dev, The Ops, And The Team: What works in a DevOps Team?
The Dev, The Ops, And The Team: What works in a DevOps Team?
Johannes Dienst155 views
Effizient arbeiten mit Architecture Decision Records (ADR) von Johannes Dienst
Effizient arbeiten mit Architecture Decision Records (ADR)Effizient arbeiten mit Architecture Decision Records (ADR)
Effizient arbeiten mit Architecture Decision Records (ADR)
Johannes Dienst338 views
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu... von Johannes Dienst
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Johannes Dienst163 views
Everything as Code: Pipeline, Infrastructure, Configuration, Documentation von Johannes Dienst
Everything as Code: Pipeline, Infrastructure, Configuration, DocumentationEverything as Code: Pipeline, Infrastructure, Configuration, Documentation
Everything as Code: Pipeline, Infrastructure, Configuration, Documentation
Johannes Dienst311 views
DevOps im Konzern - Autonomie vs Betriebssicherheit (Continuous Lifecycle) von Johannes Dienst
DevOps im Konzern - Autonomie vs Betriebssicherheit (Continuous Lifecycle)DevOps im Konzern - Autonomie vs Betriebssicherheit (Continuous Lifecycle)
DevOps im Konzern - Autonomie vs Betriebssicherheit (Continuous Lifecycle)
Johannes Dienst823 views
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu... von Johannes Dienst
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Johannes Dienst472 views
Pride & Prejudice: Teambildung & Motivation im agilen Umfeld von Johannes Dienst
Pride & Prejudice: Teambildung & Motivation im agilen UmfeldPride & Prejudice: Teambildung & Motivation im agilen Umfeld
Pride & Prejudice: Teambildung & Motivation im agilen Umfeld
Johannes Dienst345 views
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu... von Johannes Dienst
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Johannes Dienst509 views
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu... von Johannes Dienst
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Leichtgewichtige Softwarearchitektur mit Architecture Decision Records und Qu...
Johannes Dienst744 views
DevOps im Konzern: Autonomie vs Betriebssicherheit von Johannes Dienst
DevOps im Konzern: Autonomie vs BetriebssicherheitDevOps im Konzern: Autonomie vs Betriebssicherheit
DevOps im Konzern: Autonomie vs Betriebssicherheit
Johannes Dienst349 views
Und wer testet die Tests? - Mutationstesten mit PIT von Johannes Dienst
Und wer testet die Tests? - Mutationstesten mit PITUnd wer testet die Tests? - Mutationstesten mit PIT
Und wer testet die Tests? - Mutationstesten mit PIT
Johannes Dienst125 views
Type Script 3.x - Was war. Was kommt! von Johannes Dienst
Type Script 3.x - Was war. Was kommt!Type Script 3.x - Was war. Was kommt!
Type Script 3.x - Was war. Was kommt!
Johannes Dienst53 views
Ist das Softwarearchitektur oder kann das weg? von Johannes Dienst
Ist das Softwarearchitektur oder kann das weg?Ist das Softwarearchitektur oder kann das weg?
Ist das Softwarearchitektur oder kann das weg?
Johannes Dienst158 views
Clean Code ist doch einfach... Qualität ist schwierig! von Johannes Dienst
Clean Code ist doch einfach... Qualität ist schwierig!Clean Code ist doch einfach... Qualität ist schwierig!
Clean Code ist doch einfach... Qualität ist schwierig!
Johannes Dienst203 views

Spock vs Supermutanten: Spezifikationstesten trifft Mutationstesten

  • 1. Ralf D. Müller @RalfDMueller Johannes Dienst @JohannesDienst Spock vs Supermutanten Spezifikationstesten trifft auf Mutationstesten
  • 2. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst Was ist Spock?
  • 3. Was ist Spock? 3 Leonard Brüning Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. 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
  • 8. 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
  • 9. 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, fib.calc(0)); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
  • 10. 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, fib.calc(0)); } void "test the fibonacci generator with input 1" { assertEquals(1, fib.calc(1)); } // … Developer Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst
  • 11. 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, 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
  • 12. 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 == expected } 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
  • 13. Was ist Spock? 13 void "test the fibonacci generator with input 0"() { 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
  • 14. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst14 Reports
  • 15. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst15 Reports
  • 16. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst16 Reports Product Owner Developer
  • 17. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst17 100% Zeilenabdeckung?
  • 18. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst18 100% Icons made by Sprang from www.flaticon.com
  • 19. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst19 Finde den Fehler? public List<Integer> sort(List<Integer> coll) { List<Integer> list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List<Integer> list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com
  • 20. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst20 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
  • 21. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst21 Finde den Fehler? public List<Integer> sort(List<Integer> coll) { List<Integer> list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List<Integer> list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com
  • 22. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst22 Und nun? Icons made by Sprang from www.flaticon.com
  • 23. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst23 Fehler gezielt provozieren Icons made by Sprang from www.flaticon.com
  • 24. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst24 Automatisierung Icons made by Sprang from www.flaticon.com
  • 25. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst25 Mutationstesten Icons made by Sprang from www.flaticon.com
  • 26. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst26 Mutationstesten - Funktionsweise Icons made by Sprang from www.flaticon.com
  • 27. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst27 DEMO HTML Report Icons made by Sprang from www.flaticon.com
  • 28. 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 @JohannesDienst28 Default Mutatoren
  • 29. 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 @JohannesDienst29 Default Mutatoren
  • 30. 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 @JohannesDienst30 Default Mutatoren
  • 31. 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 @JohannesDienst31 Default Mutatoren
  • 32. 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 @JohannesDienst32 Default Mutatoren
  • 33. public Object foo() { return new Object(); } Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst33 Code Smells finden mit dem Return Values Mutator public Object foo() { new Object(); return null; }
  • 34. public Object foo() { return new Object(); } Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst34 Code Smells finden mit dem Return Values Mutator public Object foo() { new Object(); return null; }
  • 35. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst35 Dead Code finden mit dem Void Method Call Mutator public List<Integer> sort(List<Integer> coll) { List<Integer> list = new ArrayList<>(coll); Collections.sort(list); log(list); return Collections.unmodifiableList(list); } public void log(List<Integer> list) { System.out.println( list.stream().map(Object::toString) .collect(Collectors.joining(", "))); } Icons made by Sprang from www.flaticon.com
  • 36. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst36 Ä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
  • 37. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst37 Warum PIT? Schnell durch Parallelisierung Arbeitet auf Bytecode Lesbare Reports Tooling
  • 38. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst38
  • 39. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst39 Mutationstesten – im größeren Team Icons made by Sprang from www.flaticon.com
  • 40. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst40 Mutationstesten – im größeren Team Icons made by Sprang from www.flaticon.com
  • 41. 41
  • 42. 42
  • 43. 43
  • 44. Welche zwei Fragen sind noch offen? Johannes.Dienst@DeutscheBahn.com @JohannesDienst Ralf.D.Mueller@DeutscheBahn.com @RalfDMueller
  • 45. DB Systel. Digital bewegen. Gemeinsam. Ralf D. Müller @RalfDMueller und Johannes Dienst @JohannesDienst45 https://jaxenter.de/mutant-testing-pit-java-84437 https://m.heise.de/developer/artikel/Mutationstests-mit-PIT-in- Java-3888683.html?seite=all