TDD and Real Options

A couple of days ago I watched the fantastic “TDD as if you really meant it” session by Keith Braithwaite on Infoq. I highly recommend it even if you are not a developer ( writer of code ).

I love the simplicity of the process that Keith tells the session attendees to adopt. It is a great exercise in emergent design that highlights how easily developers make assumption about the design rather than let it emerge.

The only thing I questioned was Keith’s suggestion that the developers start “anywhere”. As Keith said this my immediate response was “Start with the ouputs”. I commented on the InfoQ article as such.

I got the impression that a number of the people in the session started with the inputs. They soon ran into problems and started making assumptions about the design. This is exactly the opposite of the Feature Injection process which starts with the outputs. A colleague ( developer ) and I started going through the Tic-Tac-Toe exercise using pseudo-code. (I’m hoping to complete the exercise using C#).

As we worked through the exercise starting from the outcome ( Game Over ) and working into the functions ( isWon, isStaleMate ) generating Mocks as we went along, we suffered from none of the problems that the people in the session encountered. We had none of the desire to make assumptions about the design. More importantly, we quickly encountered the fundamental domain questions about Tic-Tac-Toe ( 3×3 Grid? 4×4 grid? 3 dimensional grid? ). How do we test to make sure the isWon works properly. Issues about inputs were not even discussed. Issues about display were not discussed. We had lots of options. We drove right into the riskiest part of the development from a domain perspective.

Previously I have never commented on TDD but it seems to me that TDD should also start with the outputs and work to the inputs. In effect, Feature Injection, should be injected into TDD.

I’m waiting for the flames!

Disclaimer – I assume someone else has already said this but I just am not aware of it.

I will post the code when I do it in C#

Pseudo Code: Code in red

Test 1 – isFinished is TRUE

iSFinished() return True

Test 2 – isFinished returns FALSE

isFinished() return game.Finished()

Create mock game.isFinished returns False

Test 1 Fails. Refactor test 1 to use Mock game.isFinished returns True

Test 3 – game.isFinished is TRUE

game.isFinished() return TRUE

Test 4 – game.isFinished is FALSE ( GIVEN NOT isStaleMate AND NOT isWon WHEN game.IsFinished THEN FALSE )

gameisFinished()

if game.isWon() || game.staleMate() then

    return TRUE

else

    return FALSE

2 Mocks game.isWon() returns FALSE and game.isStaleMate() returns FALSE

Test 5 – game.isFinished is TRUE, isStaleMate ( GIVEN isStaleMate WHEN game.IsFinished THEN TRUE )

2 Mocks game.isWon() returns FALSE and game.isStaleMate() returns TRUE

Test 6 – game.isFinished is TRUE, isWon ( GIVEN isWon WHEN game.IsFinished THEN TRUE )

2 Mocks game.isWon() returns TRUE and game.isStaleMate() returns FALSE

Test 7 – Test 7 – game isFinished is TRUE, isWon and isStaleMate ( GIVEN isWon and isStalemate WHEN game.IsFinished THEN throw exception )

2 Mocks game.isWon() returns TRUE and game.isStaleMate() returns TRUE

gameisFinished()

if game.isWon() || game.staleMate() then

    return TRUE

elseif NOT(game.isWon() )&&NOT(game.staleMate()) then

    return FALSE

else

raise exception (“Its broken because it should be possible to win and be in stalemate”)

The coding finishes when all the mocks are all implemented.

Coding to be continued…

Note that the GIVEN WHEN THEN calls out the Mocks to use. Mocks were the inspiration for the pattern.

Notes:

 

Tic Tac Toe ( Winning )      
1 1     1     1  
2 1       1     1
3 1         1    
4   1   1        
5   1     1   1 1
6   1       1    
7     1 1        
8     1   1     1
9     1     1 1  

Display

 

1 2 3
4 5 6
7 8 9

 

About theitriskmanager

Currently an “engineering performance coach” because “transformation” and “Agile” are now toxic. In the past, “Transformation lead”, “Agile Coach”, “Programme Manager”, “Project Manager”, “Business Analyst”, and “Developer”. Did some stuff with the Agile Community. Put the “Given” into “Given-When-Then”. Discovered “Real Options” View all posts by theitriskmanager

14 responses to “TDD and Real Options

  • Jon Jagger

    starting with the output also has a nice echo of pull rather than push (in the kanban sense – although as we both know, kanban sucks 😉

  • talboomerik

    First time people try this technique they start focusing on the simplest thing which is the input. After a while you’ll see that people start realizing that they should really focus on the pure behavior of the system. In most cases this means that people need to start thinking outside in instead of inside out.

    I’ve seen the same struggle when people try to write Conway’s game of life and starting from the inside out. The whole idea of this technique is that you don’t assume anything upfront. So there is no inside out option. That’s why I always suggest people to start from the rules of the game, what happens when a generation moves to a new stage.

    I like your post and I’m curious about your implementation in C#. If I can just give you one piece of advice on how you can make this even better. Try to write your tests in a more natural naming. If your tests are more descriptive, your implementation will probably be more descriptive as well and you end up with a better naming all over the system.

  • Jérôme Avoustin

    Hi Chris,

    I remember Kent Beck’s book “TDD by Example”.
    One of the best advices I remembered is that when writing a test, it’s better to start writing the assertions before anything else.

    What I felt when I read this is that the concept about starting with output is deep into TDD mindset

  • stefanhendriks

    Recently I built a feature from the ‘outside’ to the ‘inside’. And it brought a much simpler design with it.

    One thing you have to keep in mind though, in this case you have a few mocks and you implement them later. But, in a ‘realworld’ solution you can have multiple mocked objects. You need to be aware that when you start implementing one of them you might also introduce new mock objects.

    All in all, keep a track of the mocked objects as you go. You might forget some.

    Funny thing is, if you actually return stubbed data, you can actually see it working in your application. The more you implement the mocks(stubs), the more you’re using ‘real’ data and the more the stubs are being removed in favor of the real deal.

    If you’re rely on third party services, stubbing them out is a great way to keep on working while they fix their servers.

    Great post. One tip: You could perhaps use some code format, as it reads a bit tough.

    • Steve Freeman

      A slight confusion over terminology, by “mocks” you mean hard-coded stubs? Otherwise, a good point.

      • stefanhendriks

        The correct answer would be “depends”. They are mocks in my tests, but they are stub(s) when running the real application. This way I can run the application, see how it behaves.

        In this case, I had data that would eventually be taken from a 3rd party webservice. But 90% of the time it was stubbed. Only at the last moment I actually called the webservice layer (which I knew was working, because it was tested on its own) and it all worked flawlessly.

        So in short:
        1. First the view (JSP ) shows a stubbed view object (ie, just showing data
        2. Then the view object got created by a mapper. THe mapper would be returning the stubbed VO first
        3. Actually implement the mapper
        4. Stub the result from the webservice, since the mapper works (ie, tested) it still shows me the same result
        5. The webservice method is now returning a stubbed result. The ‘web application’ basically is finished. Now its time to get the webservice client working.

        Basically from there I would be implementing the webservice practically the same way. I had an integration test to make sure it really worked. Once that worked, I could use the actual implementation and it worked! 🙂

  • Fredrik Wendt

    When I teach TDD to people unfamiliar to unit testing, I make sure they understand the point your making. I typically reference to this as writing the 3 A bottom up: start with Assertion – what do you want to achieve? Then the Act – what’s going to achieve this? Then Arrange as needed.
    The business value lie in assert+act, so that should be the focus when writing a test = write the test bottom up.

  • J. B. Rainsberger

    I absolutely teach everyone that the output of the system is what matters, so start there. This is also why I teach writing tests starting with the assertion: focus on what you want to check, then figure out what you need to compute it. This is also why I teach designing starting with the client: focus on what the client needs, then figure out how to provide it simply. This avoid unnecessary code.

    It works.

  • Steve Freeman

    Yes, we did say it before 🙂

  • Zsolt Fabok (@ZsoltFabok)

    Interesting idea, thanks Chris! I’ll try it out next time when I have a chance.

  • Guillaume

    Chris,

    Shouldn’t we call that approach to TDD “outcome first” rather than “output first” ?

    To me a winning board (or a tie board) is the outcome of a game of TTT, not necessarily the (only) output. If we see the game as a product, from a customer perspective, wouldn’t there be other outputs the customer is interested in ? What about a game in progress ? What about a blank board (first thing user sees when he logs on to the game) ?

    Even if it so happened that no user of the TicTacToe product ever managed to finish a game, wouldn’t they still need those outputs in the first place ?

    The kind of TDD you describe certainly works for programs that have a single identified outcome, such as computations that produce one result, games with a winner, etc. But we know this is not the case with all programs.

    Anyway, very interesting article, makes me want to try it that way. And I’d be really interested in seeing your actual code 😉

  • 52e session du Coding Dojo du 07/02/2012(Salle H.201) - Club Agile Rhône-Alpes : Club Agile Rhône-Alpes

    […] du TDD en sa basant sur les sorties plutôt que les entrées comme indiqué dans l’article TDD and Real Options. Nous entraînerons sur le défi tu […]

  • Rétrospective 2014Agilité, Architecture, C++ "in the mix"

    […]  TDD avec real-options sur l’exercice Elephant Carpaccio […]

Leave a comment