Test-Oriented Languages: Is it time for a new era?

2,815 views

Published on

Where is TDD going next? Mock Methods not Objects?

There are many good reasons for using TDD in it’s ‘mockist’ form and you tend to build better software as as result. However there’s still a lot of overhead involved in creating mock and stub objects and passing them around. It makes the approach less accessible, more elitist and harder to integrate into a project if all the devs aren’t indoctrinated with the approach.

The slides below throw around some ideas for how we might do things differently. At it’s core is the concept of mocking methods rather than objects along with a compilation process that forces isolation.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,815
On SlideShare
0
From Embeds
0
Number of Embeds
1,033
Actions
Shares
0
Downloads
14
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Test-Oriented Languages: Is it time for a new era?

  1. 1. Test-Oriented Languages: is it time for a new era? Ben Stopford : The Royal Bank of ScotlandFriday, 25 March 2011
  2. 2. Mocking is fundamental part of Test Driven DevelopmentFriday, 25 March 2011
  3. 3. But how much further can we go in current imperative languages?Friday, 25 March 2011
  4. 4. What might we improve if we were not inhibited by current mainstream compilers?Friday, 25 March 2011
  5. 5. What might we do with a blank slate?Friday, 25 March 2011
  6. 6. QuiltFriday, 25 March 2011
  7. 7. How is Quilt Different Stub methods not classes Compiler significantly reduces the amount of test code that must be written to provide isolationFriday, 25 March 2011
  8. 8. Taking step back...Friday, 25 March 2011
  9. 9. What are the motivations for mock driven development?Friday, 25 March 2011
  10. 10. State based tests inevitably overlap !"#$%&($% !"#$%&($%Friday, 25 March 2011
  11. 11. This makes it hard to diagnose the source of a break. !"#$%&($% !"#$%&($%Friday, 25 March 2011
  12. 12. The solution is to use mock objects to provide substitute interactions that we can assert from our test !"#$%&($% !"#$%&($%Friday, 25 March 2011
  13. 13. Current ChallengesFriday, 25 March 2011
  14. 14. Coupling between test and sourceFriday, 25 March 2011
  15. 15. “Ive always been a old fashioned classic TDDer and thus far I dont see any reason to change. I dont see any compelling benefits for mockist TDD, and am concerned about the consequences of coupling tests to implementation.”Friday, 25 March 2011
  16. 16. The JMock EraFriday, 25 March 2011
  17. 17. Mock InteractionsFriday, 25 March 2011
  18. 18. All interactions must be explicitly coded in the test !"#$%&($%Friday, 25 March 2011
  19. 19. The Mockito EraFriday, 25 March 2011
  20. 20. Only mock interactions you care about !"#$%&($%Friday, 25 March 2011
  21. 21. This reduces coupling between test and classFriday, 25 March 2011
  22. 22. Quilt takes this concept further by only requiring methods to be stubbed not whole objects (but more on that later)Friday, 25 March 2011
  23. 23. The Testing Barrier To do Mock-Driven development you need to test firstFriday, 25 March 2011
  24. 24. Should it be like this?Friday, 25 March 2011
  25. 25. In quilt it’s as easy to test after as it is to test first !"#$%&($%Friday, 25 March 2011
  26. 26. What Makes Quilt Different?Friday, 25 March 2011
  27. 27. The complier isolates testable units for you. Where it needs your input it requires that you provide it.Friday, 25 March 2011
  28. 28. So when you run a test the compiler will restrict the execution scope, say to a single class !"#$%&($%Friday, 25 March 2011
  29. 29. If that class under test calls other classes the compiler will automatically isolate the interactions !"#$%&($%Friday, 25 March 2011
  30. 30. If those interactions return state then the compiler requires that a active stub be declared in the test !"#$%&($%Friday, 25 March 2011
  31. 31. So quilt creates seams around the testable unit isolating the functionality under test !"#$%&Friday, 25 March 2011
  32. 32. Methods are Stubbed not Objects !"#$%&($%Friday, 25 March 2011
  33. 33. Testing units can be one or many classes: a Patch 91,#%,2#%)2.60#5% +,&-"#%,2#%#0,2,&#5% *$&.%,%:+,&-";% 78%:<#,/;% !"#$%&#($)%&"*%+,&-"%&"#% -./0*1#2%3*11%4.2-#%&"#% 5#-1,2,(.$%.4%,%&677#5% 2#&62$%&80#%4.2%&"*%/#&".5%Friday, 25 March 2011
  34. 34. There is no need for dependency injection for the purpose of testingFriday, 25 March 2011
  35. 35. The barrier for testing is loweredFriday, 25 March 2011
  36. 36. Looking more closelyFriday, 25 March 2011
  37. 37. Compilation Ensures that Stubs are Required only if they Affect the Output of the Test.Friday, 25 March 2011
  38. 38. class ConstructionSite{ Digger digger = new Digger(); Mixer mixer = new CementMixer(); !"#$%&(($ Foreman foreman = new Foreman(); ConstructionSite(){} ConstructionSite(Digger d, Mixer m, Foreman f){ digger = d; mixer = m; foreman = f; } boolean buildFoundation(Bricks bricks){ Cement cement = mixer.mix(); Foundation foundation = digger.dig(); BrickLayer layer = foreman.getLayer(); if(!cement.isSolid() && bricks.size()> 100){ Posts posts = layer.lay(bricks, cement); foundation.fill(posts); return true; } return false; } }Friday, 25 March 2011
  39. 39. !"#$!#%&$ ()*)+$ @Test shouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){ Digger digger = mock(Digger.class); CementMixer mixer = mock(CementMixer.class); Foreman foreman = mock(Foreman.class); Cement cement = mock(Cement.class); BrickLayer layer = mock(BrickLayer.class); Foundation foundation = mock(Foundation.class); when(mixer.mix()).thenReturn(cement); when(digger.dig()).thenReturn(foundation); when(cement.isSolid ()).thenReturn(Boolean.FALSE); when(foreman.getLayer()).thenReturn(layer); ConstructionSite site = new ConstructionSite(digger, mixer, foreman); assertTrue(site.buildFoundation(new Bricks(101))) }Friday, 25 March 2011
  40. 40. In all this mock/stub setup only two parts are actually pertinent to the test: @Test shouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){ Digger digger = mock(Digger.class); CementMixer mixer = mock(CementMixer.class); Foreman foreman = mock(Foreman.class); Cement cement = mock(Cement.class); BrickLayer layer = mock(BrickLayer.class); Foundation foundation = mock(Foundation.class); when(mixer.mix()).thenReturn(cement); when(digger.dig()).thenReturn(foundation); when(cement.isSolid ()).thenReturn(Boolean.FALSE); when(foreman.getLayer()).thenReturn(layer); ConstructionSite site = new ConstructionSite(digger, mixer, foreman); assertTrue(site.buildFoundation(new Bricks(101))) }Friday, 25 March 2011
  41. 41. !"#$!#%&$ ()*+&,$ shouldBuildFoundationsWithLotsOfBricksAndSlowDryi ngCement(){ Seam: cement.isSolid() returns false; bricks.size returns 100; AssertTrue: new ConstructionSite().buildFoundation(..); }}Friday, 25 March 2011
  42. 42. No need to set up stub objects shouldBuildFoundationsWithLotsOfBricksAndSlowDryi ngCement(){ Seam: cement.isSolid() returns false; bricks.size returns 100; AssertTrue: new ConstructionSite().buildFoundation(..); }}Friday, 25 March 2011
  43. 43. Stub Methods not Objects shouldBuildFoundationsWithLotsOfBricksAndSlowDryi ngCement(){ Seam: cement.isSolid() returns false; bricks.size returns 100; AssertTrue: new ConstructionSite().buildFoundation(..); }}Friday, 25 March 2011
  44. 44. Avoiding mock object chains input.do().do().do() returns “foo”;Friday, 25 March 2011
  45. 45. Static analysis lies at the heart of the Quilt compiler The compiler tracks the state used in the class under test. A bottom up analysis technique allows the compiler to exclude cross seam calls that cannot affect the test output.Friday, 25 March 2011
  46. 46. The unit under test should be more than one class 91,#%,2#%)2.60#5% +,&-"#%,2#%#0,2,&#5% *$&.%,%:+,&-";% 78%:<#,/;% !"#$%&#($)%&"*%+,&-"%&"#% -./0*1#2%3*11%4.2-#%&"#% 5#-1,2,(.$%.4%,%&677#5% 2#&62$%&80#%4.2%&"*%/#&".5%Friday, 25 March 2011
  47. 47. Quilt Test: Running multiple patches together !"#$%&()%&Friday, 25 March 2011
  48. 48. Quilt: A new approach to testing Compiler stubs as much There is no need to as possible create mock or stub objects and inject them Compiler forces the into the test isolation of the code under test Developer needs to write the absolute minimum Methods are mocked not amount of test code objects Can even test an existing classFriday, 25 March 2011

×