Transcript
Page 1: ALE2014 let tests drive or let dijkstra derive

Let tests drive orlet Dijkstra derive?

Sander Kooijmans

ALE 2014

Page 2: ALE2014 let tests drive or let dijkstra derive

Who is Sander Kooijmans?

www.hightechict.nl

[email protected]

www.gogognome.nl

Page 3: ALE2014 let tests drive or let dijkstra derive

Why this presentation?

• TDD is currently hyped

• Many TDD trainers say• You are not a serious programmer if you do not use TDD

• The only way to write correct programs is using TDD

• Uncle Bob (Robert Martin) says• Applying TDD and transformations may be a formal proof of

correctness (still to be proven)

Page 4: ALE2014 let tests drive or let dijkstra derive

Why this presentation?

• TDD is currently hyped

• Many TDD trainers say• You are not a serious programmer if you do not use TDD

• The only way to write correct programs is using TDD

• Uncle Bob (Robert Martin) says• Applying TDD and transformations may be a formal proof of

correctness (still to be proven)

http://blog.8thlight.com/uncle-bob/2013/05/27/TheTransformationPriorityPremise.htmlhttp://blog.8thlight.com/uncle-bob/2014/05/02/ProfessionalismAndTDD.html http://cleancoders.com/episode/clean-code-episode-6-p2/show

Page 5: ALE2014 let tests drive or let dijkstra derive

My experience with TDD

Page 6: ALE2014 let tests drive or let dijkstra derive

My experience with tests

Tests require clean code

Page 7: ALE2014 let tests drive or let dijkstra derive

My experience with tests

• Tests protect against accidental modification of existing behavior• When adding new functionality

• When refactoring existing functionality

Page 8: ALE2014 let tests drive or let dijkstra derive

My experience with tests

Tests are examples of how production code must be used

Page 9: ALE2014 let tests drive or let dijkstra derive

My experience with tests

Tests as specification

Page 10: ALE2014 let tests drive or let dijkstra derive

My experience with tests

Writing tests first helps to clarify specifications

Page 11: ALE2014 let tests drive or let dijkstra derive

My experience with tests

I don’t dare to deliver production code without tests!

Page 12: ALE2014 let tests drive or let dijkstra derive

The Prime Factors Kata by Uncle Bobpackage primeFactors;

import static primeFactors.PrimeFactors.generate;

import junit.framework.TestCase;

import java.util.*;

public class PrimeFactorsTest extends TestCase {

private List<Integer> list(int... ints) {

List<Integer> list = new ArrayList<Integer>();

for (int i : ints)

list.add(i);

return list;

}

public void testOne() throws Exception {

assertEquals(list(),generate(1));

}

public void testTwo() throws Exception {

assertEquals(list(2),generate(2));

}

public void testThree() throws Exception {

assertEquals(list(3),generate(3));

}

public void testFour() throws Exception {

assertEquals(list(2,2),generate(4));

}

public void testSix() throws Exception {

assertEquals(list(2,3),generate(6));

}

public void testEight() throws Exception {

assertEquals(list(2,2,2),generate(8));

}

public void testNine() throws Exception {

assertEquals(list(3,3),generate(9));

}

}

package primeFactors;

import java.util.*;

public class PrimeFactors {

public static List<Integer> generate(int n) {

List<Integer> primes = new ArrayList<Integer>();

for (int candidate = 2; n > 1; candidate++)

for (; n%candidate == 0; n/=candidate)

primes.add(candidate);

return primes;

}

}

The algorithm is three lines of code!

http://butunclebob.com/files/downloads/Prime%20Factors%20Kata.ppt

Page 13: ALE2014 let tests drive or let dijkstra derive

Edsger Wybe Dijkstra (1930-2002)

“Program testing can be used to show the presence of bugs,

but never to show their absence!”

Page 14: ALE2014 let tests drive or let dijkstra derive

Edsger Wybe Dijkstra

Page 15: ALE2014 let tests drive or let dijkstra derive

Edsger Wybe Dijkstra

program derivation: to “develop proof and program hand in hand”

Page 16: ALE2014 let tests drive or let dijkstra derive

PredicatesAll variables of your program int i=0; int j=100;

After execution these predicates hold:P(i,j) Î i==0Q(i,j) Î i<jR(i,j) Î i==0 && j==100

For brevity we write

R Î i==0 && j==100

true or false

Page 17: ALE2014 let tests drive or let dijkstra derive

Hoare triple

The Hoare triple {Pre} S {Post} means:When Pre holds and S is executed

then if S terminates Post holds

In the Java code samples I use this notation:

Page 18: ALE2014 let tests drive or let dijkstra derive

Assignment

{Pre} x = E {Post} is equivalent to Pre Á Post(x:=E)

Let us prove

{x == 5} x = x+3 {x > 7}

(x > 7)(x:=x+3)Î { substitution }

x+3 > 7Î { calculus }

x > 4Ë { precondition }

x == 5

Page 19: ALE2014 let tests drive or let dijkstra derive

Assignment

{Pre} x = E {Post} is equivalent to Pre Á Post(x:=E)

And another proof. In this case Pre is equivalent to Post(x:=E).

{x == 40} x = x+2 {x == 42}

(x == 42)(x:=x+2)Î { substitution }

x+2 == 42Î { arithmetic }

x == 40

Page 20: ALE2014 let tests drive or let dijkstra derive

If-statement

{Pre} if (B) S else T {Post} is equivalent to:

{Pre && B} S {Post} and {Pre && !B} T {Post}

Let us prove

{true} if (y>=x) u=y else u=x {u == max(x,y)}

Page 21: ALE2014 let tests drive or let dijkstra derive

If-statement {Pre && B} S {Post}

We use the following definition of max in our proofu=max(x,y) Î (u==x || u==y) && u>=x && u>=y

{true} if (y>=x) u=y else u=x {u == max(x,y)}

(u == max(x,y))(u:=y)Î { substitution }

y == max(x,y)Î { definition of max }

(y==x || y==y) && y>=x && y>=yÎ { calculus }

y >= x

Page 22: ALE2014 let tests drive or let dijkstra derive

If-statement {Pre && !B} T {Post}

{true} if (y>=x) u=y else u=x {u == max(x,y)}

(u == max(x,y))(u:=x)Î { substitution }

x == max(x,y)Î { definition of max }(x==x || x==y) && x>=x && x>=y

Î { calculus }x >= y

Ë { calculus }y < x

Î { calculus }!(y>=x)

Page 23: ALE2014 let tests drive or let dijkstra derive

While-loop

{Inv} while (B) S {Post} follows from• {Inv && B} S {Inv}• Inv && !B Á Post• Provided that the loop terminates

Inv is called an invariant

Page 24: ALE2014 let tests drive or let dijkstra derive

Termination of a while-loop

Termination is proved using a bound function• A bound function decreases with at least one each iteration

• The bound function is bounded from below

Page 25: ALE2014 let tests drive or let dijkstra derive

While-loop

Let us prove

Page 26: ALE2014 let tests drive or let dijkstra derive

While-loop

Let us prove

Proof for {Inv && B} S {Inv}

(p * 2n == 2originalN)(p:=2*p)(n:=n-1)Î { substitutions }(2*p * 2n-1 == 2originalN)

Î { calculus }p * 2n == 2originalN

Î { definitionof invariant }true

Page 27: ALE2014 let tests drive or let dijkstra derive

While-loop

Let us prove

Page 28: ALE2014 let tests drive or let dijkstra derive

While-loop

Let us prove

Proof for {Inv && B} S {Inv}

(sum == 1 + 2 + … + p)(p:=p+1)(sum := sum+p+1)Î { substitution p := p+1 }(sum == 1 + 2 + … + p + (p+1))(sum := sum+p+1)

Î { substitution sum := sum + p+1}sum + (p+1) == 1 + 2 + … + p + (p+1)

Î { use invariant sum = 1 + 2 + … + p }sum + (p+1) == sum + (p+1)

Î { calculus }true

Page 29: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

Page 30: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

originalN == 140

Page 31: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

Page 32: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

originalN == 180

Page 33: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

Page 34: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

Page 35: ALE2014 let tests drive or let dijkstra derive

Deriving a solution to the Prime Factors Kata

Page 36: ALE2014 let tests drive or let dijkstra derive

Deriving an alternate solution

Page 37: ALE2014 let tests drive or let dijkstra derive

Deriving an alternate solution

Page 38: ALE2014 let tests drive or let dijkstra derive

The Prime Factors Kata by Uncle Bob

The algorithm is three lines of code!

Page 39: ALE2014 let tests drive or let dijkstra derive

Conclusions

• There is no guarantee that TDD results in correct code

• Deriving and proving an algorithm can go hand in hand

• TDD and formal proofs are tools, not goals

• The goal is correct code

• Tests help to keep the code correct

Page 40: ALE2014 let tests drive or let dijkstra derive

Questions?

www.hightechict.nl

[email protected]

www.gogognome.nl


Recommended