Successfully reported this slideshow.
Your SlideShare is downloading. ×

Refactoring legacy code driven by tests - ITA

Upcoming SlideShare
Agile Testing
Agile Testing
Loading in …3
×

Check these out next

1 of 59 Ad
1 of 59 Ad

Refactoring legacy code driven by tests - ITA

Download to read offline

Are you working on code poorly designed or on legacy code that’s hard to test? And you cannot refactor it because there are no tests?

During this Coding Dojo you’ll be assigned a coding challenge in Java, C#, Ruby, JavaScript or Python. You will face the challenge of improving the design and refactoring existing code in order to make it testable and to write unit tests.

We will discuss SOLID principles, the relation between design and TDD, and how this applies to your solution.

Reading list:
Growing Object-Oriented Software, Guided by Tests; Steve Freeman, Nat Pryce
Test Driven Development: By Example; Kent Beck
Working Effectively with Legacy; Michael Feathers
Agile Software Development, Principles, Patterns, and Practices; Robert C. Martin (C++, Java)
Agile Principles, Patterns, and Practices in C#; Robert C. Martin (C#)

Are you working on code poorly designed or on legacy code that’s hard to test? And you cannot refactor it because there are no tests?

During this Coding Dojo you’ll be assigned a coding challenge in Java, C#, Ruby, JavaScript or Python. You will face the challenge of improving the design and refactoring existing code in order to make it testable and to write unit tests.

We will discuss SOLID principles, the relation between design and TDD, and how this applies to your solution.

Reading list:
Growing Object-Oriented Software, Guided by Tests; Steve Freeman, Nat Pryce
Test Driven Development: By Example; Kent Beck
Working Effectively with Legacy; Michael Feathers
Agile Software Development, Principles, Patterns, and Practices; Robert C. Martin (C++, Java)
Agile Principles, Patterns, and Practices in C#; Robert C. Martin (C#)

Advertisement
Advertisement

More Related Content

Advertisement

More from Luca Minudel (20)

Advertisement

Refactoring legacy code driven by tests - ITA

  1. 1. Refactoring legacy code driven by tests Luca Minudel + Ilias Bartolini + Luigi Bozzo I’m the Refactoring Chicken I’m the TDD egg
  2. 2. Let’s clarify the scope of this Workshop
  3. 3. Languages supported in this Workshop C# Java JavaScr ipt Ruby Pytho n Sala PHP Cpp
  4. 4. Automatic Testing Continuum Specification (documentation) Verification Design
  5. 5. Scope of this workshop Specification (documentation) Verification Design
  6. 6. Types of Automatic Tests End-to-end, out-of-process, business facing Unit, in-process, technology facing
  7. 7. Scope of this workshop End-to-end, out-of-process, business facing Unit, in-process, technology facing
  8. 8. Exercise 1: Tire Pressure Monitoring System Alarm class: controlla la pressione di un pneumatico e lancia un allarme se la pressione esce dall’intervallo di valori attesi.
  9. 9. Exercise 1: Tire Pressure Monitoring System Alarm class: controlla la pressione di un pneumatico e lancia un allarme se la pressione esce dall’intervallo di valori attesi. Sensor class: simula un vero sensore di pressione in un pneumatico, generando valori casuali ma realistici di pressione.
  10. 10. Exercise 1: Tire Pressure Monitoring System Scrivi gli unit test per la Alarm class. Fai il Refactoring del codice sino a rendere la Alarm class testabile.
  11. 11. Exercise 1: Tire Pressure Monitoring System Scrivi gli unit test per la Alarm class. Fai il Refactoring del codice sino a rendere la Alarm class testabile. Minimizza i cambiamenti alla API pubblica più che puoi.
  12. 12. Exercise 1: Tire Pressure Monitoring System Scrivi gli unit test per la Alarm class. Fai il Refactoring del codice sino a rendere la Alarm class testabile. Minimizza i cambiamenti alla API pubblica piu che puoi. Extra credits: Alarm class viola alcuni dei principi SOLID. Prendi nota della linea di codice e il principio violato.
  13. 13. The SOLID acronym S single responsibility principle O open closed principle L Liskov substitution principle I interface segregation principle D dependency inversion principle
  14. 14. Dependency Inversion Principle (DIP) Martin Fowler's definition: a) High level modules should not depend upon low level modules, both should depend upon abstractions. b) Abstractions should not depend upon details, details should depend upon abstractions.
  15. 15. Dependency Inversion Principle (DIP) Both low level classes and high level classes should depend on abstractions. High level classes should not depend on low level classes.
  16. 16. DIP Violation In Example Code High Level Class Dependency Low Level Class
  17. 17. Open Closed Principle (OCP) Bertrand Meyer's definition: Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
  18. 18. Open Closed Principle (OCP) Classes and methods should be open for extensions & strategically closed for modification. So that the behavior can be changed and extended adding new code instead of changing the class.
  19. 19. OCP Violation In Example Code Want to use a new type of sensor? Must modify code; cannot extend it
  20. 20. Dependency injection
  21. 21. Reference: WELC Parametrize Constructor Extract Interface
  22. 22. Exercise 2: Unicode File To Htm Text Converter UnicodeFileToHtmTextConverter class: trasforma del testo semplice in html per essere visualizzato da un browser.
  23. 23. Exercise 2: Unicode File To Htm Text Converter Scrivi gli unit test per la UnicodeFileToHtmTextConverter. Fai il Refactoring del codice sino a rendere la classe testabile.
  24. 24. Exercise 2: Unicode File To Htm Text Converter Scrivi gli unit test per la UnicodeFileToHtmTextConverter. Fai il Refactoring del codice sino a rendere la classe testabile. Minimizza i cambiamenti alla API pubblica più che puoi.
  25. 25. Exercise 2: Unicode File To Htm Text Converter Scrivi gli unit test per la UnicodeFileToHtmTextConverter. Fai il Refactoring del codice sino a rendere la classe testabile. Minimizza i cambiamenti alla API pubblica più che puoi. Extra credits: UnicodeFileToHtmTextConverter class viola alcuni dei principi SOLID. Prendi nota della linea di codice e il principio violato.
  26. 26. Feathers’ rules of thumb. Extended ! A test is not a unit test when:  It talks to the database  It communicates across the network  It touches the file system or reads config info  It uses DateTime.now() or Random  It depends on non-deterministic behavior  It can't run at the same time as any of your other unit tests  You have to do special things to your environment (such as editing config files) to run it.
  27. 27. Refactoring and TDD Should we inject this dependency?
  28. 28. Behavior of TextReader TextReader documentation from MSDN Non-idempotent behavior
  29. 29. Dependency injection and idempotent behavior
  30. 30. Reference: WELC Parametrize Constructor Extract Interface Skin and Wrap the API
  31. 31. Exercise 3: Ticket Dispenser TicketDispenser class: gestisce il sistema delle code agli sportelli di un negozio. Ci possono essere più distributori dei biglietti col numero del turno senza che questi distribuiscano lo stesso numero a due clienti diversi.
  32. 32. Exercise 3: Ticket Dispenser TurnTicket class: rappresenta il biglietto col numero del turno. TurnNumberSequence class: genera la sequenza dei numeri del turno.
  33. 33. Exercise 3: Ticket Dispenser Scrivi gli unit test per la TicketDispenser class. Fai il Refactoring del codice sino a rendere la classe TicketDispenser testabile.
  34. 34. Exercise 3: Ticket Dispenser Scrivi gli unit test per la TicketDispenser class. Fai il Refactoring del codice sino a rendere la classe TicketDispenser testabile. Minimizza i cambiamenti alla API pubblica più che puoi.
  35. 35. Exercise 3: Ticket Dispenser Scrivi gli unit test per la TicketDispenser class. Fai il Refactoring del codice sino a rendere la classe TicketDispenser testabile. Minimizza i cambiamenti alla API pubblica più che puoi. Extra credits: TicketDispenser class viola alcuni dei principi OO e SOLID. Prendi nota della linea di codice e il principio violato.
  36. 36. Encapsulation Violation In Example Code
  37. 37. DIP Violation In Example Code High Level Class Dependencies Low Level Classes
  38. 38. OCP Violation In Example Code Want to use a new type of sequence or ticket? Must modify code; cannot extend it
  39. 39. Dependency injection
  40. 40. Introduce Instance Delegator
  41. 41. Reference: WELC Parametrize Constructor Extract Interface Skin and Wrap the API Introduce Instance Delegator …
  42. 42. Exercise 4: Telemetry System TelemetryDiagnosticControl class: establishes a connection to the telemetry server through the TelemetryClient, sends a diagnostic request and receives the response with diagnostic info. TelemetryClient class: simulates the communication with the Telemetry Server, sends requests and then receives and returns the responses
  43. 43. Exercise 4: Telemetry System Write the unit tests for the TelemetryDiagnosticControl class. Refactor the code as much as you need to make the class testable.
  44. 44. Exercise 4: Telemetry System Write the unit tests for the TelemetryDiagnosticControl class. Refactor the code as much as you need to make the class testable. Minimize changes to the public API as much as you can.
  45. 45. Exercise 4: Telemetry System Write the unit tests for the TelemetryDiagnosticControl class. Refactor the code as much as you need to make the class testable. Minimize changes to the public API as much as you can. Extra credits: TelemetryClient class fails to follow one or more of the OO and SOLID principles. Write down the line number, the principle & the violation.
  46. 46. Single Responsibility Principle (SRP) A class should have only one reason to change.
  47. 47. Single Responsibility Principle (SRP) There should never be more than one reason for a class to change. A class should have one and only one responsibility.
  48. 48. Interface Segregation Principle (IRP) Clients should not be forced to depend upon interfaces that they do not use.
  49. 49. Interface Segregation Principle (IRP) Clients should not be forced to depend upon interface members that they don't use. Interfaces that serve only one scope should be preferred over fat interfaces.
  50. 50. Reference: SRP http://www.objectmentor.com/resources/articles/srp.pdf Pag. 151/152
  51. 51. Refactoring and TDD
  52. 52. Synergy between testing and design Michael Feathers: writing tests is another way to look the code and locally understand it and reuse it, and that is the same goal of good OO design. This is the reason for the deep synergy between testability and good design.
  53. 53. Other testing strategies for legacy code  Start with other tests  Use an automatic refactoring tool  Strangler pattern  DDD anti-corruption layer
  54. 54. Mike Cohn's Test Pyramid. Explained ! UI tests Integration tests Unit tests
  55. 55. More references
  56. 56. More references
  57. 57. More references
  58. 58. References  http://scratch.mit.edu/projects/13134082/  http://vimeo.com/15007792  http://martinfowler.com/bliki/TestPyramid.html  http://martinfowler.com/bliki/StranglerApplication.html  http://www.markhneedham.com/blog/2009/07/07/domain-driven- design-anti-corruption-layer/  http://www.objectmentor.com/resources/articles/srp.pdf  http://www.objectmentor.com/resources/articles/ocp.pdf  http://www.objectmentor.com/resources/articles/lsp.pdf  http://www.objectmentor.com/resources/articles/isp.pdf  http://www.objectmentor.com/resources/articles/dip.pdf
  59. 59. References / Links / Slides On Twitter On Twitter : @GGBOZZO @ILIASBARTOLINI @LUKADOTNET

Editor's Notes

  • The triangle in action: http://scratch.mit.edu/projects/13134082/
  • They could be code you inherited from a legacy code-base.
  • They could be code you inherited from a legacy code-base.
  • They could be code you inherited from a legacy code-base.
  • They could be code you inherited from a legacy code-base.
  • They could be code you inherited from a legacy code-base.
  • Michael Feathers, NDC 2010
    The Deep Synergy Between Testability and Good Design
    http://vimeo.com/15007792

    http://michaelfeathers.typepad.com/michael_feathers_blog/2007/09/the-deep-synerg.html
  • http://martinfowler.com/bliki/TestPyramid.html
    http://martinfowler.com/bliki/StranglerApplication.html
    http://www.markhneedham.com/blog/2009/07/07/domain-driven-design-anti-corruption-layer/


  • http://martinfowler.com/bliki/TestPyramid.html
    http://martinfowler.com/bliki/StranglerApplication.html
    http://www.markhneedham.com/blog/2009/07/07/domain-driven-design-anti-corruption-layer/


  • Magic Tricks of Testing , Sendi Metz, https://speakerdeck.com/skmetz/magic-tricks-of-testing-railsconf

×