100 % confident with legacy code

30
100% Confident with Legacy Code Johan MARTINSSON Developer - Independent [email protected] m @ johan_alps Rémy SANLAVILLE Developer - Orange Software Expert [email protected] @ sanlaville

Upload: sanlaville

Post on 02-Jul-2015

2.205 views

Category:

Software


2 download

DESCRIPTION

I T.A.K.E 2014 unconference

TRANSCRIPT

Page 1: 100 % Confident With Legacy Code

100% Confident with Legacy

Code

Johan MARTINSSON

Developer - Independent

[email protected]

@johan_alps

Rémy SANLAVILLE

Developer - Orange Software Expert

[email protected]

@sanlaville

Page 2: 100 % Confident With Legacy Code

Working with Legacy Code

Page 3: 100 % Confident With Legacy Code

Working with Legacy Code

Refactoring Legacy Code with Object

Calisthenics2012 - 2013

Anonymous Developers - Season 1

Page 4: 100 % Confident With Legacy Code

Working with Legacy Code

100% Confident with Legacy Code

2014

Anonymous Developers - Season 2

Page 5: 100 % Confident With Legacy Code

Testing Legacy Code - Blockers

Integration tests are too long

Unit tests are too coupled to the source code

Hard and long to write tests

Page 6: 100 % Confident With Legacy Code

Testing Legacy Code

100% Confident with Legacy Code

2014

Anonymous Developers - Season 2

Page 7: 100 % Confident With Legacy Code

Testing Legacy Code

100% Confident with Legacy Code

2014

Anonymous Developers - Season 2

Page 8: 100 % Confident With Legacy Code

Testing Legacy Code

Don’t forget to replace

temporary refactoring

tests

by maintainable tests

Page 9: 100 % Confident With Legacy Code

Trivia Challengehttp://www.hasbro.com/games/en_US/shop/details.cfm?R=93C6EE71-

6D40-1014-8BF0-9EFBF894F9D4:en_US

https://github.com/jbrains/trivia

It simulates a trivia game

using a randomizer

for correct and wrong answers

How long do you need to

reach ~100% code coverage ?

Page 10: 100 % Confident With Legacy Code

Trivia Challengehttps://github.com/jbrains/trivia

http://www.hasbro.com/games/en_US/shop/details.cfm?R=93C6EE71-

6D40-1014-8BF0-9EFBF894F9D4:en_US

It works well because there

are no dependencies

1

1

Serialize game state and

compare it with Approval Tests1

Cover all branches by

variying the results of the

randomizer

2

2

Page 11: 100 % Confident With Legacy Code

Server 1Server 2

EncodeAudioLegacy Challenge

Remote Server 1

Audio File encoding

HTTPS Server 2

Audio File Encoded

Audio File

Audio File available

at Remote Server 1

Encoded Audio File

available

download upload

Encode Audio Engine

Page 12: 100 % Confident With Legacy Code

Baby Steps

Step0: Development environment validation

Step1: String comparison with ApprovalTests

Step2: Branch coverage by input parameter variation

Step3: Serializing a complex type

Step4: Mocking web services

Step5: Capturing side effects

Page 13: 100 % Confident With Legacy Code

Step 0: Development environment validation

EclEmmaJUnit

Technical Solution: Unit Testing + Code Coverage Tool + Diff

Tool

Context: Launch UT + Code Coverage + String comparison

Server 1

Remote Server 1

Audio Filedownload

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

Meld

WinMerge…

Page 14: 100 % Confident With Legacy Code

Step 1: Method returns a primitive type

Technical Solution: Approval Tests (string comparison)

Context: No side effect + Method returns a primitive type

Server 1

Remote Server 1

Audio Filedownload

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

Note: encoding issues

Page 15: 100 % Confident With Legacy Code

Step 2: Branches coverage by input

parameters variation

Technical Solution: Approval Tests (legacyApprovals)

Context: No side effect + Method returns a primitive type

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

Server 1

Remote Server 1

Audio Filedownload

Page 16: 100 % Confident With Legacy Code

Step 3: Method returns a complex type

Note: date issues

Context: No side effect + Method returns a complex type

Technical Solution: Approval Tests + XStream

Server 1

Remote Server 1

Audio Filedownload

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

IFluxTmlg

IBodyTmlg

ITravelInfoTmlg

IAudioAnnounceTmlg

Page 17: 100 % Confident With Legacy Code

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

Step 4: Third-party services

Context: WebService difficult to configure or/and not

avalaible

Technical Solution: Moco

Server 1

Remote Server 1

Audio Filedownload

Page 18: 100 % Confident With Legacy Code

Step 5: Capturing side effects

Note: can be used for context with void methods

not mocking side effect

Context: Side effects

Technical Solution: State, Side Effects Serialization + Approval

Tests

Server 1

Remote Server 1

Audio Filedownload

Server 2

encoding

HTTPS Server 2

Audio File available

at Remote Server 1

Encode Audio Engineupload

Audio File Encoded

Audio File

Encoded

Audio File

Encoded Audio File

available

Page 19: 100 % Confident With Legacy Code

Conclusion - Why it’s working?

Easy assertion: record and replay

Even ugly tests do the job (Temporary tests)

Fast to execute

Available good libraries:

Approval Tests, XStream, Moco…

Tests are resilient to refactoring

Page 20: 100 % Confident With Legacy Code

Next…

http://approvaltests.sourceforge.net/

http://martinsson-johan.blogspot.fr/

http://github.com/dreamhead/moco

https://github.com/pearlfish/pearlfish-java

UI visual diffing

https://www.youtube.com/watch?v=UMnZiTL0tUc

Working Effectively with Legacy Code – in particular for

creating “seams”

Page 21: 100 % Confident With Legacy Code
Page 22: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Page 23: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Approval Tests

only needs 2

lines!

Page 24: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Run your test

Diff Tool (by default TortoiseMerge)

Cf. Using Reporters in Approval Tests

http://blog.approvaltests.com/2011/12/using-reporters-in-approval-tests.html

Page 25: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Result of the current test

named received

Page 26: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Result reference

named approved

Page 27: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Approve result

and save file

Page 28: 100 % Confident With Legacy Code

http://approvaltests.sourceforge.net/

Page 29: 100 % Confident With Legacy Code

BACKUP

Page 30: 100 % Confident With Legacy Code

Server 1Server 2

EncodeAudioLegacy Challenge

Remote Server 1

Audio File encoding

HTTPS Server 2

Audio File available

at Remote Server 1

download

Encode Audio Engineupload

AudioAnnouceTmlg

URL Remote Server 1

format

filename

audioConfigTmp

target audio file extension

target encoding properties

httpConfigTmp

Local Tempory Folder path,

URL Remote HTTPS Server 2

Local Tempory Folder

Audio File Encoded

Audio File

Local HTTP

Server

Encoded

Audio File

Encoded Audio File

availableAudioFile

name

format