Archive for the ‘BDD’ category

BDD and "How Are You Going to Use That Information"

September 7, 2007

 

Fred George has a post called “And How Are You Going to Use That Information?” that strikes at the heart of the analysis practices in Behavior Driven Development.

I’ve been looking for a question like, “and how are you going to use that information”.  My team is probably going to get really fed up hearing this particular question as I often use variants of it when trying to drive home the importance of BDD to YAGNI-avoidance.  Fred’s way makes it much easier for me.

Here’s an example from a recent release planning meeting:

Other: I’d like to see the current SVN build stamp in the footer of the app’s web pages.
Me: Why?
Other: So I can include it in feedback on the pre-alpha previews.
Me: Can you give me a story for that?

My assumption here is that once the story is surfaced, the person I’m speaking with will see that the feature won’t be valuable.

Here’s a the same conversation (theoretically) from Fred’s universe:

Other: I’d like to see the current SVN build stamp in the footer of the app’s web pages.
Me: Why?
Other: So I can include it in feedback on the pre-alpha previews.
Me: And how are we going to use that information?
Other: To track which release the feedback applies to (presumably).

Since we’ve got an extremely small number of people in our preview pool (less than 10 presently), and since we’ve got very little functionality released for preview, the build number won’t really help with the actions that we take based on feedback.

With such a small dev team, and so few previewers, and so little functionality, it’s near impossible for anyone who is invested in the project to not know what feedback pertains to.

The build number stamp is superfluous to our ability to respond to feedback and take action based on the feedback.  Our review of the inbound feedback, and the prioritization of tasks happens as a matter of agile planning, which is an information-immersive negotiation for stakeholders and designers.

No one could possibly not know what the feedback pertains to and therefore having further qualification by build number doesn’t enable us to fulfill our responsibilities any better.  It does however arbitrarily cost us the time of implementing the build number stamp.

This information might be useful to us later – when we have more releases, more features, more feedback, etc.  If we were to put in the effort to build it now, we would – in Lean terms – be incurring inventory cost.

Asking “How are you going to use that information” forces us to look at the behaviors that capitalize on that information, or that are enabled by that information.  When we just declare that we need some piece of information or other without justifying it with a concrete user story, we’re just doing model-driven or data-driven design.

When I focus first on behaviors – especially user goals as expressed based on scenarios with realistic context – the understanding of the necessary data will simply become clear and evident.  If I get distracted in the details of data-driven and model-driven analysis, I run a really high risk of accumulating unneeded inventory and its associated costs.

Drill down on behaviors.  Find out if they are real and substantial, and then figure out the data needs.  Starting at data is often a crap shoot at best.  Behaviors will surface data needs, but the opposite is almost never true – not in any substantial and meaningful way that works against incurring inventory in any case.

BDD and “How Are You Going to Use That Information”

BDD, TDD, and the other Double D’s

September 7, 2007

 

Behavior Driven Development (BDD) has been a pretty big topic in some of the email groups I lurk in.  I’m seeing BDD cast as a whole new paradigm of development, where as I see BDD as an evolution of TDD with a better syntax and mechanics for expressing the desired functionality with tests/specifications.  That’s more than enough advantages to jump into BDD and plenty to be excited about, but not enough to designate BDD as a whole new paradigm.  Andy Glover described BDD as TDD Done Right and I concur.

Part of the impetus to move to BDD is appealing to people who were always turned off by TDD.  That’s great, but I’m seeing people trying to skip the “driving a design through unit tests” discipline part of TDD to skip right to executable requirements at the acceptance level.  Jeremy, you might say, that’s just some useless terminology from Agile yesterday that we need to let go of!  That’s not baggage so much as it’s a set of hard lessons learned. 

Any testing/specification is better than no testing/specification, but in 4+ years of practicing TDD I’ve learned over and over again that it’s more efficient to write fine-grained unit tests first before proceeding on to making the acceptance and integration tests pass.  It’s great to have the business facing tests/specifications written before coding, but you don’t work with them until you’re reasonably confident from unit tests.  It’s all about the feedback cycle and reducing a big problem into small, manageable parts.  It’s easier to shake out most of the problems with the code at the unit level first than it is to try to code up to a big coarse grained test first.  If you try to skip right to coarse grained tests you’re likely to spend some time in debugger jail.  I’ll scream until I’m hoarse that it’s best, and even more efficient in developer time, to do multiple levels of testing instead of only coarse grained tests.

Besides, if you want to know how to code in a way to make BDD succeed at both the unit and acceptance levels, you’re going to end up learning almost all of the lessons we TDD practitioners have already faced.  Don’t even think about ditching all of the TDD design lore when you move to BDD.  Besides, those cool executable requirements specifications in xBehave?  They’ll work a lot smoother if your code is testable (loosely coupled, highly cohesive) and there’s already quite a bit of lore on how to do that in the TDD canon.

How many of these Double D’s do I need?  How “Driven” must I be?

While technically you need zero of the Double D’s to deliver working code, many of the xDD practices and methods are quite complementary.  Rebecca Wirfs-Bock has a nice summary of many of the Double D’s.  I’ll take my own crack at how the Double D’s are different and where they complement each other:

  • Test Driven Development / Behavior Driven Development – Low level design, unit testing as well.  Should lead to low level specifications for the code, especially with BDD.
  • Acceptance Test Driven Development – Capturing business requirements as executable tests.  Do NOT confuse this with TDD/BDD.  Not all that common in practice, but highly advantageous.
  • Responsibility Driven Development – A design technique that puts an emphasis on the assigning of responsibilities to the consituent classes in an OOP system with plenty of terminology for identifying and classifying responsibilities.  I think RDD is a perfect complement to TDD/BDD because of its lightweight nature
  • Domain Driven Design – The Domain Model pattern done right for logic intensive systems.  DDD is also a natural ally of TDD because it leads to a system that’s far easier to drive through unit tests than a traditional n-Tier system written in a procedural Transaction Script style.  RDD is also a natural complement to DDD to help guide the assignment of responsibilities between entities and services.
  • Model Driven Development – I threw this one in just to be complete, but it’s coming from a completely different world view than the other Double D’s, and I’ve always been dubious on this one.  I suppose DDD could easily be combined with MDD.  I used to worry that I was in danger of missing the boat if it really took off, but that thought hasn’t crossed my mind for years.  Go make up your own mind

BDD, TDD, and the other Double D’s

Design vs. Coding – How Much Is Too Much?

September 7, 2007

 

A while ago I got asked the following question:

I’ve been wondering something about
OOD that perhaps many developers think about, and that is the
relationship between the amount of time used for design (eg. drawing
UML) and actual coding.
What’s your take on this? Do you like to design everything from the
high-level till the ground-level with UML? What UML diagrams you find
most usefull? Or do you think that using pure TDD makes UML somewhat
obsolete?

Since I got introduced to agile methods, I was also introduced very early to the concept of “code” as a design tool. To be more specific, this is the concept that everyone has come to know formally as Test Driven Development. When practicing TDD/BDD the goal is to write the test before the code that you are wanting to create actually exists. Don’t forget what we are doing here, we are writing “code” for “code” that does not yet exist. This gives us a completely blank slate to work with. This allows us to code the object with the exact “behaviors” that we would want it to exhibit and the API through which we interact with it. After you have been doing TDD for a while the “explicit thought” of “I should write a test” becomes a habit, so you write the test first without even thinking about it. This is great. When you have been doing TDD for a while.

The problem lies for the people who are fresh into TDD and they are still in that uncomfortable period where it does not yet feel natural to write the test first. As much as TDD is about design it is also about “moving ahead”. When you find yourself staring at a screen and lost for which direction to drive out a test the answer is simple “Get Up In Front Of A WhiteBoard and Draw!!!” (I am making the assumption here that you have already tried talking with your team and you are all collectively at a loss for where to begin). If you are feeling stuck and unable to move ahead one of the following diagrams :

  • UML Class Diagram
  • UML Sequence Diagram

may help to generate some ideas in your head that can serve as a starting point for helping you to drive out the test. Of all of the UML diagrams, the only ones I find myself using anymore are:

  • UML Class Diagram
  • UML Sequence Diagram
  • UML State Diagram

Even on teams of experienced agile practitioners, it can often be beneficial to whiteboard an high level idea that you are having to quickly share information with the team and solicit feedback. These should be quick sanity check sessions where you are just brainstorming. It is not a 2 hour session where you are drawing out a complicated class/sequence diagram that will almost definitely not correlate to the resulting code that is produced. 

One of the most effective tools that a developer has in their arsenal to convey design ideas quickly (aside from unit tests) is a whiteboard and marker. So even though you may currently feel stuck with respects to which direction to take test; the act of getting up and trying to draw down a quick UML sketch can get the creative juices flowing and provide you with the ammo and direction with which to get back to the computer and start writing the test. Which is ultimately the design exercise you want to move to, as it is a “specification” that is able to adapt to the code that it is targeting (unlike a static UML diagram).

People starting out in TDD get very uncomfortable when they are often faced with the realization that the design skills they thought they had are actually not really that proficient. TDD brings this to the forefront because design is something that is being done constantly. Most developers that I know who are familiar with UML are able get in front of a whiteboard and come up with a quick sketch of a proposed object model they are thinking about. Put the majority of those developers in front of studio with an test fixture and they often flounder.

It is time that people started developing a different set of design skills. The skill of designing an application by “coding in reverse”. One of the best ways I try to describe TDD when I am pairing with someone is to “code it like it’s there and it has the exact API that you want to use”. Once people can take that phrase and literally apply it to a test they are writing for an object; they have crossed , IMHO , the largest learning gap on the road to effective TDD.

Do I think that design is dead? Absolutely not. TDD is first and foremost about design, not testing. It is a practice that requires discipline on the part of all the members of a development team. One of the startling revelations that people who are skeptical about TDD encounter when introduced into a team practicing it, is that the emphasis on solid design is actually much higher than other teams they have been a part of. Why? Because design is something that is happening almost every minute of every iteration. Developers working on stories are driving out the design of components one test at a time. They are driving out the communication between disparate layers in the system one test at a time. All of these “design” artifacts brought together with the accompanying implementation code, over the course of (x) iterations result in a piece of software that has been actively designed and developed over the entire lifecycle.

At the end of the day, I no longer see any value in BDUF. Let me stress this point, “this does not mean you turn a blind eye to changes that are coming in future iteration that may (most likely will) require change”. More importantly you build the system with tests as a design tool that enable you to keep your objects following:

  • Single Responsibility Principle
  • HollyWood Principle
  • Dependency Inversion principle
  • …….

This will ensure that when change comes (and it will) the effort required to  accomodate the change will not be a negative one. And will you be able to drive out the “design” and implementation of the change by following a set of repeatable practices that eventually will become second nature for you, if you stick with it.

Design vs. Coding – How Much Is Too Much?

BDD and "How Are You Going to Use That Information"

September 4, 2007

 

Fred George has a post called “And How Are You Going to Use That Information?” that strikes at the heart of the analysis practices in Behavior Driven Development.

I’ve been looking for a question like, “and how are you going to use that information”.  My team is probably going to get really fed up hearing this particular question as I often use variants of it when trying to drive home the importance of BDD to YAGNI-avoidance.  Fred’s way makes it much easier for me.

Here’s an example from a recent release planning meeting:

Other: I’d like to see the current SVN build stamp in the footer of the app’s web pages.
Me: Why?
Other: So I can include it in feedback on the pre-alpha previews.
Me: Can you give me a story for that?

My assumption here is that once the story is surfaced, the person I’m speaking with will see that the feature won’t be valuable.

Here’s a the same conversation (theoretically) from Fred’s universe:

Other: I’d like to see the current SVN build stamp in the footer of the app’s web pages.
Me: Why?
Other: So I can include it in feedback on the pre-alpha previews.
Me: And how are we going to use that information?
Other: To track which release the feedback applies to (presumably).

Since we’ve got an extremely small number of people in our preview pool (less than 10 presently), and since we’ve got very little functionality released for preview, the build number won’t really help with the actions that we take based on feedback.

With such a small dev team, and so few previewers, and so little functionality, it’s near impossible for anyone who is invested in the project to not know what feedback pertains to.

The build number stamp is superfluous to our ability to respond to feedback and take action based on the feedback.  Our review of the inbound feedback, and the prioritization of tasks happens as a matter of agile planning, which is an information-immersive negotiation for stakeholders and designers.

No one could possibly not know what the feedback pertains to and therefore having further qualification by build number doesn’t enable us to fulfill our responsibilities any better.  It does however arbitrarily cost us the time of implementing the build number stamp.

This information might be useful to us later – when we have more releases, more features, more feedback, etc.  If we were to put in the effort to build it now, we would – in Lean terms – be incurring inventory cost.

Asking “How are you going to use that information” forces us to look at the behaviors that capitalize on that information, or that are enabled by that information.  When we just declare that we need some piece of information or other without justifying it with a concrete user story, we’re just doing model-driven or data-driven design.

When I focus first on behaviors – especially user goals as expressed based on scenarios with realistic context – the understanding of the necessary data will simply become clear and evident.  If I get distracted in the details of data-driven and model-driven analysis, I run a really high risk of accumulating unneeded inventory and its associated costs.

Drill down on behaviors.  Find out if they are real and substantial, and then figure out the data needs.  Starting at data is often a crap shoot at best.  Behaviors will surface data needs, but the opposite is almost never true – not in any substantial and meaningful way that works against incurring inventory in any case.

BDD and “How Are You Going to Use That Information”

Deep Dive into TDD Revisited

August 30, 2007

 

Hi, everyone. I haven’t posted any serious technical content on this blog for a long time now. The reason for this is that I’m now a pointy haired boss most of the time. I spend my days teaching, mentoring, coaching, and occasionally pairing with someone on another team. I miss coding… I really do.

However, I’ve been digging into Interaction Based Testing over the past few weeks, and I’ve found it fascinating. The road I took to get here involved trying to learn more about what Behavior Driven Development is, and why so many people I know and respect seem to like it, or at least appreciate it. One of the techniques that BDD uses is something called Interaction Based Testing, or IBT for short.

Interaction Based Testing

IBT is different from traditional TDD in that it is defining and verifying the interactions between objects as they take place, rather than defining and verifying that some input state is being successfully translated to some output state. This latter kind of testing, called State Based Testing, or SBT for short, is what I had always done when I did TDD (for the most part). IBT involves using a Mock Object Framework that allows you to set expectations on objects that your class under test is going to call, and then helps you verify that each of those calls took place. Here is a short example:

[TestFixture]
public class IBTExample
{
    [Test]
    public void SampleITBTest()
    {
        MockRepository mocks = new MockRepository();

        IListener listener = mocks.CreateMock<IListener>();
        Repeater repeater = new Repeater(listener);

        listener.Hear("");
        LastCall.On(listener).Constraints(Is.NotNull()).Repeat.Once();

        mocks.ReplayAll();

        repeater.Repeat("");

        mocks.VerifyAll();
    }
}

The basic problem that I’m trying to solve here is that I can write a method, Repeat(), on a class called Repeater such that when I call Repeat(), it repeats what it was passed to its IListener. The way that I set this up is more complicated than I would use in a state-based test, but I avoid cluttering my test with irrelevant implementation details (like explicit data).

What this test is doing is creating the system and setting expectations on the IListener that define how the Repeater class is going to use it at the appropriate time. The MockRepository is the class that represents the mock object framework I’m using, which in this case is Rhino Mocks. I new one of these up, and it handles all the mocking and verification activities that this test requires. On the next line, you see me creating a mock object to represent an IListener. I typically would have created a state-based stub for this listener that would simply remember what it was told, for my test to interrogate later. In this case, the framework is creating a testing version of this interface for me, so I don’t have to build my own stub. Next, I create the class under test and wire it together with the listener. Nothing fancy there.

The next line looks a little strange, and it is. It is actually a result of how this particular mocking framework functions, but it is easily understood. While it may look like I’m calling my listener’s Hear method, I’m actually not. When you create an instance of the mocking framework, it is created in a recording mode. What this means is that every time you invoke a method on a mocked out object while recording, you are actually calling a proxy for that object and defining expectations for how that object will be called in your regular code later. In this case (admittedly, not the simplest case), listener.Hear() is a void method, so I have to split the setting of expectations into two lines. On the first line, I call the proxy, and the framework makes a mental note that I called it. On the next line, I say to the framework, “Hey, remember that method I just called? Well, in my real code, when I call it, I expect that I am going to pass it some kind of string that will never be null, and I’ll call that method exactly once. If I do these things, please allow my test to pass. If I don’t do them, then fail it miserably”.

After I set up the single expectation I have on the code I’m going to be calling, I exit record mode and enter replay mode. In this mode. the framework allows me to run my real code and plays back my expectations for me while my real code executes. The framework keeps track of whatever is going on, and when I finally call my application method, Repeater.Repeat() in this case, followed by the mocks.VerifyAll(), it checks to make sure that all expectations were met. If they were, I’m cool, otherwise my test fails.

I hope that was at least a little clear. It was very confusing to me, but I sat down with a few folks at the agile conference two weeks ago, and they showed me how this worked. I’m still very new at it, so I’m likely to do things that programmers experienced with this kind of testing would find silly. If any of you see something I’m doing that doesn’t make sense, please tell me!

Here is the code this test is forcing me to write:

public class Repeater
{
    private readonly IListener listener;

    public Repeater(IListener listener)
    {
        this.listener = listener;
    }

    public void Repeat(string whatToRepeat)
    {
        listener.Hear(whatToRepeat);
    }
}

public interface IListener
{
    void Hear(string whatToHear);
}

Advantages to IBT style TDD

There are several things about this that I really like:

  • It allows me to write tests that completely and totally ignore what the data is that is being passed around. In most state-based tests, the actual data is irrelevant. You are forced to provide some values just so that you can see if your code worked. The values obfuscate what is happening. IBT allows me to avoid putting any data into my tests that isn’t completely relevant to that test, which allows me to focus better on what the test is saying.
  • It allows me to defer making decisions until much later. You can’t see it in this example, but I’m finding that I’m much better able to defer making choices about things until truly need to make them. You’ll see examples of this in the blog entries that are to follow (more about this below).
  • I get to much simpler code than state-based testing would lead me to
  • My workflow changes. I used to
    1. Write a test
    2. Implement it in simple, procedural terms
    3. Refactor the hell out of it

With ITB, I’m finding that it is really hard to write expectations on procedural code, so my code much more naturally tends to lots of really small, simple objects that collaborate together nicely. I am finding that I do refactoring less frequently, and it is usually when I’ve changed my mind about something rather than as part of my normal workflow. This is new and interesting to me.

There are some warts that I’m seeing with it, and I’ll get to those as well, as I write further in this series. I’m also very certain that this technique has its time and place. One of the things I want to learn is where that time and place is. Anyhow, here are my plans for this:

Revisiting my Deep Dive

I want to redo the example I did a couple years ago when I solved the Payroll problem in a 6-part blog series. I want to solve the same problem in a ITB way, and let you see where it leads me. I’ve done this once already, part of the way, just to learn how this worked, and the solution I came up with was very different than the one I did the first time. I’m going to do this new series the exact same way as the old series, talking through what I’m doing and what I’m thinking the whole time. I’m personally very curious to see where it goes.

Once we’re finished, I want to explore some other stories that are going to force me to refactor some of my basic design assumptions, because one of the knocks against ITB is that it makes refactoring harder by defining the interactions inside your tests and your code. We’ll find out.

Please ask questions

I’m learning this stuff as I go, so I’m very eager to hear criticisms of what I’ve done and answer questions about why I’ve done things. Please feel free to post comments on the blog about this and the following entries. I’m really looking forward to this, and I hope you readers are, too.

— bab

Deep Dive into TDD Revisited