Reading the latest posts on the Yahoo XP group, it seems that good TDDers understand that the word “test” is developer-speak for something a little more complex. “Test”, in Test Driven Development, encapsulates the idea of specification, design, verification of implementation and the ability to confidently refactor. Regression testing itself is almost a by-product of these uses of the word “test”. “Test” is often the first word we think of when doing TDD – you always start with a test – and yet we use it in defiance of its own definition.
I believe that the word “should”, and similar elements of Behaviour Driven Design vocabulary, remove the developer-speak, thus helping to bring the code closer to those people who aren’t privy to the secret language of software. This includes the customers, and anyone who isn’t familiar with TDD.
I believe that the inclusion of developer-speak such as “test”, which no longer means what it says, allows us to easily utilise developer-speak in other ways without noticing. We use other laden terms such as “mock”, “stub”, “functional test”, “…Impl”, etc. We find ourselves free to name classes after the patterns they mimic and the classes with which they interact (ScalpelSheepVisitor) instead of capturing their role succinctly (Veterinarian). We refer to documentation blindly (JIRA345Test.testHappyPath()). We don’t make readable, legible code.
Sometimes, because we can’t read our code properly, we mix up the roles and the responsibilities of our classes (ScalpelSheepVisitor shears the sheep too). We assign responsibilities to classes which don’t really have responsibility for them (SheepVisitor.getCostOf(sheep)), and we verify that these new responsibilities work (testCostOfSheepReturnedSuccessfully) instead of considering whether they’re appropriate.
For people who are already aware of these pitfalls, and who use TDD with care, mindful of what the word “test” really means – BDD will bring little that’s new into your life.
For everyone else – try thinking of these things when you code. Don’t test; think “What should this class do? What are its roles and responsibilities? What does it do to the things I’m going to give to it?” Then write a method which will describe the class’s behaviour. If you need a prefix on the name of the method to make it run then write it, but don’t type those letters until the real name has come to you.
I find that using the word “should” helps me think of the name. I find it helps me consider the roles and responsibilities of the class, and the class’s interaction with others. I find it keeps me away from that distracting, misleading, misnomer: “Test”.
By phrasing this in terms of TDD and vocabluary, you kind of hint at, but never explicitly say that the bulk of our industry lacks a basic understanding of OOP.
I wish that using the word ‘should’ instead of ‘test’ would solve this problem, but I won’t be holding my breath.
I just posted a response to something similar on the group:
Next time you’re on a big project, take a look at some of the test
methods. Think about how they’d look if you replaced “test” with “should”.
Are they proper English? Do they make any sense? Or do they say
“shouldDatabaseUnavailable()” and “shouldOneItemInList()”?
These kind of tests have been standard in most projects I’ve worked in.
The exceptions have been the ones where people have introduced BDD,
knowingly or not.
Making the suggestion that someone try writing tests
with the word “should”, and explaining the BDD principles, is a really
good way to make that introduction – and I know, because it’s how I was
introduced.
And I replied to this.(on the XP geoup)
“shouldDatabaseUnavailable()” and “shouldOneItemInList()”?
could be phrased as “shouldHaveNoAccessToDatabase()” and “shouldHaveOneItemInList” with no change in information content ‘Should’ is not magic.
there is a more subtle problem with tests written like this (explained in my response on the group).But the original comneter is right. What is missing is basic knowledge of OO whih cannot be faked by using should.
Ravi Mohan (http://ravimophan.blogspot.com)
uggh the blog url should be “http://ravimohan.blogspot.com”
Cheers, Ravi.
The method, found in some code here, reads “testDatabaseUnavailable”. I would find its intent clearer if it read, “shouldRunSuccessfullyEvenIfDatabaseUnavailable”, which I can see from the code is the real intention.
I think that our opinion differs because I do see a change in information content when things are named this way, and I believe the word “should” encourages that change. You can see the change in the different intent of our two database methods – if you had seen the method as it was originally named, you might well have misinterpreted it; whereas if the method actually behaved as your description implies, I would have thought it did something else. I believe that anything which encourages clarification of intent is a good thing.
Ravi Mohan says
“The method, found in some code here, reads “testDatabaseUnavailable”. I would find its intent clearer if it read, “shouldRunSuccessfullyEvenIfDatabaseUnavailable”, which I can see from the code is the real intention.”
You are absolutely right. If you can see the code and see a better name, you should change it.
“if you had seen the method as it was originally named, you might well have misinterpreted it; ”
This is not fair.I am just translating the name *you* gave in the post to a test based name conveying *exactly* the same semantics with adifferent prefix. The point being that should-prefixed and test prefixed names can give the exact same information (good and bad).Thus i did *not* change anyting except the prefix; the point being that the prefix was irrelevant.
If i were to name a test “properly” it woudl end up very simliar to teh shouldXX ame you came up with buts tsill using testXX see below.
I would NOT name a production code method this way. You see what the code is supposed to do and think of good names. If I were in your place I would have changed it to (assuming Junit) “testRunsSuccessfullyWhenDatabaseUnavailable” . I am NOT against good method names. I am against “should magic”.
My preferred naming method these days is Dale Emery’s condition-connector-result pattern .Thus in this case , result= “runs successfully” condition = “Database is unavailable” connector = “When” giving the name above.
I don’t have to believe in any language specific “magic”( magic = i don’t know how it works – it just taps some mysterious cognitive process etc -the Shapir Worf hypothesis apparently underlying BDD) rule to do this.Whether the name should be prefixed with test or should is irrelevant . What matters is that it has all 3 components.And it will be just as clear with any prefix.
This is my problem with BDD (as we thrashed out on the xp mailing list).It is just a renaming of *existing* OO practice.
If you are saying “clarify intent”, I agree totally. This is a principle which can be achieved in many ways without new tools etc. There is notheing “BDD’ about this.
If you are saying “Use should.This is better than test” I disagree because this is a very cultish way of doing things,imo.The prefix has littel to do with teh quality of the method name. You can get perfectly good names with test-prefix/junit as demonstrated above.But since we’ve been down this road before, let me stop.
have a nice day.
Nice blog.
Ravi, we’ve done this. With respect, I’m bowing out before this turns into an extension of the XP group thread.