The document discusses Quilt, a new test-oriented programming language that aims to improve on current mock-driven development approaches. Quilt uses static analysis at the compiler level to automatically isolate and stub dependencies for the code under test, reducing the amount of test code needed. It focuses on stubbing methods rather than full objects. This lower coupling between tests and code makes testing easier and helps avoid issues like overlapping test states.
7. How is Quilt Different
Stub methods not classes
Compiler significantly reduces the amount of test code
that must be written to provide isolation
Friday, 25 March 2011
9. What are the motivations for
mock driven development?
Friday, 25 March 2011
10. State based tests inevitably
overlap
!"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
11. This makes it hard to
diagnose the source of a
break. !"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
12. The solution is to use mock
objects to provide substitute
interactions that we can
assert from our test !"#$%&'($%
!"#$%&'($%
Friday, 25 March 2011
15. “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
33. Testing units can be one or
many classes: a Patch
91,''#'%,2#%)2.60#5% +,&-"#'%,2#%'#0,2,%
*$&.%,%:+,&-";% 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. There is no need for
dependency injection for the
purpose of testing
Friday, 25 March 2011
37. Compilation Ensures that
Stubs are Required only if
they Affect the Output of the
Test.
Friday, 25 March 2011
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. !"#$!#%&$
'()*)+$
@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. 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. !"#$!#%&$
'()*+&,$
shouldBuildFoundationsWithLotsOfBricksAndSlowDryi
ngCement(){
Seam:
cement.isSolid() returns false;
bricks.size returns 100;
AssertTrue:
new ConstructionSite().buildFoundation(..);
}}
Friday, 25 March 2011
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. Stub Methods not Objects
shouldBuildFoundationsWithLotsOfBricksAndSlowDryi
ngCement(){
Seam:
cement.isSolid() returns false;
bricks.size returns 100;
AssertTrue:
new ConstructionSite().buildFoundation(..);
}}
Friday, 25 March 2011
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. The unit under test should
be more than one class
91,''#'%,2#%)2.60#5% +,&-"#'%,2#%'#0,2,%
*$&.%,%:+,&-";% 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. Quilt Test: Running multiple
patches together
!"#$%&'()%&
Friday, 25 March 2011
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
class
Friday, 25 March 2011