Refactoring test code


Published on

When you use Test Driven Development as a design approach in a software project, any change in the requirements should be adjusted first in the unit tests. Consequently, the test code quality and cleanness is as important as in the production code. This talk introduces the technique of test code refactoring as an approach to continuously improve the test code quality. It brings up some issues like “how to define test code behavior?” and “how to maintain test code behavior?”, and presents new test code refactorings and their respective classification.

Published in: Technology, Business
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Refactoring test code

  1. 1. Refactoring Test CodeEduardo Guerra
  2. 2. RefactoringCleaning the source code toimprove its design withoutchanging its externalbehavior.
  3. 3. Source code is simple tounderstand and canaddress only the currentrequirements. It is easier to maintain and evolve a simple and organized code structure.
  4. 4. But, does test code need to berefactored?
  5. 5. To add or changefunctionality you need to deal with existing tests!
  6. 6. “.. keep it (tests) at good object-oriented design, so than if we needto make a change or add somethingor kick something away , we onlyhave to do that in may be one placeand not in two hundred differentscripts.“ Lisa Crispin Author of “Agile Testing“ Software Engineering Radio Podcast
  7. 7. How can I How can I verifydefine what is maintainancethe test code of test code behavior? behavior?
  8. 8. Undestanding Tests
  9. 9. Test Target → instance usedA in the test. Action → changes environment or the Test Target. Assertion → comparison between the Test Target behavior and the expected one.
  10. 10. Test → a sequenceof at least one action and one assertion. A A
  11. 11. A AA A A A ATest Suite → a set of tests thatcan be independently executed.
  12. 12. A A A A A A AInitialization Finalization
  13. 13. Verification → a sequence of actions and one assertion dealing with the same target. A A A AA A A A A V1 V2
  14. 14. Two test suites can beconsidered equivalentwhen they perform the same verifications!
  15. 15. A A A A A A A AEquivalent! Same Verifications! A A A A A A A A A A A
  16. 16. Test Refactoring Classification
  17. 17. Test Method Test Class Test Suite
  18. 18. Test Method RefactoringsChanges actions and assertions for equivalent ones.
  19. 19. Test Method Refactorings● Add Assertion Explanation● Introduce Assertion Method● Simplify Test Scenario● Separate Action from Assertion● Decompose Assertion
  20. 20. Decompose Assertion@Test @Testpublic void needyEmployee{ public void needyEmployee{ Employee e = new Employee(); Employee e = new Employee(); e.setPayment(300); e.setPayment(300); assertTrue(“Employee Profile”, assertTrue(“Needy employee”, e.isNeedy() && e.isNeedy()); e.getDiscount() == 0); assertEquals(“Employee is free”,} e.getDiscount(), 0); }
  21. 21. Test Class RefactoringsReorganize actions and assertionsamong methods inthe same test class.
  22. 22. Test Class Refactorings● Add Fixture● Introduce Initialization Method● Inline Initialization Method● Join Incremental Tests● Split Test● Join Similar Tests with Distinct Data
  23. 23. Join Incremental@Test public void oneItem(){ cart.addItem(100); assertEquals(115,;} Tests@Test public void twoItens(){ cart.addItem(100); cart.addItem(100); assertEquals(200,;}@Test public void threeItens(){ cart.addItem(100); cart.addItem(100); cart.addItem(100); assertEquals(385,;} @Test public void insertItens(){ cart.addItem(100); assertEquals(115,; cart.addItem(100); assertEquals(200,; cart.addItem(100); assertEquals(385,; }
  24. 24. Test Suite Refactorings Reorganize testmethods among the test classes.
  25. 25. Test Suite Refactorings● Mirror Hierarchy to Tests● Pull Up Test● Pull Down Test● Create Template Test● Split Tests from Composition
  26. 26. <<abstract>> SuperClass +methodSuper() Mirror Hierarchy TestSubClass2 SubClass2 to Tests +testMethodSuper() +methodSub2() +testMethodSub2() TestSubClass1 SubClass1+testMethodSuper() +methodSub1()+testMethodSub1() <<abstract>> <<abstract>> TestSuperClass SuperClass +methodSuper() TestSubClass2 SubClass2 +testMethodSuper() +methodSub2() +testMethodSub2() TestSubClass1 SubClass1 +testMethodSuper() +methodSub1() +testMethodSub1()
  27. 27. Why testsmells appear?
  28. 28. Wrongstep size
  29. 29. Many increments inthe same test
  30. 30. Test code design evolves, like the production code design evolves!
  31. 31. Refactoring Test bar shouldProduction Code continue green But some bad smells can appear in the test code!
  32. 32. ROUND 1
  33. 33. They have something in common... Extract Superclass Pull Up Method
  34. 34. There are someduplicated tests there!
  35. 35. Refactoring the tests! Mirror Hierarchy to Tests Add Fixture Pull Up Test
  36. 36. ROUND 2
  37. 37. ScheduledExecution duplicate some Action functionality. Move Logic to Delegate
  38. 38. The test is now covering one possible composition of ScheduledExecution, but it can becomposed by any Executor subclass! Split Tests From Composition
  39. 39. Refactoring Knockout
  40. 40. Refactorings thatchange the classesstructure usuallycreate a test bad smell!
  41. 41. Future Vision of Test Code Refactoring
  42. 42. AutomateTest RefactoringsCreation of an Eclipse plugin toautomate test refactorings andbad smell detectionindependently from the testframework.
  43. 43. Verify Test BehaviorMaintainance with Mutants Create a tool that executes tests on test target mutants before and after the refactoring to verify if the test behavior was changed.
  44. 44. “Unlike production code, which youdont have a choice but to maintain,tests are optional, you can alwaysstop running them and just throwthem away, and any investmentthat you made (...) are just throwout the window.“ Gerard Meszaros Author of “xUnit Test Patterns“ Software Engineering Radio Podcast