I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.
nicknameoptional wrote:
I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.
There is a good Google video about rspec and Behavior Driven Development by the very well-dressed Dave Astels:
http://video.google.com/videoplay?docid=8135690990081075324&pl=true
···
--
James Britt
"A language that doesn't affect the way you think about programming is not worth knowing."
- A. Perlis
nicknameoptional wrote:
I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.
Well ... I don't "get" Test::Unit. It just seems so complicated and intricate. Rspec is a whole lot simpler to use, and it integrates some good tools, like Rcov. I think it's the perfect way to learn TDD/BDD.
I do have a bone to pick with the tutorial (or maybe I don't understand TDD/BDD yet). In the stack example, I cringe with horror when I see them setting a method that just returns "true" simply to get a test to pass. That grates on me, because I *know* I'm actually going to have to write the real code eventually. It seems like a waste of time to do the nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
Part of that may be the algorithm I'm implementing. It's very well defined already -- not something I have to "figure out" given a set of behaviors. But the same is true of a stack, which is the example in the tutorial. Everybody knows what a stack is supposed to do, everybody knows what the output from sorting an array of strings is supposed to be, etc. I think a better example would be something where you didn't "instantly" know what the code should look like -- a case where you really had some *behavior* but no code when you started developent, and had to "create" the objects and methods and classes from the behavior.
···
--
M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC(P)
http://borasky-research.blogspot.com/
If God had meant for carrots to be eaten cooked, He would have given rabbits fire.
I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.
Disclaimer: I am the lead developer of rspec and freely admit whatever
bias that might bring.
RSpec is a tool which tries to make BDD easier. BDD is an approach to
development that tries to tackle some of the problems that development
teams (customers, developers and testers) run into doing TDD.
For me, BDD addressed some questions that I had at the time I first
heard about it, so I got involved. It has changed the way I approach
development regardless of platform or tools.
RSpec does not set out to do more from a testing perspective than
'test/unit' does. It just tries to help you see the whole process
through a slightly different lens.
If you're not interested in seeing it through a different lens, there
may be no value in it for you. I can tell you that I've heard from
some skeptics who have really given it a shot that it does change the
way they approach testing.
Cheers,
David
···
On 1/19/07, nicknameoptional <dorrenchen@gmail.com> wrote:
"nicknameoptional" <dorrenchen@gmail.com> writes:
I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.
I don't know about you, but since I use test/spec[1] (my Test::Unit
based variant of RSpec), I enjoy writing tests and doing test-first a
lot more. I didn't think it would make such a big difference, but it
really does.
[1]: leah blogs: Announcing test/spec 0.2, a BDD interface for Test::Unit
(I hope to release test/spec 0.3 this week... speak up now if you wish
for anything.)
···
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org
There is a good Google video about rspec and Behavior Driven
Development by the very well-dressed Dave Astels:http://video.google.com/videoplay?docid=8135690990081075324&pl=true
--
James Britt
I still fail to see the value added by rSpec. In the video, one main
point I got was BDD try to break the 1-1 relation of class and test
class, which he said is useful if refactoring code. but writing rails
app, with convention over configuration ideology, I don't really do
that much refactoring.
and if you look at the example,
"@stack.should_be_empty" is mapped to stack.empty? method,
@stack.top.should_equal "one item" is stack.top == "one item"
besides more English like, how is it better than the assert_equal?
M. Edward (Ed) Borasky wrote:
I do have a bone to pick with the tutorial (or maybe I don't understand TDD/BDD yet). In the stack example, I cringe with horror when I see them setting a method that just returns "true" simply to get a test to pass. That grates on me, because I *know* I'm actually going to have to write the real code eventually. It seems like a waste of time to do the nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
It seems to be part of Kent Beck's definition of TDD. AFAICT, he excuses it away as, "well, this bogus 'true' method will be fixed when we get to the refactor stage -- duplication between the 'true' in the code and the 'true' in the test," but I don't really buy that.
Not all of the cases of cheating are going to be duplication -- say, you're supposed to be implementing the gamma function, but, starting off only testing natural numbers, you just implement fac first. AFAIK, implementing factorial is not going to help you implement gamma. Likewise, saying 'def size; 0 end' may make you feel better, but it's hardly progress towards an actual implementation of #size.
In any case, if the point is to keep the cycles short and to encourage the tests to be written, I'd at least like to inject a bit of pragmatism. We all get interrupted, have short memories, etc. -- at the very least, the stub implementation should be:
def empty?
true # XXX bogus code -- actual implementation pending tests
end
(Remember, imaginary folks who are the audience of this rant: Bad code should *look* bad.)
Fondly,
Devin
First of all, it's just a simple example for people brand new to
RSpec. It's good to take baby steps. As you do it more you'll
obviously combine a couple steps into one. But if you get stuck you
can always take a few steps back and then do the baby steps.
Now for the more important theoretical point...
There are two key parts when doing TDD/BDD. The first is writing a
spec that fails. The second is getting it passing. I do that every
single time, no matter how trivial the code is. After you've been
doing BDD for a while you'll probably write a spec and then write the
code, run the spec, and move on. That'll work really well for you for
a long time. Then one day you're going to do that and your spec will
pass, but some part of the behavior still doesn't seem right. You
spend a lot of time hunting this bug down, and finally you get
frustrated and tear out the new code to start from square one. And
you run your spec...and it's green. What the hell? You just yanked
out your code. Then you realize that you wrote the wrong spec, and
vow never to skip that trivial red step again.
Pat
···
On 1/19/07, M. Edward (Ed) Borasky <znmeb@cesmail.net> wrote:
I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually. It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
nicknameoptional wrote:
> I just discovered rspec today, reading the example and tutorials,
> besides the doc and coverage features, I can't see how is it different
> from unit test. For my rails app, existing testing tools in rails
> already fills all my testing needs. So what does rspec do more than
> existing testing tools? Thanks.
>
> http://rspec.rubyforge.org/tools/index.html
>
Well ... I don't "get" Test::Unit. It just seems so complicated and
intricate. Rspec is a whole lot simpler to use, and it integrates some
good tools, like Rcov. I think it's the perfect way to learn TDD/BDD.I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually.
That is very interesting, I just recently did the same, set up a method in
my testee
def method
end
and one more test passed I felt like a hero.
Now, maybe I should have felt like a Zero I think this question has a lot to
do with abstraction
and I try very hard to abstract. It kind of forces your mind *not to think
about implementation*.
So that is the setup I am pretty sure, if it is always the right thing to
do? Of course not!
It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
Part of that may be the algorithm I'm implementing. It's very well
defined already -- not something I have to "figure out" given a set of
behaviors. But the same is true of a stack, which is the example in the
tutorial. Everybody knows what a stack is supposed to do, everybody
knows what the output from sorting an array of strings is supposed to
be, etc. I think a better example would be something where you didn't
"instantly" know what the code should look like -- a case where you
really had some *behavior* but no code when you started developent, and
had to "create" the objects and methods and classes from the behavior.
Actually that is a really good point it is almost impossible to see a stack
abstractly!
Stacks should be forbidden in tutorials anyway ![]()
···
On 1/20/07, M. Edward (Ed) Borasky <znmeb@cesmail.net> wrote:
--
M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC(P)
http://borasky-research.blogspot.com/If God had meant for carrots to be eaten cooked, He would have given
rabbits fire.Cheers
Robert
--
"The best way to predict the future is to invent it."
- Alan Kay
nicknameoptional wrote:
> I just discovered rspec today, reading the example and tutorials,
> besides the doc and coverage features, I can't see how is it different
> from unit test. For my rails app, existing testing tools in rails
> already fills all my testing needs. So what does rspec do more than
> existing testing tools? Thanks.
>
> http://rspec.rubyforge.org/tools/index.html
>
Well ... I don't "get" Test::Unit. It just seems so complicated and
intricate. Rspec is a whole lot simpler to use, and it integrates some
good tools, like Rcov. I think it's the perfect way to learn TDD/BDD.I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
This dates back to the beginnings of TDD. I just wrote about this in
another thread, but for completeness' sake here: when you're doing TDD
as prescribed, you run all of your unit tests very often. The fact
that they all pass gives you confidence to move quickly rather than
stop and wonder what you might be affecting that's not immediately in
your view. If you make a change that introduces a problem and run the
tests right away, you discover the problem right away and don't have
to start debugging the work you've done over the last
minutes/hours/days.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually. It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
The triviality of the fix is the beauty of the whole thing. Every
problem gets broken down into really tiny bite size problems. You
don't have to hold up a delicate house of cards in your head that
falls down every time the phone rings.
Part of that may be the algorithm I'm implementing. It's very well
defined already -- not something I have to "figure out" given a set of
behaviors. But the same is true of a stack, which is the example in the
tutorial. Everybody knows what a stack is supposed to do, everybody
knows what the output from sorting an array of strings is supposed to
be, etc. I think a better example would be something where you didn't
"instantly" know what the code should look like -- a case where you
really had some *behavior* but no code when you started developent, and
had to "create" the objects and methods and classes from the behavior.
I agree. I'll add a new tutorial to the rspec website sometime soon.
David
···
On 1/20/07, M. Edward (Ed) Borasky <znmeb@cesmail.net> wrote:
--
M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC(P)
http://borasky-research.blogspot.com/If God had meant for carrots to be eaten cooked, He would have given rabbits fire.
Hi Ed,
I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually. It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
I don't look at this as "add a test to the spec/add a trivial fix to
the code" but instead as "add a test to the spec/do the simplest thing
that could possibly work to get the tests to pass", and I find
substantial value in this approach.
A few weeks ago I was doing BDD using RSpec and Francis Hwang's MockFS
library (which mocks the file system). I needed to add a method to
MockFS to mock File#size. So I added a spec that called File#size,
and ran it. As expected, I got some error about File#size not found.
I looked through the MockFS code to see where this error came from,
and I saw that MockFS had an array of symbols which were the names of
the methods that it mocked. :size wasn't in this array, which caused
the error. Looking at the MockFS code, I *knew* that I needed to do
two things: add :size to the array, and also implement the method that
mocked File#size. I remember being strongly tempted to do both these
changes before re-running the spec. But since I got the error because
:size wasn't in the array, simply adding :size to the array was the
simplest thing that could possibly work. So I did that, and re-ran
the spec, *knowing* that I was going to get a NoMethodError. But
instead, ALL MY TESTS PASSED. I was quite surprised. Investigating
what had happened, I discovered that Francis implements the mock files
as StringIO objects, so StringIO#size got called, which returned the
size of the string/file, which was correct, so all the tests passed.
(Duck Typing in action).
If I hadn't forced myself to try the simplest thing that could
possibly work, I would have had to implement (and debug) a File#size
mock method. This would have added unnecessary complexity to the
system. Worse, my experience is that once code gets implemented and
debugged, it rarely gets removed. So that code probably would have to
be maintained forever.
By forcing myself to always do the simplest thing that could possibly
work, I find that every day or two I come across a situation just like
this one, where a solution that I would have gladly bet serious money
that it was too simple to really work, actually does work. In
addition, every hour or two I find a solution that I thought might be
too simple to really work, that does work. Before I was doing BDD/TDD
I very rarely came up with simple solutions like this. The cumulative
effect is that my code is noticeably simpler and cleaner, and I find
this to be one of the major benefits I get from BDD/TDD.
Wayne
···
On 1/19/07, M. Edward (Ed) Borasky <znmeb@cesmail.net> wrote:
---
Wayne Vucenic
No Bugs Software
Ruby, C# and Erlang Agile Contract Programming in Silicon Valley
Christian Neukirchen wrote:
"nicknameoptional" <dorrenchen@gmail.com> writes:
I just discovered rspec today, reading the example and tutorials,
besides the doc and coverage features, I can't see how is it different
from unit test. For my rails app, existing testing tools in rails
already fills all my testing needs. So what does rspec do more than
existing testing tools? Thanks.I don't know about you, but since I use test/spec[1] (my Test::Unit
based variant of RSpec), I enjoy writing tests and doing test-first a
lot more. I didn't think it would make such a big difference, but it
really does.[1]: leah blogs: Announcing test/spec 0.2, a BDD interface for Test::Unit
(I hope to release test/spec 0.3 this week... speak up now if you wish
for anything.)
I like the continuity with test/unit. I'd be more likely to use this than rspec for my older projects.
Questions (from a BDD newbie):
Are the context and specify argument strings purely documentation, or do they need to be class or method names?
Is it possible to nest contexts? Is this a good idea?
Inside of a context, is there a setup/teardown protocol as there is in test/unit?
···
--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
M. Edward (Ed) Borasky wrote:
I do have a bone to pick with the tutorial (or maybe I don't understand
TDD/BDD yet). In the stack example, I cringe with horror when I see them
setting a method that just returns "true" simply to get a test to pass.
That grates on me, because I *know* I'm actually going to have to write
the real code eventually. It seems like a waste of time to do the
nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.
The idea behind doing small steps is that you know exactly what went wrong
when you run the tests. If you roll several steps into one test/development
cycle then you have many possibilities to investigate what went wrong if
they fail.
Sometimes, it is easier to skip the most trivial steps though!
···
--
View this message in context: http://www.nabble.com/I-don't-get-rspec-tf3042672.html#a11287619
Sent from the ruby-talk mailing list archive at Nabble.com.
nicknameoptional wrote:
besides more English like, how is it better than the assert_equal?
It's not. If you're doing TDD right, then BDD is just what you're doing
already, by another name.
The problem is a lot of people don't do TDD right, and the semantics of
it raise the barrier to entry.
BDD is about trying to change those semantics, so TDD
As-It-Was-Meant-To-Be becomes more popular. It's just a bonus that
rSpec reads so nicely and prints out nice looking reports.
So I was in the same boat as you. Then I decided: "You know, they have
a point about people misinterpreting TDD. So is trying to change the
language used to describe it really such an awful thing?"
And that's where I am now.
Is using rSpec in your projects going to increase velocity by 10%? Or
make it easier to communicate with business people? Or allow you to
write better tests? Have fewer bugs? Any of these things? No. Not if
you're already doing TDD well. It might help more developers to get
there though. It might help new team-members integrate faster with less
training on TDD and the way you're doing things. It might just give you
a warm fuzzy. Compared to a lot of the arbitrary and complex choices we
sometimes make, you could do a lot worse I think.
nicknameoptional wrote the following on 20.01.2007 01:20 :
There is a good Google video about rspec and Behavior Driven
Development by the very well-dressed Dave Astels:http://video.google.com/videoplay?docid=8135690990081075324&pl=true
--
James BrittI still fail to see the value added by rSpec. In the video, one main
point I got was BDD try to break the 1-1 relation of class and test
class, which he said is useful if refactoring code. but writing rails
app, with convention over configuration ideology, I don't really do
that much refactoring.and if you look at the example,
"@stack.should_be_empty" is mapped to stack.empty? method,
@stack.top.should_equal "one item" is stack.top == "one item"besides more English like, how is it better than the assert_equal?
assert_equal is ambiguous and as said in the video, many mismatch the
parameters (I've done it several times myself).
@object.method.should_equal is less prone to errors.
This specific comment aside, from what I understood from the video the
main benefit is that it helps those who don't really get the test
process with TDD not being confused by the naming used in Test::Unit. It
keeps them in the right set of mind: "How should objects in some
contexts behave?" and not "what equality/difference/basic property/...
should I test?". This single change of context doesn't seem so helpful
at first glance, but in practice I've seen numerous developers
(including myself) being drowned in tests, adding new useless or
unimportant ones because they lost focus on what they should test:
correct behaviour of the application and its components. So I believe
this approach can help ("the language shapes the thought" as mentioned
in the video is probably true from my point of view).
A good point is that it definitely enhances test readibility too.
Lionel.
M. Edward (Ed) Borasky wrote:
> I do have a bone to pick with the tutorial (or maybe I don't understand
> TDD/BDD yet). In the stack example, I cringe with horror when I see them
> setting a method that just returns "true" simply to get a test to pass.
> That grates on me, because I *know* I'm actually going to have to write
> the real code eventually. It seems like a waste of time to do the
> nitty-gritty "add a test to the spec/add a trivial fix to the code" cycle.It seems to be part of Kent Beck's definition of TDD. AFAICT, he excuses
it away as, "well, this bogus 'true' method will be fixed when we get to
the refactor stage -- duplication between the 'true' in the code and the
'true' in the test," but I don't really buy that.Not all of the cases of cheating are going to be duplication -- say,
you're supposed to be implementing the gamma function, but, starting off
only testing natural numbers, you just implement fac first. AFAIK,
implementing factorial is not going to help you implement gamma.
Likewise, saying 'def size; 0 end' may make you feel better, but it's
hardly progress towards an actual implementation of #size.
There's a point that Kent makes I'm not seeing in your description.
Hard coding the return value gets you right to a green bar, which is a
very important part of refactoring. As you refactor towards the real
implementation, the passing tests are an invariant that helps you to
know that you're not doing things that adversely affect not only the
method that you are working on, but everything else that you've
already written.
The value of this is difficult to see in the trivial examples we see
in books, but as an application grows it becomes increasingly
important.
In any case, if the point is to keep the cycles short and to encourage
the tests to be written, I'd at least like to inject a bit of
pragmatism. We all get interrupted, have short memories, etc. -- at the
very least, the stub implementation should be:
def empty?
true # XXX bogus code -- actual implementation pending tests
end
If that helps you to feel more confidence so that you can progress,
then do it. That's an important point of TDD. To provide YOU with
confidence that you're doing the right thing.
Cheers,
David
···
On 1/20/07, Devin Mullins <twifkak@comcast.net> wrote:
(Remember, imaginary folks who are the audience of this rant: Bad code
should *look* bad.)Fondly,
Devin
> There is a good Google video about rspec and Behavior Driven
> Development by the very well-dressed Dave Astels:
>
> http://video.google.com/videoplay?docid=8135690990081075324&pl=true
>
> --
> James Britt
>I still fail to see the value added by rSpec. In the video, one main
point I got was BDD try to break the 1-1 relation of class and test
class, which he said is useful if refactoring code. but writing rails
app, with convention over configuration ideology, I don't really do
that much refactoring.
You may not now, but if you have to maintain your app over a long
period of time, with changing requirements, you will likely have to
some restructuring of some kind.
This is an interesting thing about Rails in general right now. It's
still in its infancy and there aren't too many companies besides 37
signals that have had to maintain Rails apps over several years. I
think as that happens that we'll see more and more interest in
refactoring strategies and tools.
and if you look at the example,
"@stack.should_be_empty" is mapped to stack.empty? method,
@stack.top.should_equal "one item" is stack.top == "one item"besides more English like, how is it better than the assert_equal?
It clarifies which comes first, the expected value or the actual value:
assert_equal(5, result) ???
assert_equal(result, 5) ???
result.should == 5
That's pretty easy to get right.
···
On 1/19/07, nicknameoptional <dorrenchen@gmail.com> wrote:
I saw Dave Astels talk about this, at Canada on Rails, and initially I
thought it was a bunch of BS. It seemed like the only difference
between BDD and TDD was the words; everything else was just the same
thing with new names. Like the only development involved was a bunch
of alias statements. But I was totally wrong. What you're really doing
is a more intuitive, smoother version of TDD which produces
documentation as its byproduct. TDD isn't really about testing -- it's
about design. BDD makes it easier to use TDD for what it's really for.
···
--
Giles Bowkett
http://www.gilesgoatboy.org
http://gilesgoatboy.blogspot.com
Joel VanderWerf <vjoel@path.berkeley.edu> writes:
I like the continuity with test/unit. I'd be more likely to use this
than rspec for my older projects.Questions (from a BDD newbie):
Are the context and specify argument strings purely documentation, or
do they need to be class or method names?
They can contain anything except NUL bytes (the extended symbol
syntax). They are turned into class and method names automatically
(we need some special formatting for that due to Test::Unit
restrictions).
Is it possible to nest contexts? Is this a good idea?
test/spec allows them since 0.2, and I use them to group contexts that
go together. Note that nothing is inherited, it's purely namespacing.
RSpec doesn't have them, and they aren't interesting in implementing
them AFAICT.
Inside of a context, is there a setup/teardown protocol as there is in
test/unit?
Yes, you can use
context "Blah" do
setup do
@blah = Blah.new
end
teardown do
@blah.destroy!
end
end
You can have multiple of these, and they are run in order of
appearance.
···
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org
Wayne Vucenic wrote:
I don't look at this as "add a test to the spec/add a trivial fix to
the code" but instead as "add a test to the spec/do the simplest thing
that could possibly work to get the tests to pass", and I find
substantial value in this approach.
When I do TDD, I approach it with a Jeckle and Hyde perspective. When I
write a test, I am writing a specification of how the code should work.
When I start writing code, I become the laziest programmer you can
imagine, writing only enough code to pass the specification as it is
written at that moment. If it is not called out in the spec, it doesn't
get written.
When I switch back to test writing, I cuss out that lazy programmer
(i.e. me just a few moments ago) and write additional specs to force the
code to do exactly what I want.
The tension between Dr. Jeckle (the spec writer), and Mr. Hyde (the
programmer) causes Dr. Jeckle to write better specs and Mr. Hyde to
write lean, correct code.