Beyond Test Driven Development: Behaviour Driven Development

MALE SPEAKER: Hello, everybody Thanks for coming to today’s TechTalk We are fortunate to have Davis Astels, the author of Test-driven Development: A Practical Guide And unfortunately, we are not fortunate enough to have the books yet But we do have a Sparrow page We’ll be sending it out on the [? Inge Talks ?] mailing lists So look for that And we promise you’ll all get your book in due time I also need to let everybody know that, during the Q and A section, if you have any questions that might bring up any confidential information, please save them for the second part of the Q and A We’re actually going to shut off the camera, and then you can ask anything you like Dave signed the NDA So anyways, without further ado, I guess we’re all here to learn about behavior-driven development, the next step after test-driven development DAVID ASTELS: Thanks Yeah Behavior-driven development This talk is in Ruby, because– closer to the microphone? I hate those things I’m a wanderer Anyway, we’ll deal with that Don’t worry Yeah, this is in Ruby We decided to start off in Ruby partly because I wanted to learn Ruby and see what we could do with its language features It’s an easy enough language, so everyone should pretty much be able to pick it up If you have questions about the syntax and whatnot, feel free So first, about me– you did a pretty good job already Test-driven Development: A Practical Guide I like to say this is the first time I’ve been to SD West when I didn’t win a Jolt Award This is only my second time, so– and I also co-authored a book on extreme programming So I don’t know how many of you watched Steve Jobs’ keynotes, but I got some inspiration from that And also the slides look a little different I’m using something akin to the Takahashi style of slides So if you want to get my slides, you can have them, but you’re not going to get much out of them without the audio So first off, act one BDD A lot of people are doing TDD Some people here are doing TDD TDD is becoming more mainstream There are talks at conferences There are lots of books out now Lots of information in the press about TDD So everyone’s doing TDD, everyone’s happy, they’re getting the maximum benefit Everything’s good Yeah, bullshit I’ve gone in and trained companies in TDD, and talking to people but TDD And there’s a score of mistakes that people make And mostly it’s because they’re talking about testing Right? When you’re using TDD, you’re using something like JUnit or NUnit And you have to start your methods with the word “test,” or you put an annotation on that’s a “test” annotation You extend test case, maybe You’re making assertions All very verification-specific language You’re talking about testing And what do we think about when we think about testing? We think about, I’ve got some code and I have to know that it works properly I want to verify that it’s correct That’s what we think about most often when we talk about testing So we’re being constantly barraged with all this testing nomenclature, this testing baggage And what is TDD? Is it testing? Well, if you actually had copies of the book, the first line in there says, “This is not a book about testing.” It’s about design It’s a design process So we want to stop talking about testing We want to get rid of that What we want to talk about instead is something that’s an evolution beyond TDD We want to talk about behavior This is what we’re getting to And some people ask, well, what’s the difference? It’s still the same And yes, at a technical level, it is the same

If you look at your Java bytecode, it’s probably going to look very much the same The way I describe it is, behavior-driven development is what you are doing already if you are doing test-driven development very well The problem is most people aren’t doing it very well And our hypothesis is that that’s because people are thinking about testing while they’re doing it So another thing about testing– JUnit and NUnit are purported as unit test frameworks So we have this word, unit What does that mean? Can I get some definitions? What’s a unit? Someone? Oh, there’s a hand up You can answer, then AUDIENCE: A small, focused module of code DAVID ASTELS: A small, focused module of code AUDIENCE: Like a class DAVID ASTELS: Like a class Anyone else? AUDIENCE: A method DAVID ASTELS: A method AUDIENCE: That somehow doesn’t touch a database or anything else that might make it slow DAVID ASTELS: That’s good I haven’t heard that before from an audience Yeah Something that doesn’t just touch a database or something else that would make it slow So something that’s isolatable And when you’re doing TDD, that’s what you want to do You want to isolate what you’re testing So there’s a couple different definitions of unit So that’s a very nebulous term, that’s very vague We want something a little more concrete So we don’t want to talk about units, because everyone has their own definition and it’s situationally dependent Maybe you’re working on a class now and a method later Those are both units, in a sense So instead of units, we want to talk about behavior, little fine-grained, focused pieces of behavior All the code you’re writing, all the systems you’re developing, have behavior, have interesting behavior Otherwise you’re just wasting your time, if they don’t have interesting bits of behavior to them And that’s what we want to focus on We want to look at not whether it’s in a method or it’s in that class or it’s two classes cooperating to produce it We want look at, I’ve got this little bit of behavior in my system and I want to talk about that I don’t care where it is in the system, in terms of how it’s structured There’s a quote on the sign for this, that talked about the one-to-one correspondence between tests and methods or test classes and classes That is one the biggest problems I see with people starting out with TDD, is that they structure things so that the structure of their test code mirrors the structure of their production code So there’s a couple things that happen there What happens when you refactor and you change the structure of your production code? Do you then go and automatically change the structure of your test code to match? You shouldn’t have to ask those questions You should be focusing on behavior and structuring your tests, or your specifications, the new word we use, around the behavior Not around the structure of your production code, but around what it does, what the interesting pieces of behavior are So now I’ll pull out some linguistic stuff Anyone familiar with Sapir-Whorf? OK, we’ve got some It’s sort of a controversial theory, but I think there’s some truth in there That’s spelled wrong, isn’t it? Oh, yeah I guess I was thinking– OK The idea behind Sapir-Whorf is that the language you use, the terminology, the grammar, et cetera, in some way influences how you think So language in some sense drives thought So the words you use shape how you think So for you who are saying test all the time, there’s a very strong likelihood that that’s putting you into a verification mindset So if we can step away from saying test, maybe we can start to think a bit differently So instead of test-driven development, we’ll take that away and we’ll start using behavior-driven development Take the focus away from testing and verification, to behavior Stop thinking about, how do I prove that my code works, to thinking about describing what I want my code to do Get away from state This is another problem that’s pretty prevalent, at least in beginning test drivers The reliance on testing state And probably the worst case of this I’ve seen was on one project where we were using reflection to get–

I wasn’t They were using it before I got there I straightened them out They were using reflection in their test code to access private member variables in the production code So in the test code, they’d actually go in, put some values into these private members, do something, and then go in and look at what was in the private members afterwards And that is probably the worst example of state-based testing that you– well, actually, it’s a very good example of state-based testing But it’s an example of the worst thing you could possibly do Because this is all fine, everything worked, and the tests passed and everything, and this class that was being tested grew and grew It was sort of of one of the core domain classes And it got to a point where it was unwieldy So we said, OK, we’ve got to refactor it We’ve got to split it up We’ve got different areas of responsibility in here, so let’s start splitting it up So we do it fairly conservatively We group the functional areas, and we pull out a class, and we delegate out to the new class and gradually find all the callers and prune them out And so we did this with one area of behavior and suddenly things blew up All of these tests started failing Why? Because that area of behavior included a variable which we moved out to the new class Now, that variable was no longer needed in the original class We just had the methods delegate And suddenly that variable wasn’t there anymore And because the test was using reflection, that didn’t show up until runtime, and it caused all the tests to fail So depending on implementation, state in your tests is a real barrier to refactoring So we want to get away from that So no more state-based testing Who’s familiar with mock-objects? Excellent Wow That’s good Mock-objects are one approach to getting away from state-based testing Start looking at testing the interactions, looking at the interactions, rather than the state And that’s really all that behavior-driven development is doing, is making that formal that we’re not looking at state, we’re looking at interactions We’re looking at behavior, what it does, not the internals of how it does it So instead of state, we want to look at behavior We get rid of the word test, and everything that goes along with it And we replace that with specifications This is really what your tests are when you’re doing TDD They are executable specifications of behavior of your system AUDIENCE: So could you say we’re doing computer-aided specification evolution? DAVID ASTELS: Sure, you can say that What did you say? We’re doing computer-aided specification– AUDIENCE: Evolution DAVID ASTELS: Evolution I don’t know about evolution But yeah, we’re writing specifications that– Bob Martin, I think, says we’re writing specifications of the behavior of our systems in such a precise way that we can execute them So instead of dealing with assertions– you know, in JUnit, we’ve got all these assertions– we want to get rid of that That’s test-centric as well, verification-centric We want to set up expectations about the behavior of our code OK That’s the background Any questions there? AUDIENCE: [INAUDIBLE] DAVID ASTELS: How do you test a protocol? AUDIENCE: [INAUDIBLE] DAVID ASTELS: Basically, a protocol– you’re putting something in and you’re seeing something come out You control what you put in and you know what you expect to come out and how you expect that interaction to occur So mock-objects could be used there, to basically pretend to be the other system You know what to expect coming at it You can verify it that way Anything else? OK Act two rSpec Now we get into some nuts and bolts At first, I wrote a blog post and I talked about behavior-driven development in hand-wavy form, and wouldn’t it be nice if we could write our specifications like this And a friend of mine read that, and said, OK, you’ve been talking about that for a while, and me and a couple of guys at work– working in a Rails shop– have been thinking about that, and I think we’re just going to start writing this So they went and a week or so later, they had a rudimentary framework in place And we’ve gone from there We’re actually on Version 2 of the guts of the thing now So xUnit– we get rid of xUnit, because it talks about test. Instead we need new frameworks We need new frameworks that are behavior-specific, that are specification-oriented And this led us to rSpec for Ruby

There are a couple people– one of the guys I’m working with at the moment– who are working on csSpec for .net And a couple of us have started talking about, OK, it’s time to do a jSpec, which won’t look nearly as nice as rSpec, but functionally they’ll be equipment So from Test::Unit in Ruby, and jUnit by extension, we’re familiar with looking at something like this, which doesn’t read all that well. assert_equal, expected comma actually You have to know the API You have to know what the argument structure is How many people, when they started using TDD, jUnit, nUnit, whatever, consistently got these two backwards? Yeah, right? And then your error messages really help So we’ll get rid of that And we’ll be able to say something like that, where actual is our value that we’re looking at, expected of course is what we’re expecting to see And we can say, actual should equal expected So result should equal 5 OK So I’m just going to go through the API that we’ve built up for setting these expectations And you can see what things might look like So here we are For brevity on the slides, I’ve left off the target object, but this would be result.should.equal 5, on all these slides So it should equal 5 Most of these– almost all of these, in fact– have a negative version, should.not.equal 5 So for object identity, we have should.be, should.not.be This is an interesting one that the guy I’m working with, Dave Chelimsky, came up with If your target object responds to a method, in this case, called items, so for the prototypical– you know, cur_object, that could be wheels It returns something that responds to either size or length So now we can say, for example, cur should have 4 wheels So through reflection, we take the last call there, apply that to the target object, get back something that responds to length or size, call that In this case it should have the length or size that we specified We also have should.have.at.least and should.have.at.most AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Don’t we worry that something could have both length and size, assumedly meaning different things Yeah, we haven’t thought too much about that yet, but that certainly is a potential problem, that there would be some confusion there But the onus is always on the developer to know these things, because they’re writing the items method, for example And they’re writing the specification and they know what it’s going to do And of course, you can always pass in a block to do some arbitrary testing The target object gets passed into the block and then you can do whatever you want to make whatever assertions I personally don’t really like this I think it gives you a little too much rope But we had someone very vocal that was working on it that really wanted that backdoor in And it’s nice to have there, so that you don’t have to whine and complain that the API that we built doesn’t do what you want OK, just do it yourself Of course, Ruby has good pattern matching So we have should.match, should.not.match, with regular expressions And you can do an arbitrary predicate, a predicate being a method that returns true or false and may or may not take arguments In Ruby, the convention is to have the method named with the question mark at the end of it If anyone here is a Lisper, it’s like saying predicatep So predicate? So the target object here is assumed to have a method called predicate? So empty? might be one that collections have. So you could say, this result, collection, should be empty And there’s a little bit of syntactic sugar I don’t have on the slide You could say should in the predicate So should.start might be something Or you can put a be in there, which is just syntactic sugar So you could say, should.be.empty All for the sake of readability Because don’t forget, these specifications on your tests, if you’re using TDD, serve a documentation value So the more readable and the more clear they are, the more

valuable they are So that was one of our driving goals here, is to make things readable And of course there’s a forced failure violated takes a message to tell you what the problem was This is called, not on the target object, but on the enclosing context that you write your expectations in OK Exceptions How many Ruby programmers here, people that have dabbled– you know what a proc object is, then So if you pass this to a proc object, it gets executed and you set the expectation that it should or should not throw a certain exception Methods to check the direct class of an object Methods to check the inheritance chain of an object, if you will So direct class or one of its ancestors And should be a kind– also it uses a or an, which are synonymous You can use either to make it read well And checking whether or not it supports certain methods, messages And here’s a small example from my tutorial, of what it might look like Or what it does look like This will execute And here’s the background code to that So you can see we have the obelisk? predicate And we also have a facing? predicate that takes an argument Any questions up to that point? OK So mock-objects, as I mentioned, is a very important concept when you’re starting to do interaction-based testing and behavior-based testing, or behavior specification See, it’s hard to get away from that testing word So there’s a mocking framework built into our spec And I went out looking for one for Ruby and found one, called Schmock How many of you use jMock? A few people, good This is very much like jMock It’s open-source I contacted the author and said, do you mind if we roll this into the rSpec project and build on top of it, and that was cool So it’s integrated right in There’s one way to do mocks in rSpec, and it’s fully integrated So to create a mock, you call the mock convenience method, give it a name You set an expectation that a method’s called with the should.receive call, give it the name of the method, tell it how many times it should expect that call, and with what arguments, if any, or if you care And then what it should return when that call’s actually made Oh, let’s back up These cool fading slides don’t back up nearly as nicely There we go So you say and_returns and give it a single value, or you can say and_returns_consecutively and give it an array And if you’ve set up an expectation for multiple calls, it will step through that array the first time it’s called and return the first value, the second time the second value, and so on And if you hit the end, it’ll just keep returning the last value You can provide a block– the same guy who wanted the block for the expectations wanted the block here So instead of setting all those expectations and settings very declaratively, so I want to call this many times with these arguments– you can do that in a block The block gets passed any arguments that are passed into that method call, and you can do arbitrary checks on it And the last value executed in the block gets returned in the call So here’s an example it’s kind of lengthy Can everyone see that, hopefully? You can always watch the video later and zoom in So you say mock database should_receive(:getList).once with no arguments, and return the array a,b One more thing about mocks– they get auto-verified So if you create them using the call to mock that I showed earlier, when your specification is finished executing, all the mocks will be verified So you don’t have to do that explicitly, the same as if you’re using jMock, inheriting from the right test case So why Ruby? Well, it’s dynamic It’s a dynamic language I learned OO by using Smalltalk, so I’m a big fan of

dynamic languages Before that, I did a lot of Lisp So using C-sharp and C++ was like a noose Java’s like a straitjacket So I’m a big fan of dynamic languages, and I’ve been looking at Ruby for awhile, and it’s like, oh, this is a good opportunity to actually get in and do some Ruby Ruby’s very productive Again, this goes hand in hand with it being a dynamic language to a large extent Ruby’s very productive It’s very terse, not to the point of Perl, maybe, but it’s very expressive You don’t have to write a lot of Ruby code to do something So our whole framework’s a few hundred lines It’s a very lightweight framework And it’s fun Even given that we don’t have any IDEs really I used TextMate It’s sort of a New Age EMACS, I guess But even so, Ruby’s a lot of fun to work in OK, any questions on that? The technical details? OK So this is the– how are we doing for time? AUDIENCE: [INAUDIBLE] DAVID ASTELS: OK Good So any questions or discussion? You think my brain’s chilled from being up north? AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Yeah, I’ll get those up Yeah? AUDIENCE: So obviously in Ruby, you’ve got this framework and everything You said something [INAUDIBLE] framework for Java? DAVID ASTELS: Right OK, so the question was, we have this framework in Ruby Someone’s working on it in Java? Not yet There is a BDD– actually, the term BDD was originated by Dan North in the UK, London– ThoughtWorks London– who has a project called jBehave. And he’s recently put together a project called rBehave. So there’s some work done there He has a Java framework It’s a little different, philosophically, from what we’re doing And we will be starting a Java version of this framework, which will syntactically, of course, be a little different, but trying to stay true to the form that we’ve set here, as much as possible AUDIENCE: [INAUDIBLE] stuck with jUnit What’s the best I can do [INAUDIBLE]? DAVID ASTELS: That’s a good question And I love the way you phrased that– if i’m stuck with Java and stuck with jUnit, what’s the best I can do? Are you using jUnit 4, yet? Using Java 5? You’re using Java 5? AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Yeah, JDK 1.5? OK Are you using jUnit 4? AUDIENCE: [INAUDIBLE]? DAVID ASTELS: OK You’re probably using jUnit 3.8.1, then So if you’re using that, you’re kind of stuck in a way Because you have to start all of your methods with test That’s the one big hurdle, because you have that in there and it’s awkward If you can, you should as soon as possible switch to jUnit 4 There’s some backward compatibility built in It uses annotations to tag– the way, if you’ve ever used nUnit and C-sharp, it uses the Java 5 annotations to tag your test methods So you can call them whatever you want now And so you can start calling them in a little more behavior-centric way, typically with should So you name your class after the state of the world So empty_collection would be your class name And you could have methods named should_have_no_elements, should_have_size_of_zero, should_return_an _empty_iterator, things like that So you can name your methods that way That helps That takes the test focus away and focuses on what the behavior should be That’s about it But mostly it’s naming there And also thinking– I know, I’ll get to you in a second– thinking about it from a behavior point of view A lot of it is mindset, and a lot of what we’re doing with changing the nomenclature in the new framework is trying to change people’s mindset, make them think in a specification way rather than a verification way So a lot of people that are doing TDD quite well are doing that already, in spite of the framework and the words it uses So yeah, you can certainly start thinking that way A big part of is doing things like, instead of focusing on

the structure of your code, focus on the behavior of your code Often that means having a lot of test case classes for one production class, or for a small group of production classes A lot of people have a mantra that, we’ll have class_x and class_x_test and that’s it And they have all kinds of ways to defend that Oh, it shows up together in the listing and it’s easy to find, and so forth But there are other ways to accomplish that So structuring your classes and your methods around the behavior and getting rid of that idea that you need a one to one correspondence, or you need– I mean, this is endemic in a lot of beginning OO-ers, that they’re afraid to make classes Oh, we want big classes that– so have lots of little test classes You should be building your test classes around the setup, around the fixture that you’re building The purpose of that test class is to encapsulate, this is one configuration of part of the application that the methods inside it run against, or run within So that should be how you’re organizing things and that gets you a long way toward doing BDD That’s one of the biggest changes, is to start structuring things around the pieces of behavior and around the context that those behaviors are exhibited in AUDIENCE: The book, The Art of Unix Programming talks about systems being discoverable and transparent Discoverable means they’re easy for a novice to get into, transparent means they’re easy for an expert to live in How do you organize your executable specifications to get discoverability and transparency and completeness? DAVID ASTELS: Whoo Did you get that? OK Good A lot of the discoverability is done through naming So you give good names that are self-evident That carries through That’s sort of a truism But if you name the classes well to reflect what the situation is– so empty_list– that reflect what the configuration of the world is for that fixture, and then name the methods that read right along with that, to describe what the actual behavior is that’s being tested So things like, empty.list.shoul d.have.no.elements That reads And if you’re using jUnit for this, you can actually– there’s a project called AgileDox Anyone familiar with that? I think TestDox is the actual program name You can Google it I think it’s on SourceForge But it basically goes through your test code, pulls out the class names and the method names, and assuming, since it’s Java, that they’re camel-cased, puts in spaces, fiddles the case, and puts out a bunch of one-liner specifications So with the right naming, you can actually run that and get a list of, OK, here’s all the behaviors of my program and the situations in which those behaviors occur Now, being able for an expert to live in it– I don’t really see a whole lot of difference there Most of it’s navigation, just being able to find things, knowing where to add new tests when you need to One of the side practices in TDD is, if you come up with a bug, the first thing you do is to write a test to expose it The question then is, well, where do I put that test? If you have class_x_test, well, OK, it’s a bug in class_x, I’ll put it in there, no-brainer But if you’re doing things a bit more intelligently, then sometimes it’s, OK, you have to give it a bit of thought What situation does this bug show up in? Where does it live best? Often the best way is to create a new test case class and put your test in there and look at, what do I have to do to get to the point where I can expose this bug? And maybe that’s going to match one of the existing test cases, and I’ll just move it to there That’s another thing Don’t be afraid to move things around to put them– it’s like with your production when you’re refactoring Put things where they belong best. So with the test code or the specification code, that fits too Often when I’m working and I’m going into a new area in the application– writing an application, test first, whatever– I’ll just start a new class I don’t want to worry about if there’s one existing I’ll just start a new class and check later, see how it evolves And I’ll move it if it’s appropriate Or I’ll grow it and, oh, I should split this up now, because I’m hitting two different functional areas and the setup’s starting to diverge So I’ll split it up into two classes Again? AUDIENCE: One of the things I liked about unit tests is that working on a little piece of code, I know that I’m testing

all the conditionals within the, say, ifthen [UNINTELLIGIBLE] test both Is it a little bit harder to make sure you’re getting good cover when you’re doing [INAUDIBLE]? AUDIENCE: Repeat the question DAVID ASTELS: So working with jUnit and having your test class, you’re hitting all the different branches, all of your paths through the code Is it harder if you have everything split up around the– I’d say, if you’re just trying to do it as a thought exercise, then yeah, probably But if you’re using some tools to help out, no So you can use Clover, for example That’s what I used to do code coverage, run the whole suite of tests under a code coverage measurement And it just points out what code isn’t getting run by your tests That’s what’s not getting covered AUDIENCE: Sometimes those can be a bit misleading And when you’re working on a little piece of code, you have a better, finer understanding of what it means to truly test a branch The code coverage can become a tool DAVID ASTELS: Yes OK, the question was, working on a small piece of code, you have a better idea of what you’re doing to test all the different branches, where code covering– AUDIENCE: Yeah What it really means to make a proper test of each branch DAVID ASTELS: OK And code coverage can be misleading there, because you might go through that and not get all the nuances Right? Yeah AUDIENCE: I have a question DAVID ASTELS: OK, go for it AUDIENCE: Didn’t you write that branch in response to some specification that needed it DAVID ASTELS: Zing Yeah Now, that’s one answer You shouldn’t have had that code in there in the first place if you didn’t have a test that required it, if you’re doing true TDD The other answer is part two of my answer, which is, yeah, code coverage gets you so far But it doesn’t give you all the information It’s a good first pass to make sure you don’t have any gaping holes in your coverage The next thing to do is more of a semantic code coverage, and for Java there’s a tool– I don’t know how active it is now But it’s a tool called Jester Has anyone run into that? I know Jeff probably has Jester essentially does semantic code coverage It takes your code base and makes one tiny change, but intelligently makes one tiny change So it will change a true to a false Or it will stick “and false” onto a logical expression Or “and true.” It will make little changes that change the logic, that are guaranteed to have a semantic change to the behavior of your program And then it will do a build and then it will run all of your tests And if nothing fails, it logs it And it logs it in enough detail that you can then go back after it’s all finished and get the report And it will say, OK, this line here, this if statement, I made this change and it should have caused the test to fail and it didn’t So it can point out some interesting things It can point out some redundancies, where you have an if statement that it really doesn’t matter which branch you take If you’re doing some XML processing, and the if statement does some structural stuff but logically it doesn’t make a difference in the XML– that happened to me, when I was writing the book actually Actually, I think it’s mentioned in the book that I found that But it’s very interesting to see what will happen And it will log it, like I said And you can find out [UNINTELLIGIBLE PHRASE] maybe it’s covered, it’s executed, by the tests but not in enough detail Your tests aren’t hitting all the conditions to exercise that And there’s a logical condition that isn’t covered properly So automation For things like that, use as much automation as you can to look at it and find out what’s going on At the back AUDIENCE: [INAUDIBLE]? DAVID ASTELS: OK, the crux of the question was, it still looks like testing Yeah Like I said, it’s the same thing you’re doing if you’re doing TDD well That’s the operative word In my experience, most people aren’t doing TDD well That’s why I wrote a book But yeah, technically you’re doing the same thing The big reason behind this is to try to get people away from thinking about testing and thing about specifications So really moving this activity into the design spectrum, or

the designer arena So people aren’t thinking about verification AUDIENCE: [INAUDIBLE]? DAVID ASTELS: OK I’m just going to paraphrase that back to you It looks like we’re writing a language to write specifications, and whether it’s– something about whether it’s Ruby or whether it could be used to write specifications for any programming language? Was that it? AUDIENCE: [INAUDIBLE]? DAVID ASTELS: That’s a good point And some people are actually talking about that, making, essentially, a specification DSL, domain-specific language, from this We’re writing in Ruby I gave some reasons Basically because we wanted to write it in Ruby, is what it comes down to But we could certainly do that with bindings to other languages It could become a specification tool and hooked in to drive whatever implementation language you want it And that could be one way it goes There are people talking about moving it in that direction AUDIENCE: [INAUDIBLE]? DAVID ASTELS: We started this– when did this get started? September Something like that I’d have to look back at my blog to see when that original post went up But I think it was in the September-October framework I’m not really sure what it’s being used on So I can’t really answer that We’re at release 0.4.0 now So it’s still very young Like I said, a couple weeks ago, we sat down and we gutted– all that expectations syntax you saw is about three weeks old We sat down We gutted the whole thing out, we threw it out, and we rebuilt it using Dave Chelimsky’s idea of having helper objects Because before, and this is one criticism that’s come up, is that we’re polluting the object namespace So the interface of object, we actually added methods to object, which is something really cool you can do in Ruby But it does come at a price So you saw a nice expectation, with the periods between them We had underscores, so we had a whole method, should_be_equal, was one method that we added to object So we backed away from that Now we have intermediate objects involved So there’s one method we added to object, and that’s should And that returns an instance of a should helper, which knows what be means, and actually be is just a syntactic sugar It loops back and returns self But it knows what equal means It knows what the other nomiture means And sometimes you actually get a chain of objects together that do the work So it’s a little recursive descent-y type parser in there too with the objects But now it’s very clean, in terms of– we only have one method that we add to object And it’s very lightweight and it’s a lot more sensible now, too I think you– AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Thank you The question is, specifications by nature are non-ambiguous You don’t want ambiguous specifications So why do we use should rather than must? The quick answer to that is that I lost that argument I strongly wanted it to be must and [UNINTELLIGIBLE] strong language AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Oh, yeah Just alias it, right? Yeah And I’m not convinced that it shouldn’t be must AUDIENCE: [INAUDIBLE] should means you think it ought to be that way but you can change your mind DAVID ASTELS: That was exactly my argument Should means it would be nice for it to be like this, but it’s not mandated AUDIENCE: It comes from down on high and you can’t think about it DAVID ASTELS: I finally acquiesced on that, at least temporarily, because if you look it up in the dictionary, one of the meanings of should is– it’s a good match I’m still not 100% convinced, and I guess I have until release 1.0 to get that all straightened out Yeah? AUDIENCE: I was just thinking that instead of responds_to, you could use understands, [INAUDIBLE] DAVID ASTELS: So the question there was, instead of

responds_to or should_respond_to, to use understands or something like that should_understand this message Yeah And again, as someone said, with Ruby that’s pretty easy You can alias methods So multiple selectors for a single method So we’ll probably do some of that That’s a good point That was sort of the last thing we added to that syntax It was like, oh, we have instance_of, we have kind_of, we respond_to OK We can just put those right in like that But yeah, that’s good You should get involved and send in those comments like that Yeah, if anyone wants to try this out, there’s the links later But again, it’s a very young project It’s very much evolving So if you try it out and you have some comments, please send it to us Yeah? AUDIENCE: Another terminology question If you’re using one of the old-style testing frameworks, you can call your method “tests,” and you can say, oh, I want to write a test for that, or you need to write another test. So what’s the short one- or two-syllable word for– DAVID ASTELS: Spec AUDIENCE: Spec? OK DAVID ASTELS: Yeah, the question was, with jUnit and so forth, you have test A nice snappy word And you can say, I need to write a test, or you need another test for that We don’t want to go around saying, you need another executable specification for that So we just call them specs, hence rSpec How are we? OK So I’m just going to finish off the slides AUDIENCE: [INAUDIBLE]? DAVID ASTELS: Yeah, I love that Yeah Here’s an interesting comment, just sort of on Ruby more than anything There’s where you can find rSpec If you have RubyGems installed, you just gem install rSpec and that will get it And you can watch my site, my blog for information and announcements and articles or whatever on rSpec And other things too, but that’s a lot of what I’m writing about now, is BDD and rSpec And that’s my slide set Any questions?