BDD – Consider your audience

Unlike vanilla TDD, the artifacts produced by BDD can and should be read by more than just developers. Most of us who practice TDD name our tests more or less like this:

MessageBoardControllerTests.Index_WithTenMessages_ReturnsFiveMostRecentFromRepository()

Shifting into Context/Specification style testing, one may be tempted to write specs like this:

MessageBoardController, when invoking index action when there are ten messages, 
  should return five most recent messages from the repository

The problem with this spec is subtle but important. You often want these specs to be readable and understandable by a normal person, someone in your business that can provide you feedback on your specs. Using words like "invoking", "index", "action" and "repository" are clear indicators that your audience is another developer. You should use the time writing specs to speak in the language of the business and to clarify your ubiquitous language. Here’s how I’d rewrite this:

Message Board, when viewed
  should show only the five most recent messages

Again, the difference is subtle, but notice how I could show this to anyone in the company and they would understand exactly what is happening.

There are times for developer speak in specs I believe. If you are specing an API to be consumed by other developers I think it’s ok to use words like "throw" and "return" because that is what the developers care about when integrating with an API.

Most of the time however, especially when writing the more UI/System Behavior level specs, you should consider who your audience is and try to speak like them. The code itself will provide the detail a developer needs to understand it.

As an aside, this is one of the many reasons I prefer the Context/Specification style to Given/When/Then style of BDD. Because people already don’t speak in Given/When/Then prose in real life, it makes it even more difficult to write your specs for the intended audience. It also leads you to use magic numbers and other magic state in your prose rather than formalizing business concepts and improving your ubiquitous language.

This entry was posted in bdd. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://scottic.uc Scott Bellware

    Dave,

    The significance of “should” is the impact that words like “does” and “must”, etc, have on developer psychology.

    The language can and often does create unnatural and false rigidity. More than an issue of splitting semantic hairs, it’s an issue of reinforcing the right state of mind.

  • Dave Foley

    Scott,

    “Should” seems to me to be unnecessary noise when reading through the generated specs, especially in a system that has been in active development for a long period.

    Increasingly, as time goes on, a vast majority of the specifications refer to functionality that has already been implemented. I prefer to think of the specs as a description of the system’s behavior, rather than a set of assertions.

    As to “should” clarifying the malleability of requirements, I sort of get what you’re saying, I just don’t buy it. It’s semantic hair splitting in my opinion.

    Also, I have a tendency to document limitations and assumptions in my code with tests (descriptions of what the code actually does, in it’s current state)..

    In these cases, it’s not really a matter of “it should do X” but more like “it does X because X is all we need for now”

  • http://scottic.us Scott Bellware

    Dave,

    “Should” is intended to communicate always and pervasively that specifications are soft and changeable. It’s a word that sets up a psychological context that encourages flexibility and challenges the rigidity that sets in when specifying behaviors with finalistic language.

  • Dave Foley

    On the “subtle difference” thing, “should” has started to really annoy me… I prefer “Message Board, when viewed, shows only the five most recent messages”.

  • http://colinjack.blogspot.com Colin Jack

    I agree, plugin the values doesn’t make too much sense to me. What I do find useful is being able to reuse fixtures/contexts, and parts of them, when doing acceptance testing though. I say this because you end up with just slight variants of the same thing. For example what happens if X is valid and Y isn’t, then swap. Or we’ve got very similar specs other than the type of user that’s logged in or whether they logged in using one mechanism or another.

    It was those cases that I’d hoped the xBehave frameworks would help with but I didn’t like the result so I just fell back on writing my own classes/base classes/helper classes. Not perfect but doable. Still my feeling is composition is key at acceptance test level. In fact I really need to look again at JBehave as I think its taking it way beyond what we have in .NET.

    On readability, not really sure one way or the other. I find the GWT syntax works quite well especially at the acceptance level where there is a lot to the given. To be honest though I think I could dump GWT and use C/S for all specs, but at the moment I haven’t found a pressing reason to go down that path.

    Missing abstractions, that sounds interesting. Got an example I can mull over?

    The reporting being valuable for review within the team, hadn’t thought of that and yeah I can see the advantage of that especially in a code review setting, a lot nicer than manually going through and seeing what tests were written.

  • http://aaron.codebetter.com Aaron Jensen

    You’re correct that Dan North’s initial introduction used more sensible naming and was less focused on the specifics of the scenario. Unfortunately, the community has taken it another way w/ many of the GWT frameworks that have become focused on DRY and “plug in the values” testing.

    Despite this, I still feel the C/S method is more readable. It can also lead to more important abstractions. It’s very easy to tie multiple Givens together and not realize that what you’re describing actually has an important name.

    The reporting is valuable for review. We’ve already seen value in that. I’ll look over new specs written by the team or we’ll review them as a team. It’s an excellent way to catch things that just don’t behave the way they should or the wording is awkward or incorrect. You can do the same in the code, but having the report removes even more of the noise than MSpec ever could.

  • http://colinjack.blogspot.com Colin Jack

    On the behavior vs scenario thing, even when I do use GWT I would usually use the second style. So I might phrase it as “Given an account that is in credit, when I withdraw more money than the account has in it”. Actually thats the style of scenario that Dan North originall described (http://dannorth.net/introducing-bdd), though I guess things might have moved on since.

    On the reporting. I evaluted MSpec last week and really loved it. Great idea, great work. However in the end we decided not to use it (for now at least). For me one big loss from not using it might be the reporting so I’ll be interested to see what you find.

    My thinking is that the specs that are valuable to the BA or whoever are ones that we involve them in upfront, and with that in mind the reporting *might* have limited value. But since I haven’t tried I don’t really know…

    On transitive nature of stories, I see what you are saying. I’m only tying them to stories because the stories drive them out and for the upper level tests, the ones that most interest the BAs/domain experts etc, the wording matches closely.

  • http://aaron.codebetter.com Aaron Jensen

    I feel that behavior testing is more interesting than scenario testing. Obviously you need scenarios to test the behavior, but I feel it is important to name those scenarios appropriately. There is a large difference between “Given an account with $5, When I withdraw $6″ and “When withdrawing more money than an account has”

    GWT/Scenario based frameworks have this concept baked in. The whole notion of turning the GWTs into methods with parameters is awkward and forces you to concentrate on the scenario when you should really be looking at and documenting the behavior. Context/Specification, when applied correctly, does just this.

    To be perfectly honest, we’ve only recently started making heavy use of MSpec and creating specs. We haven’t yet begun tagging the specifications that would be useful to BAs etc and pulling them out to show them. We do plan on it, but it hasn’t happened yet. I’ll definitely describe my experiences when we do. I’m quite confident that when we do, the ones written in their language will make more sense to them.

    And yes, the lower level specs are more technical in nature, but care still needs to be taken to focus on the behavior and not the implementation. It’s subtle, but important.

    Domain specs are a set of specs that I think are very important to keep pure and in as much UL as possible. This is where much is born, and it is important to communicate with the customer/ba/etc while doing this. This is something we have been doing and it has led to greater insight into our domain.

    Also, I’d be careful calling tests “story based”. Stories are transient statements of feature to business value mapping. Though working to deliver them does drive the creation of specifications, I would shy away from tying them to the stories in any permanent capacity.

  • http://colinjack.blogspot.com Colin Jack

    Yeah I hear what you are saying, and I didn’t mean to infer they should be involved in all specs.

    What I should have said was that I don’t think GWT hampers BDD because Dan North was primarily pushing it for specs that did come out of work with BAs etc (which I agree is just a subset of the specs you write).

    Here’s a question for you though, have you found reporting on all of your specs is really useful and are your users/BAs/domain experts really interested?

    I can see that the reports on the story based tests have value but you then write a lot of detailed/technical specifications (mapping, process, controller, integration) and I haven’t seen any value in exposing that level of detail outside the dev team. I guess it could have value for certain types of specs though, particularly those against the domain itself?

    Not suggesting writing your specs in developer language though…

  • http://aaron.codebetter.com Aaron Jensen

    Colin,

    I completely agree that they should be involved. The level of involvement can vary from shop to shop though, and I certainly don’t expect my users or BA’s to write all of the specs with me. Their job in our shop is to aid in writing the stories and to answer language or content questions we may have while writing specs. I think the key is to get developers thinking like them and to just be aware of the fact that they are not writing specs for other developers to understand necessarily.

    From there you do what you need to do when writing the specs whether it be involve your user/BA/customer in every one or just certain areas + review.

  • http://colinjack.blogspot.com Colin Jack

    Good post but I think that the best way to ensure that the specs are written in the users language (or the UL) is to get them involved. If you do that then words like “invoking” only make it into the specs (GWT or not) if your user/domain expert is happy with the term.