Ontdek de 7 verschillen

40
Inleiding Software Engineering Inleiding Software Engineering Universiteit Antwerpen Betrouwbaarheid 2.1 Ontdek de 7 verschillen

description

Ontdek de 7 verschillen. Een oplossing met een foutje …. 2. Betrouwbaarheid. Software Engineering Wat? Bouw vs. Ontwikkel Vereisten Betrouwbaarheid (Aanpasbaarheid & Planning) Betrouwbaarheid: TicTacToe specificatie versie 1.0: ontwerp, implementatie & test - PowerPoint PPT Presentation

Transcript of Ontdek de 7 verschillen

Page 1: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.1

Ontdek de 7 verschillen

Page 2: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.2

Een oplossing met een foutje …

Page 3: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.3

2. Betrouwbaarheid• Software Engineering

– Wat?– Bouw vs. Ontwikkel– Vereisten

• Betrouwbaarheid• (Aanpasbaarheid & Planning)

• Betrouwbaarheid: TicTacToe– specificatie– versie 1.0: ontwerp, implementatie & test– versie 1.1a: ontwerp, implementatie

met slechte test (manuele controle)– versie 1.1a en 1.1: contracten

Page 4: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.4

Wat is Software Engineering ?

Specificatie Systeem

"Multi-person construction of multi-version software"– Ploegwerk– Evolueren of ... uitsterven

Page 5: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.5

"Bouw" een systeem

• Monolithische systemen– banken, verzekeringen,

loonberekening• Programmeerploeg: stricte

functie-opdeling– Analist, programmeur, ...

• Organisatie in functie van systeem– Organisatie past zich aan

Page 6: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.6

"Ontwikkel" een systeem

• Modulaire systemen– “desktop” systemen, web-applicaties

• Programmeerploeg: losse functie-opdeling– Analist + programmeur, ...

• Systeem in functie van organisatie– Systeem past zich aan

Page 7: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.7

Vereisten

Vereisten• Betrouwbaarheid• Aanpasbaarheid• Planning

Technieken• Testen + Contracten• Objectgericht ontwerp• Tijdsschatting

Page 8: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.8

play

player

TicTacToe: SpecificatieUse Case 1: play• Goal: 2 players play TicTacToe,

1 should win• Precondition: An empty 3x3 board• Success end: 1 player is the winnerSteps1. Two players start up a game

(First is "O"; other is "X")2. WHILE game not done

2.1 Current player makes move2.2 Switch current player

3. Anounce winner

Page 9: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.9

Vuistregel

Keep It Stupidly Simple(the KISS principle)

Hoe ?• Begin zo klein mogelijk

=> laat ontwerp & implementatie langzaam groeien

Waarom ?"There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies, and the other way is make it so complicated that there are no obvious deficiencies."

(C. A. R. Hoare - Turing Award Lecture)

Page 10: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.10

TTT1.0: Ontwerp

TicTacToenotDone(): BOOLEANdoMove()

t: TicTacToeaGame

play*[t.notDone()]

doMove ()

TYPETicTacToe* = POINTER TO

TicTacToeData;

PROCEDURE (aTicTacToe: TicTacToe)notDone* (): BOOLEAN;

PROCEDURE (aTicTacToe: TicTacToe)doMove* (): BOOLEAN;

WHILE t.notDone() DOt.doMove();

END;

klein ontwerp: een lus

Page 11: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.11

TYPETicTacToe* = POINTER TO TicTacToeData;TicTacToeData* = RECORD

nrOfMoves: INTEGER;END;

PROCEDURE (aTicTacToe: TicTacToe) init*;

BEGINaTicTacToe.nrOfMoves

:= 0;END init;

PROCEDURE (aTicTacToe: TicTacToe) notDone* (): BOOLEAN;BEGIN

RETURN aTicTacToe.nrOfMoves

< 9;END notDone;

PROCEDURE (aTicTacToe: TicTacToe) doMove* ();BEGIN

aTicTacToe.nrOfMoves :=

aTicTacToe.nrOfMoves + 1;END doMove;

kleine implementatie:een teller

Page 12: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.12

Vuistregel

Minstens één test per "normaal" scenario

Waarom ?• Minimum veiligheidsnormHoe ?• Controleer de tussentijdse toestand via "should" & "shouldNot"

=> onthoud of een test gelukt is of niet

Page 13: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.13

TTT1.0: Test

TicTacToeTestsetUp(testCase:

ARRAY OF CHAR)run()tearDown()should (…): BOOLEANshouldNot (…): BOOLEANtestBasicGame(): BOOLEAN

aGame: TicTacToe: TicTacToeTest

testBasicGame()

*[aGame.notDone()]doMove ()

setUp("testBasicGame")

should(aGame.notDone())

shouldNot(aGame.notDone())

tearDown()

NEW(); init();

should(aGame.nrOfMoves() =9)

Page 14: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.14

PROCEDURE (aTest: TicTacToeTest) testBasicGame*(verbose: BOOLEAN): BOOLEAN;

BEGINIF verbose THEN Out.String(aTest.testCase); Out.Ln; END;IF ~ aTest.should(aTest.aGame.notDone(),

"notDone is FALSE at beginning of game") THEN RETURN FALSE; END;

WHILE aTest.aGame.notDone() DOaTest.aGame.doMove();

END;IF verbose THEN Out.String("... at the end of the loop"); Out.Ln; END;IF ~ aTest.shouldNot(aTest.aGame.notDone(),

"notDone is TRUE at the end of game") THEN RETURN FALSE; END;

IF ~ aTest.should(aTest.aGame.numberOfMoves() = 9,"number of moves at end of game is <> 9") THEN RETURN

FALSE; END;RETURN TRUE;

END testBasicGame;

Controleer tussen-tijdse toestand

Page 15: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.15

PROCEDURE (aTest: TicTacToeTest) fail (MSG: ARRAY OF CHAR);BEGIN

Out.String("Failure: "); Out.String(aTest.testCase);Out.String(" - "); Out.String(MSG); Out.Ln();

END fail;

PROCEDURE (aTest: TicTacToeTest) should (b : BOOLEAN; MSG: ARRAY OF CHAR): BOOLEAN;BEGIN

IF ~ b THEN aTest.fail(MSG); END; RETURN b;END should;

PROCEDURE (aTest: TicTacToeTest) shouldNot (b : BOOLEAN; MSG: ARRAY OF CHAR): BOOLEAN;BEGIN

IF b THEN aTest.fail(MSG); END; RETURN ~ b;END shouldNot;

Page 16: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.16

PROCEDURE Main*;VAR testsPassed: BOOLEAN; aTest: TicTacToeTest;

BEGINNEW(aTest); aTest.init();testsPassed := TRUE (* assume that tests will pass *);aTest.setUp("testBasicGame");IF ~ aTest.testBasicGame (TRUE) THEN testsPassed := FALSE; END;aTest.tearDown();(* -- add more test case invocations before this line -- *)IF testsPassed THEN

Out.String("TicTacToeTest: All tests passed"); Out.Ln();ELSE

Out.String("TicTacToeTest: *** At least one test failed"); Out.Ln();END;

END Main;Onthoud testresultaat!

Page 17: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.17

TTT1.1a: doMovet: TicTacToe

doMove()

TicTacToe- nrOfMoves: Integer: 0

+ doMove()+ notDone(): BOOLEAN+ setMark (col, row,

marker: CHAR)+ getMark (col, row:

CHAR): CHAR

[ODD(t.nrOfMoves)] setMark(CHR((t.nrOfMoves MOD 3) + ORD("a")),CHR((t.nrOfMoves DIV 3) + ORD("1")),"X")

[~ODD(t.nrOfMoves)] setMark(CHR((t.nrOfMoves MOD 3) + ORD("a")),CHR((t.nrOfMoves DIV 3) + ORD("1")),"O")

a b c1 O X O2 X O X3 O X O

nrOfMoves := nrOfMoves + 1

Page 18: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.18

PROCEDURE (aTicTacToe: TicTacToe) doMove* ();VAR row, col, mark: CHAR;BEGIN

col := CHR((aTicTacToe.nrOfMoves MOD 3) + ORD("a"));row:= CHR((aTicTacToe.nrOfMoves DIV 3) + ORD("1"));IF ODD(aTicTacToe.nrOfMoves) THEN

mark := "X" ELSE mark := "O"; END;aTicTacToe.setMark(col, row, mark);aTicTacToe.nrOfMoves := aTicTacToe.nrOfMoves + 1;

END doMove;

Ontwerp & Implementatiegroeien langzaam

Page 19: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.19

Vuistregel

Als de functionaliteit groeit,dan groeit de test mee

Waarom ?• Veiligheidsmaatregel: gecontroleerde groeiHoe ?• Pas bestaande tests aan

=> extra tussentijds toestanden controleren

Page 20: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.20

TTT1.1a: Test

t: TicTacToeTest

mark := getMark(col, row)

t: TicTacToe

*[col := "a" .. "c";row := "1" .."3"]

should(mark = expectedMark)

[expectedMarker = "X"] expectedMark := "O"

[expectedMarker = "O"] expectedMark := "X"

Page 21: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.21

PROCEDURE (aTest: TicTacToeTest) testBasicGame* (verbose: BOOLEAN): BOOLEAN;

...WHILE aTest.aGame.notDone() DO aTest.aGame.doMove(); END;expectedMark := "O";FOR col := ORD("a") TO ORD("c") DO

FOR row := ORD("1") TO ORD("3") DOIF verbose THEN ... END;mark := aTest.aGame.getMark(CHR(col), CHR(row));IF ~ aTest.should(mark = expectedMark,

"mark is not what expected") THEN RETURN FALSE; END;

IF expectedMark = "X"THEN expectedMark := "O" ELSE

expectedMark := "X"; END;END;

END;...

Test groeit mee

Page 22: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.22

Vuistregel

Een test produceert zo weinig mogelijk uitvoer

• "all tests passed"• "at least one test failed"

Waarom ?• Veel en frequent testen => onmogelijk om uitvoer te controlerenHoe dan wel ?• Tests antwoorden "all tests passed" of "at least one test failed"• Tests werken normaal in "silent mode" maar er is ook "verbose"

Page 23: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.23

PROCEDURE (aTest: TicTacToeTestBad) testBasicGame*;…

Out.String("BEGIN OF GAME: aGame.notDone() = "); IF aTest.aGame.notDone() THEN Out.String("TRUE");

ELSE Out.String("FALSE"); END; Out.Ln;WHILE aTest.aGame.notDone() DO aTest.aGame.doMove(); END;mark := "O";FOR col := ORD("a") TO ORD("c") DO

FOR row := ORD("1") TO ORD("3") DOOut.Char(CHR(col));

Out.Char("-");Out.Char(CHR(row));Out.Char(":");Out.Char(aTest.aGame.getMark(CHR(col), CHR(row)));Out.String(" =? "); Out.Char(mark);Out.Ln;IF mark = "X" THEN mark := "O" ELSE mark := "X"; END;

END; END;…

Out.String("END OF GAME: aGame.numberOfMoves() = "); Out.Int(aTest.aGame.numberOfMoves(), 0); Out.Ln;

Een slechte test

Page 24: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.24

De vorige testcode produceert volgende uitvoer

BEGIN OF GAME: aGame.notDone() = TRUEa-1:O =? Oa-2:X =? Xa-3:O =? Ob-1:X =? Xb-2:O =? Ob-3:X =? Xc-1:O =? Oc-2:X =? Xc-3:O =? OEND OF GAME: aGame.notDone() = FALSEEND OF GAME: aGame.numberOfMoves() = 9

Hoe weet ik ofdeze uitvoercorrect is ?

Manuele Verificatie van Tests

Schrijf *nooit* testcode die

manuele verificatie van de uitvoer

vereist

Page 25: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.25

PROCEDURE (aTest: TicTacToeTest) testBasicGame*(verbose: BOOLEAN): BOOLEAN;

BEGINIF verbose THEN Out.String(aTest.testCase); Out.Ln; END;IF ~ aTest.should(aTest.aGame.notDone(),

"notDone is FALSE at beginning of game") THEN RETURN FALSE; END;

WHILE aTest.aGame.notDone() DOaTest.aGame.doMove();

END;IF verbose THEN Out.String("... at the end of the loop"); Out.Ln; END;IF ~ aTest.shouldNot(aTest.aGame.notDone(),

"notDone is TRUE at the end of game") THEN RETURN FALSE; END;

IF ~ aTest.should(aTest.aGame.numberOfMoves() = 9,"number of moves at end of game is <> 9") THEN RETURN

FALSE; END;RETURN TRUE;

END testBasicGame;

Alleen uitvoer ingeval van "verbose"

Page 26: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.26

TTT1.1a: Klasse InterfaceTicTacToe

- nrOfMoves: Integer: 0

+ doMove()+ notDone(): BOOLEAN+ setMark (col, row, marker: CHAR)+ getMark (col, row: CHAR): CHAR

Zijn alle waardes van type CHAR legale col & row ?=> NEE: "a" .. "c" of "1" .. "3"

Is elke waarde van type CHAR een legale marker ?=> NEE: " ", "X" of "O"

Wat is het verband tussen "getMark" en "setMark" ?=> resultaat "getMark" is hetgeen vroeger

gezetwerd via "setMark"

Page 27: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.27

Vuistregel

• Controleer de waardes van de argumenten die je binnenkrijgt (PRE)

• Controleer de waarde van het resultaat dat je teruggeeft (POST)

Waarom ?• Meeste fouten door interpretatieproblemen van de interfaceHoe ?• Schrijf pre- en postcondities bij elke procedure

=> vlak na BEGIN: ASSERT(<boolean expression>, 100)=> vlak voor END: ASSERT(<boolean expression>, 120)

Page 28: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.28

PROCEDURE (aTicTacToe: TicTacToe)getMark* (col, row: CHAR): CHAR;

(** Answer the mark on the given position on the board. *)VAR result: CHAR;BEGIN

ASSERT( ("a"<=col) & (col<="c") & ("1"<=row) & (row<="3"), 100);

result := aTicTacToe.board [ORD(col) - ORD("a"),ORD(row) - ORD("1")];

ASSERT(("X" = result) OR ("O" = result) OR (" " = result), 120);RETURN result;

END getMark;Gebruik een "assertion"• aborteert het programma

=> fout terug te vinden• compileeroptie

=> geen redundante controles

• Constantes=> WatSon

Page 29: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.29

PROCEDURE (aTicTacToe : TicTacToe) getMark (col, row: CHAR): CHAR;(* Answer the mark on the given position on the board. *)

(* precondition (100): ("a"<=col) & (col<="c") & ("1"<=row) & (row<="3") *)

(* postcondition (120): ("X" = result) OR ("O" = result) OR (" " = result) *)

WatSon uitvoerprecondities constante in [100 ... 109](& invarianten constante in [110 ... 119])& postcondities constante in [120 ... 129]• deel van de klasse-interface

=> CONTRACT met de buitenwereld• automatisch gegenereerd

=> steeds synchroon met de code

Page 30: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.30

Vuistregel

Contracten gebruiken alleen publieke (geëxporteerde)

declaraties

Waarom ?• contract verifieerbaar door externe modulesHoe ?• Private (nt. geëxporteerde) declaraties extern niet toegankelijk

=> Denk goed na over wat je pre- & postcondities nodig hebben

Page 31: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.31

PROCEDURE (aTicTacToe: TicTacToe) setMark* (col, row, mark: CHAR);(* Mark the given position on the board. *)BEGIN

ASSERT( ("a"<=col) & (col<="c") & ("1"<=row) & (row<="3"), 100);ASSERT(("X" =mark) OR ("O" = mark) OR (" " = mark), 100);aTicTacToe.board [ORD(col) - ORD("a"), ORD(row) - ORD("1")] :=

mark;ASSERT(aTicTacToe.board [ORD(col) - ORD("a"), ORD(row) -

ORD("1")]= mark, 120);

END setMark;

board is nt. geëxporteerd=> contract niet verifieerbaar

Page 32: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.32

Vuistregel

Contracten bepalen de volgorde van oproepen.

Waarom ?• Belangrijk, maar niet te lezen in een "platte" klasse-interfaceHoe ?• post-conditie van de voorgaande => pre-conditie van de volgende

Page 33: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.33

PROCEDURE (aTicTacToe: TicTacToe) setMark* (col, row, mark: CHAR);(* Mark the given position on the board. *)BEGIN

ASSERT( ("a"<=col) & (col<="c") & ("1"<=row) & (row<="3"), 100);ASSERT(("X" =mark) OR ("O" = mark) OR (" " = mark), 100);aTicTacToe.board [ORD(col) - ORD("a"), ORD(row) - ORD("1")] :=

mark;ASSERT(aTicTacToe.getMark(col, row) = mark, 120);

END setMark;

Postconditie van setMarkgebruikt getMark=> setMark oproepen voor getMark

Page 34: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.34

Vuistregel

Gebruik pre-conditie om de initializatie van objecten te

controleren

Waarom ?• initialisatie vergeten: veel voorkomende & moeilijk te vinden foutHoe ?• pre-conditie met "properlyInitialized"

properlyInitialized ? Controleer een self-pointer

Page 35: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.35

TYPETicTacToe* = POINTER TO TicTacToeData;TicTacToeData* = RECORD

initCheck: TicTacToe;…

END;

PROCEDURE (t: TicTacToe) properlyInitialized* (): BOOLEAN;BEGIN

RETURN t.initCheck = t;END properlyInitialized;

Wijst normaal naar zichzelf

Object heeft een extra pointer …

Page 36: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.36

PROCEDURE (aTicTacToe: TicTacToe) init*;…

aTicTacToe.initCheck := aTicTacToe;ASSERT(aTicTacToe.properlyInitialized(), 120);

END init;

PROCEDURE (aTicTacToe: TicTacToe) getMark* (col, row: CHAR): CHAR;(** Answer the mark on the given position on the board. *)VAR result: CHAR;BEGIN

ASSERT(aTicTacToe.properlyInitialized(), 100);ASSERT(…)

"properlyInitialized"=> preconditie andere procedures

initializatie garandeert"properlyInitialized"

Page 37: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.37

TTT1.1: Contracten

TicTacToeproperlyInitialized (): BOOLEANpositionInRange (col, row: CHAR): BOOLEANmarkerInRange (marker: CHAR): BOOLEANgetMark (col, row: CHAR): CHARsetMark (col, row, marker: CHAR)

<<precondition>>properlyInitialized() &positionInRange(col, row)

<<postcondition>>markerInRange(result)

<<precondition>>properlyInitialized() &positionInRange(col, row) &markerInRange(marker)

<<postcondition>>getMark(col, row) = marker

(marker = "O")OR (marker = "X")OR (marker = " ")

("a"<=col) & (col<="c") &("1"<=row) &

(row<="3")

Page 38: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.38

Interpretatie Interface

Init()

playing

properlyInitialized

setMark()getMark()

Page 39: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.39

TicTacToeGame (1.1)

aGame:TicTacToe

: TicTacToeGame

*[aGame.notDone()] displayMove ()play

displayGame()

doMove()

writeOn(w)

Page 40: Ontdek de 7 verschillen

Inleiding Software EngineeringInleiding Software Engineering

BetrouwbaarheidUniversiteit Antwerpen

2.40

Vuistregels (Samenvatting)• ONTWERP

– Keep It Stupidly Simple (the KISS principle)• TESTEN

– Minstens één test per "normaal" scenario– Als de functionaliteit groeit, dan groeit de test mee– Een test produceert zo weinig mogelijk uitvoer

• CONTRACTEN– Controleer de waardes van de argumenten die je binnenkrijgt– Controleer de waarde van het resultaat dat je teruggeeft– Contracten gebruiken alleen publieke (geëxporteerde) declaraties– Contracten bepalen de volgorde van oproepen.– Gebruik pre-conditie om de initializatie van objecten te controleren