Slide 1

Slide 1 text

3P PROTECT - PREPARE - PRODUCE Johan MARTINSSON

Slide 2

Slide 2 text

PROTECT PREPARE PRODUCE 3P PROTECT - PREPARE - PRODUCE Johan MARTINSSON

Slide 3

Slide 3 text

@Johan_alps

Slide 4

Slide 4 text

@Johan_alps

Slide 5

Slide 5 text

@Johan_alps

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

The more of the Just In Time, the better the state of the project

Slide 8

Slide 8 text

3P

Slide 9

Slide 9 text

3P PROTECT PREPARE PRODUCE

Slide 10

Slide 10 text

Ex 1: Receipt printer We want a html receipt and we already have text and csv Total price and VAT calculus is mixed with formatting String makeReceipt(productNames, catalog, receiptType) productNames, catalog, receiptType makeReceipt() text csv Photo by Michael Walter on Unsplash

Slide 11

Slide 11 text

Protect Just call the function Approval tests to assert the full text String result = receiptService.makeReceipt(panier, catalog, new TextPrinter()); Approvals.verify(result);

Slide 12

Slide 12 text

Protect Just call the function Approval tests to assert the full text String result = receiptService.makeReceipt(panier, catalog, new TextPrinter()); String expectedOutput = " JP Gothié créations, Paris \n" + "-----------------------\n" + " chemise deluxe 199.99 €\n" + " veste frimeur 520.50 €\n" + " chaussures cuir croco® 410.00 €\n" + "\n" + "Total: 1035.92 TTC\n" + "TVA: 172.65 \n" + "-----------------------\n" + " JP Gothié vous remercie pour votre visite"; assertThat(result).isEqualTo(expectedOutput);

Slide 13

Slide 13 text

Prepare Extract the calculations (total + vat) Normal assertions for the total and VAT Keep one approval test for csv, one for text

Slide 14

Slide 14 text

Produce TDD the html receipt, or ITL using approval tests

Slide 15

Slide 15 text

Approval testing • Automated assertion on strings (and bitmaps, …) • External di ff -tools to inspect di ff erences • convert complex data to strings or json • Scrubbers to normalize dates, uuids, etc String result = receiptService.makeReceipt(panier, catalog, new TextPrinter()); Approvals.verify(result);

Slide 16

Slide 16 text

Approval testing • Automated assertion on strings (and bitmaps, …) • External di ff -tools to inspect di ff erences • convert complex data to strings or json • Scrubbers to normalize dates, uuids, etc

Slide 17

Slide 17 text

Value of Information Expected gain: Probability * Value - Cost of doing

Slide 18

Slide 18 text

Value of Information 50 % chance of 1000 in value. Cost is 200
 50% * (1000 - 200) + 50% * (0-200) = 300 Expected gain: Probability * Value - Cost of doing

Slide 19

Slide 19 text

Value of Information 50 % chance of 1000 in value. Cost is 200
 50% * (1000 - 200) + 50% * (0-200) = 300 If you pay 50 to know : - 50 50% * (1000 - 200) + 50% * (0 - 0) = 350 Expected gain: Probability * Value - Cost of doing

Slide 20

Slide 20 text

Value of Information 50 % chance of 1000 in value. Cost is 200
 50% * (1000 - 200) + 50% * (0-200) = 300 If you pay 50 to know : - 50 50% * (1000 - 200) + 50% * (0 - 0) = 350 Expected gain: Probability * Value - Cost of doing 70 % chance of 1000 in value, 30% 2000 in penalty. Cost is still 200 70% * (1000-200) + 30% * (-2000-200) = 100

Slide 21

Slide 21 text

Value of Information 50 % chance of 1000 in value. Cost is 200
 50% * (1000 - 200) + 50% * (0-200) = 300 If you pay 50 to know : - 50 50% * (1000 - 200) + 50% * (0 - 0) = 350 Expected gain: Probability * Value - Cost of doing 70 % chance of 1000 in value, 30% 2000 in penalty. Cost is still 200 70% * (1000-200) + 30% * (-2000-200) = 100 If you pay 50 to know : - 50 70% * (1000-200) + 30% * (- 0 - 0) = 510

Slide 22

Slide 22 text

Value of Information Expected gain: Probability * Value - Cost of doing -250 -125 0 125 250 375 500 Useful Not useful Useful Not useful 300 350 Paying to know Paying to know 510

Slide 23

Slide 23 text

Value of Information Expected gain: Probability * Value - Cost of doing -250 -125 0 125 250 375 500 Useful Not useful Useful Not useful 300 350 Paying to know Paying to know 510

Slide 24

Slide 24 text

Value of Information Expected gain: Probability * Value - Cost of doing -250 -125 0 125 250 375 500 Useful Not useful Useful Not useful -700 -525 -350 -175 0 175 350 525 700 Useful Not useful Useful Not useful 300 350 Paying to know Paying to know 100 510

Slide 25

Slide 25 text

Value of Information Expected gain: Probability * Value - Cost of doing -250 -125 0 125 250 375 500 Useful Not useful Useful Not useful -700 -525 -350 -175 0 175 350 525 700 Useful Not useful Useful Not useful 300 350 Paying to know Paying to know 100 510

Slide 26

Slide 26 text

Cheap way of knowing?

Slide 27

Slide 27 text

Cheap way of knowing? Wait

Slide 28

Slide 28 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP)

Slide 29

Slide 29 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP) Which are good After?

Slide 30

Slide 30 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP) Which are good After?

Slide 31

Slide 31 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP) Which are good After?

Slide 32

Slide 32 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP) Which are good After?

Slide 33

Slide 33 text

Types of refactorings Simpli fi cation Reduce illegal states Encode knowledge Make extensible (apply OCP) Which are good After?

Slide 34

Slide 34 text

@Johan_alps Test at end of story

Slide 35

Slide 35 text

@Johan_alps Test at start of story

Slide 36

Slide 36 text

Ef fi ciency? Test at start of story Test at end of story

Slide 37

Slide 37 text

Ef fi ciency? Test at start of story Test at end of story Replace with "micro increment” => TDD

Slide 38

Slide 38 text

Ef fi ciency? Test at start of story Test at end of story Replace with "micro increment” => TDD

Slide 39

Slide 39 text

Ef fi ciency? Learning? Test at start of story Test at end of story Replace with "micro increment” => TDD

Slide 40

Slide 40 text

Do the tests help? When we refactor? When we add new features? Learning

Slide 41

Slide 41 text

3P PROTECT PREPARE PRODUCE

Slide 42

Slide 42 text

Ex 2: Lift pass pricing (kata) github.com/martinsson/Refactoring-Kata-Lift-Pass-Pricing

Slide 43

Slide 43 text

Ex 2: Lift pass pricing (kata) github.com/martinsson/Refactoring-Kata-Lift-Pass-Pricing We want a rest-route that calculates price of several lift-passes We’ve got one for a single lift-pass!

Slide 44

Slide 44 text

@Johan_alps Rest-mapping DB request Sending response anonymous function

Slide 45

Slide 45 text

@Johan_alps ing st anon

Slide 46

Slide 46 text

@Johan_alps onse

Slide 47

Slide 47 text

Protect Provide a database Hit the REST-API Assert the results

Slide 48

Slide 48 text

Prepare Extract the unit-cost function Adapt tests to the testable interfaces

Slide 49

Slide 49 text

@Johan_alps prices (rest) http domain infra

Slide 50

Slide 50 text

@Johan_alps GetPriceUsecase PriceDao Price prices (rest) http domain infra

Slide 51

Slide 51 text

@Johan_alps GetPriceUsecase PriceDao Price prices (rest) http domain infra

Slide 52

Slide 52 text

Produce TDD a new multiple-pass cost function and wrap it in a rest-route

Slide 53

Slide 53 text

ONE GOAL : MAKE IT SAFE TO REFACTOR - COVER ALL CASES - CAPTURE ALL BEHAVIOUR 3 P PROTECT

Slide 54

Slide 54 text

ONE GOAL : MAKE IT SAFE TO REFACTOR - COVER ALL CASES - CAPTURE ALL BEHAVIOUR 3 P PROTECT POSSIBLE COMPROMISES - STABILITY - ISOLATION - WORKS ON MY MACHINE - READABILITY ! - …

Slide 55

Slide 55 text

Quick and dirty tests FTW 💩

Slide 56

Slide 56 text

Refactoring tests To protect a refactoring: what do we care about? Test quality Importance Coverage Vital Captures all side-e ff ects Vital Sub-second Nice to have Stability (not fl aky) Nice to have Stability (regarding external data changes) Nice to have Readability Who cares Runs on any machine (CI) Wildly useless Allows new features Wildly useless

Slide 57

Slide 57 text

Types of tests and qualities

Slide 58

Slide 58 text

Types of tests and qualities Nice place

Slide 59

Slide 59 text

Types of tests and qualities Nice place Nice place

Slide 60

Slide 60 text

Types of tests and qualities Nice place Nice place

Slide 61

Slide 61 text

Types of tests and qualities Nice place Nice place

Slide 62

Slide 62 text

PREPARATORY REFACTORING 3 P PREPARE

Slide 63

Slide 63 text

PREPARATORY REFACTORING MAKE IT "UNIT" TESTABLE 3 P PREPARE

Slide 64

Slide 64 text

PREPARATORY REFACTORING MAKE IT "UNIT" TESTABLE => OFTEN SIMILAR 3 P PREPARE

Slide 65

Slide 65 text

PREPARATORY REFACTORING MAKE IT "UNIT" TESTABLE => OFTEN SIMILAR 3 P PREPARE

Slide 66

Slide 66 text

PREPARATORY REFACTORING MAKE IT "UNIT" TESTABLE => OFTEN SIMILAR 3 P PREPARE

Slide 67

Slide 67 text

JUST IMPLEMENT USING TDD… … NO MATTER THE ORIGINAL CODE 3 P PRODUCE

Slide 68

Slide 68 text

Diff - trackers A multi-stage processing accumulates multiple mongodb queries that are executed at the end We want to change the request that is made Pb : unit testing the syntax of mongodb ? •Brittle •TDD for new features would be ridiculous shopping_cart_tracker.update({ "$set": { “ware_house”: warehouse_id, “stock_status": VERIFIED, } })

Slide 69

Slide 69 text

Diff - trackers A multi-stage processing accumulates multiple mongodb queries that are executed at the end We want to change the request that is made Pb : unit testing the syntax of mongodb ? •Brittle •TDD for new features would be ridiculous shopping_cart_tracker.update({ "$set": { “ware_house”: warehouse_id, “stock_status": VERIFIED, } }) shopping_cart_events.add_event( StockVerified(warehouse_id) )

Slide 70

Slide 70 text

Protect Start mongodb locally Insert data for testing Assert side-e ff ects by reading from db

Slide 71

Slide 71 text

Prepare Replace with Domain Events Separate code into 1. Loading 2. Computation of desired state 3. Saving Isolate tests - most tests concern computation

Slide 72

Slide 72 text

Produce TDD the new behaviour,
 simply emitting new Events 
 and calculating desired state

Slide 73

Slide 73 text

WireMock • stubs: somewhat useful for changing data or costly requests • veri fi cation: assertions on fi re-and-forget side e ff ects. Also useful for not damaging data

Slide 74

Slide 74 text

Test transition PROTECT PREPARE PRODUCE

Slide 75

Slide 75 text

Work fl ow comparison 3P TEST LAST IMPRESSION OF MAKING PROGRESS MAKING PROGRESS IMPRESSION OF NO PROGRESS

Slide 76

Slide 76 text

@Johan_alps From : CodeScene

Slide 77

Slide 77 text

@Johan_alps From : CodeScene

Slide 78

Slide 78 text

@Johan_alps From : CodeScene

Slide 79

Slide 79 text

@Johan_alps From : CodeScene A fraction of the e ff ort

Slide 80

Slide 80 text

When to 3P ? • We want to improve the code, but tests are lacking • We want something progressive • The code is the only spec • We don’t want bugs It maximises ROI, in a progressive fashion, associating it with stories. So

Slide 81

Slide 81 text

When not to 3P ? • When it is convenient to replace with new code • Possibly when specs are Known • We can TDD a replacement (only it’s not progressive) • When the project has no (little) ambition • Not every improvement can be linked to a story

Slide 82

Slide 82 text

Smaller is more

Slide 83

Slide 83 text

The mikado method

Slide 84

Slide 84 text

Better ROI => more of it Test and refactoring JIT => better ROI Decide late 3P allows for massive, incremental refactoring 3P enables TDD in any project 3P is safe (but maybe not SAFe) Adopting TDD? => Feedback on viability in days Smaller batches Recap Photo by Steven Wright on Unsplash

Slide 85

Slide 85 text

3P

Slide 86

Slide 86 text

3P https://martinsson-johan.blogspot.com/ 2022/11/breaking-out-of-legacy-with-3p.html