test-oriented languages: is it time for a new era?
Post on 27-May-2015
2.217 Views
Preview:
DESCRIPTION
TRANSCRIPT
Test-Oriented Languages: is it time for a new era?Ben Stopford : The Royal Bank of Scotland
Friday, 25 March 2011
Mocking is fundamental part of Test Driven Development
Friday, 25 March 2011
But how much further can we go in current imperative languages?
Friday, 25 March 2011
What might we improve if we were not inhibited by current mainstream compilers?
Friday, 25 March 2011
What might we do with a blank slate?
Friday, 25 March 2011
Quilt
Friday, 25 March 2011
Stub methods not classes
Compiler significantly reduces the amount of test code that must be written to provide isolation
How is Quilt Different
Friday, 25 March 2011
Taking step back...
Friday, 25 March 2011
What are the motivations for mock driven development?
Friday, 25 March 2011
State based tests inevitably overlap
!"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
This makes it hard to diagnose the source of a break.
!"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
The solution is to use mock objects to provide substitute interactions that we can assert from our test !"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
Current Challenges
Friday, 25 March 2011
Coupling between test and source
Friday, 25 March 2011
“I've always been a old fashioned classic TDDer and thus far I don't see any reason to change. I don't see any compelling benefits for mockist TDD, and am concerned about the consequences of coupling tests to implementation.”
Friday, 25 March 2011
The JMock Era
Friday, 25 March 2011
Mock Interactions
Friday, 25 March 2011
All interactions must be explicitly coded in the test
!"#$%&'($%
Friday, 25 March 2011
The Mockito Era
Friday, 25 March 2011
Only mock interactions you care about
!"#$%&'($%
Friday, 25 March 2011
This reduces coupling between test and class
Friday, 25 March 2011
Quilt takes this concept further by only requiring methods to be stubbed not whole objects (but more on that later)
Friday, 25 March 2011
To do Mock-Driven development you need to test first
The Testing Barrier
Friday, 25 March 2011
Should it be like this?
Friday, 25 March 2011
In quilt it’s as easy to test after as it is to test first
!"#$%&'($%
Friday, 25 March 2011
What Makes Quilt Different?
Friday, 25 March 2011
The complier isolates testable units for you.
Where it needs your input it requires that you provide it.
Friday, 25 March 2011
So when you run a test the compiler will restrict the execution scope, say to a single class
!"#$%&'($%
Friday, 25 March 2011
If that class under test calls other classes the compiler will automatically isolate the interactions
!"#$%&'($%
Friday, 25 March 2011
If those interactions return state then the compiler requires that a active stub be declared in the test
!"#$%&'($%
Friday, 25 March 2011
So quilt creates seams around the testable unit isolating the functionality under test !"#$%&
Friday, 25 March 2011
Methods are Stubbed not Objects
!"#$%&'($%
Friday, 25 March 2011
Testing units can be one or many classes: a Patch
!"#$%&#'($)%&"*'%+,&-"%&"#%-./0*1#2%3*11%4.2-#%&"#%5#-1,2,(.$%.4%,%'&677#5%2#&62$%&80#%4.2%&"*'%/#&".5%
91,''#'%,2#%)2.60#5%*$&.%,%:+,&-";%
+,&-"#'%,2#%'#0,2,%78%:<#,/';%
Friday, 25 March 2011
There is no need for dependency injection for the purpose of testing
Friday, 25 March 2011
The barrier for testing is lowered
Friday, 25 March 2011
Looking more closely
Friday, 25 March 2011
Compilation Ensures that Stubs are Required only if they Affect the Output of the Test.
Friday, 25 March 2011
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
@TestshouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){ 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
In all this mock/stub setup only two parts are actually pertinent to the test:
@TestshouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){ 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
shouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){
Seam: cement.isSolid() returns false; bricks.size returns 100;
AssertTrue: new ConstructionSite().buildFoundation(..);}}
!"#$!#%&$'()*+&,$
Friday, 25 March 2011
No need to set up stub objects
shouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){
Seam: cement.isSolid() returns false; bricks.size returns 100;
AssertTrue: new ConstructionSite().buildFoundation(..);}}
Friday, 25 March 2011
Stub Methods not Objects
shouldBuildFoundationsWithLotsOfBricksAndSlowDryingCement(){
Seam: cement.isSolid() returns false; bricks.size returns 100;
AssertTrue: new ConstructionSite().buildFoundation(..);}}
Friday, 25 March 2011
Avoiding mock object chains
input.do().do().do() returns “foo”;
Friday, 25 March 2011
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
The unit under test should be more than one class
!"#$%&#'($)%&"*'%+,&-"%&"#%-./0*1#2%3*11%4.2-#%&"#%5#-1,2,(.$%.4%,%'&677#5%2#&62$%&80#%4.2%&"*'%/#&".5%
91,''#'%,2#%)2.60#5%*$&.%,%:+,&-";%
+,&-"#'%,2#%'#0,2,%78%:<#,/';%
Friday, 25 March 2011
Quilt Test: Running multiple patches together
!"#$%&'()%&
Friday, 25 March 2011
Quilt: A new approach to testing
Compiler stubs as much as possible
Compiler forces the isolation of the code under test
Methods are mocked not objects
There is no need to create mock or stub objects and inject them into the test
Developer needs to write the absolute minimum amount of test code
Can even test an existing class
Friday, 25 March 2011
top related