Slide 1

Slide 1 text

& FÉLIX-ANTOINE BOURBONNAIS B.ING., M.SC, PSM Version: Mai 2017 (DEV) Characterization Testing : regaining control of your Legacy Code PASCAL ROY ING., CSM, PSM, PMP

Slide 2

Slide 2 text

Think how Legacy code affects your work in everyday life… Imagine a tool that helps you explore, understand and refactor it without fear. … a nice dream, isn’t?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

4 Qui sommes-nous ? Pascal Roy Ing., PSM, CSM, PMP Félix-Antoine Bourbonnais B.ing., PSM, M.Sc.

Slide 5

Slide 5 text

Training Mentoring Diagnostics Talks

Slide 6

Slide 6 text

Speakers Trainers Coaches & Mentors Tech. Team & Business Mgmt. TDD Emergent architecture Automated tests DDD … Scrum Agile QA Project management Agility BDD > We are Strategic advice > What we do

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

Am I the only one to have Legacy Code ?

Slide 9

Slide 9 text

Code that is difficult to modify and evolve. Regardless how old it is or why it got this way. What is Legacy Code ?

Slide 10

Slide 10 text

• Code written by others • Code nobody wants to touch anymore • Code no longer supported by the people who wrote it • Code that could be rewritten using better coding practices, tools or languages • ... Other popular definitions …

Slide 11

Slide 11 text

Code without tests Michael Feathers, Working Effectively with Legacy Code

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

Two basic strategies… What to do with my Legacy Code ?

Slide 14

Slide 14 text

Fear : software development’s worst enemy

Slide 15

Slide 15 text

Tired of the continuous stress of delivery, of endless debugging sessions, of the fear of breaking something?

Slide 16

Slide 16 text

Please, give me a new project !@/$%!/%

Slide 17

Slide 17 text

The cycle of death… Legacy Code No tests No refactoring Patches

Slide 18

Slide 18 text

No content

Slide 19

Slide 19 text

Why not rejuvenate your code?

Slide 20

Slide 20 text

Correctly equipped, yes you can !

Slide 21

Slide 21 text

Gradually, while still producing business value

Slide 22

Slide 22 text

Pick your next « Story » and begin paying out some of that debt!

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

Characterization test

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

A characterization test describes the actual behavior of an existing piece of code. - Michael Feathers

Slide 27

Slide 27 text

Overcome fear! To… Understand and document what the code does Protect against unintended changes when refactoring +

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

1. Find and isolate a piece of code that you need to analyze or modify 2. Write a test that uses that code, use an assertion you know will fail 3. Execute the test and let it tell you the actual behavior 4. Change the test assertion and the naming to match the actual behavior 5. Repeat… 5 steps for writing a characterization test

Slide 30

Slide 30 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; public double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } http://s3.amazonaws.com/giles/demons_010609/wtfm.jpg An example of Legacy Code? WTF? WTF? WTF?

Slide 31

Slide 31 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; public double calculate(double tSales){ if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } @Test public void test… { assert(...) } Step 1: identify a piece of code to characterize 1 ? 2 ? ? 1 2

Slide 32

Slide 32 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1+ (tSales - BQ*2)*BCR * OQM2; } } } @Test public void testCalculate() { assertEquals( 0.0, SalesUtil.calculate(1000.0) ); } Step 2: write a failing assertion 1 ? 2 ? ? 1 2

Slide 33

Slide 33 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1 + (tSales - BQ * 2) * BCR * OQM2; } } } @Test public void testCalculate() { assertEquals( 0.0, SalesUtil.calculate(1000.0) ); } Step 3: execute the test + find out the actual behavior is > junit.framework.AssertionFailedError: expected:<0.0> but was:<200.0> 1 ? 2 ? ?

Slide 34

Slide 34 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1+ (tSales – BQ*2)*BCR * OQM2; } } } @Test public void lessThanBaseQuota_useBaseCommissionRate() { assertEquals( 200.0, SalesUtil.calculate(1000.0) ); } Step 4: Replace the assertion by the actual behavior 1 2 1 200 2 ? ?

Slide 35

Slide 35 text

public class SalesUtil { double BQ = 1000.0; double BCR = 0.20; double OQM1 = 1.5; double OQM2 = OQM1 * 2; double calculate(double tSales) { if (tSales <= BQ) { return tSales * BCR; } else if (tSales <= BQ * 2) { return (BQ) * BCR + (tSales - BQ) * BCR * OQM1; } else { return (BQ) * BCR + (tSales - BQ) * BCR*OQM1+ (tSales – BQ*2) * BCR*OQM2; } } } … @Test public void testCalculate () { assertEquals( 0.0, SalesUtil.calculate(2000.0) ); } Step 5: Repeat 1 2 1 200 2 ? ?

Slide 36

Slide 36 text

Watch out for : « While we’re at it, we might as well… » ! Work only on what you need to modify now.

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

We really don’t have the time for this ?!?

Slide 39

Slide 39 text

How long does it take to understand a piece of Legacy code before you can change it (reasonably safely)?

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

• Specifies required behavior • Known behavior and new code • Permanent • Specifies actual behavior • Legacy code, Lost or forgotten behavior • Temporary Unit test Characterization test How is a CT different?

Slide 42

Slide 42 text

Will end-to-end tests around my application help me characterize my code?

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Refactoring is not a rewrite on a small scale!

Slide 45

Slide 45 text

Why are managers/customers/project managers so afraid of refactoring?

Slide 46

Slide 46 text

Watch out for Big Bang refactoring ! 46

Slide 47

Slide 47 text

A big expense Big Bang Very high risk No new business value Regular payments (debt) Step by Step Lower risk Still produce value Rewrite Renovate / Rejuvenate Rewrite or refactoring ?!?

Slide 48

Slide 48 text

A strategy > stabilize the patient and focus on what is most critical As in the emergency room…

Slide 49

Slide 49 text

Let what you are currently working on guide your efforts

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

This talk was about understanding and securing your Legacy Code…. Now, you can learn how to mercilessly renovate your Legacy Code: • Sprout Methods/Classes • Instance Delegator • Extract to Method • … Next… Refactoring techniques

Slide 52

Slide 52 text

Maintainability: a great challenge for the future

Slide 53

Slide 53 text

Code rot is avoidable

Slide 54

Slide 54 text

Although our first joy of programming may have been intense, the misery of dealing with legacy code is often sufficient to extinguish that flame. Michael Feathers, Working Effectively with Legacy Code Legacy code can kill the flame!

Slide 55

Slide 55 text

Image de http://beinweb.fr/wp-content/uploads/2014/04/boite-a-outils-entrepreneurs.jpg Characterization testing… Another tool to add to your toolbox!

Slide 56

Slide 56 text

« Legacy code » can be treated !

Slide 57

Slide 57 text

Thank you.

Slide 58

Slide 58 text

Site elapsetech.com Twitter @fbourbonnais Email [email protected] [email protected] LinkedIn linkedin.com/in/fbourbonnais ca.linkedin.com/in/roypa conferences.elapsetech.com All our conferences (french) conferences.elapsetech.com /legacy-tests-caracterisation Slides and references (french) Félix-Antoine Bourbonnais Pascal Roy