test-oriented languages: is it time for a new era?

Post on 27-May-2015

2.217 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

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,&#5%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,&#5%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