TDD killing my joy of Rails

I’ve been working through the book ‘Beginning Ruby on Rails E-Commerce’
which is very heavy on Test Driven Development. As in, you have to
write tests for scaffolding methods and validations and crap like that.
And then they fail. And you KNOW its the test not the method. So you
spend 2x the time writing a test that has to be adapted when
requirements change. You really are doubling / tripling your code.

Rails went from fun ActiveRecord magic tricks to a world of ‘TEST
FAILED.’ As a beginning Rails developer it has really taken all the fun
out of RoR development. Is TDD so much better than writing methods and
testing using a combination of the application interface and Navicat to
check the database? Because I hate it.

On 11/30/06, Taylor S. [email protected] wrote:

out of RoR development. Is TDD so much better than writing methods and
testing using a combination of the application interface and Navicat to
check the database? Because I hate it.

It is a lot of extra work. The # of lines of code usually outnumber
my actual app. But, it’s better than having a team of monkeys
clicking on every single link in my app everytime I deploy.


Rick O.
http://weblog.techno-weenie.net
http://mephistoblog.com

On Nov 30, 2006, at 3:31 PM, Taylor S. wrote:

Rails went from fun ActiveRecord magic tricks to a world of ‘TEST
FAILED.’ As a beginning Rails developer it has really taken all
the fun
out of RoR development.

Well, TDD is a choice. If it’s bad for you, exercise free will!

Is TDD so much better than writing methods and
testing using a combination of the application interface and
Navicat to
check the database?

Yes, it is. No question in my mind. TDD generally will slow you down
when you start using it, like anything new. But you’ll soon get into
the habbit, and you’ll be writing better code.

The big boost the you cannot see since you haven’t experienced it yet,
is when the application becomes more complex, and you make a change that
you KNOW works fine, and a test fails. You’ll grumble and say, “You see,
THAT is why I hate TDD.”

Then, while fixing the damn test, you’ll realize there’s nothing wrong
with it. You’ll then know, without question, why TDD works. It allows
you to make not only trivial changes with confidence, but serious tear
the wires out changes, and know that when the tests pass, you’re good
to go.

Because I hate it.

That’s a not insignificant part of the problem. :slight_smile:


– Tom M., CTO
– Engine Y., Ruby on Rails Hosting
– Reliability, Ease of Use, Scalability
– (866) 518-YARD (9273)

Taylor,

I hear ya… Writing tests can be a major pain in the butt. I don’t know
if
it’s possible to truly enjoy it, but it can really make a big difference
in
the long run. You can actually think of it as just another type of Don’t
Repeat Yourself, in that you’re putting in some extra work at the front
end
in order to save yourself from having to test and re-test stuff manually
as
your app grows and evolves.

If you write your tests well (and this is probably the hardest part,
IMHO),
they can immediately alert you to problems you create as you go along,
and
bugs that get introduced as you change functionality. My worst enemy are
always the unintended side effects of a modification… With well
written
tests, there is much less chance that this will be a problem.

And as I’m spending my day today writing a bunch of tests, I’m preaching
to
myself a bit too :wink:

Good luck,

Matt

On 12/1/06, Taylor S. [email protected] wrote:

FAILED.’ As a beginning Rails developer it has really taken all the fun
out of RoR development. Is TDD so much better than writing methods and
testing using a combination of the application interface and Navicat to
check the database? Because I hate it.


Posted via http://www.ruby-forum.com/.


Matt W.

Thermal Creative
http://blog.thermalcreative.com

Taylor S. wrote:

Rails went from fun ActiveRecord magic tricks to a world of ‘TEST
FAILED.’

This guy named DHH seems to agree with you:

http://www.43things.com/people/progress/David/16399

“I’ve been a test-driven developer for quite a while, but I haven’t
really gotten into the religious test-first branch yet.”

Who does he think he is??


Phlip
http://c2.com/cgi/wiki?ZeekLand ← NOT a blog!!

Taylor S. wrote:

testing using a combination of the application interface and Navicat to
check the database? Because I hate it.

Rails makes test-first somewhat hard, but still much easier than Brand
X.
You are lucky to have a book that gets you over the curve - and you just
recommended an otherwise boring title to me!

The fall-back is “developer-centric testing” where you alternate writing
test cases, writing code, and editing the test cases so they accept the
code
you wrote. I suspect that’s how Rails itself was invented, and it’s a
big
part of the reason why Rails is so powerful.

Tests break when you make big changes. The fix is to not make big
changes.
Make very small changes and pass all tests. When requirements change,
introduce the new requirement one tiny feature at a time. If a test
fails,
inspect it to see if it prevented you from making a mistake; if not,
adjust
it to the new requirements.

With even a little automated testing, you will debug much less, and your
projects have much more momentum. You can make small edits and run tests
with general assurance that things you forgot about did not break.

Without that support, you get debugging and churn, where fixing bugs
causes
more bugs. Yes, some of us feel nostalgia for the olden days, when the
Quest
for Bugs made us feel heroic. Get over it.

Under Debugger Driven Development, you start with fun magic tricks, and
descend into a nightmare of “app failed!”. And you might not even have a
clue which module to inspect.

Under TDD, if your program unexpectedly fails, you have an option that
debugging can’t provide:

→ you can revert your change ←

Treat that like a magic button on your editor called “kill bug”.
Debugger-driven development simply doesn’t provide that simple option.


Phlip
Redirecting... ← NOT a blog!!!

On Nov 30, 2006, at 6:31 PM, Taylor S. wrote:

Rails went from fun ActiveRecord magic tricks to a world of ‘TEST
FAILED.’

some people take the approach of stubbing all the tests you can think
of before you write the code (def test_should_incinerate_pie; end),
making sure the code more or less works, then running the existing
test suite to verify that you haven’t broken anyway, and last,
actually writing the contents of all those tests you stubbed out. it
isn’t as pure as tdd, but it does accomplish some of the major goals
(think about what should work and how, and be able to validate that
you have no regressions).

-faisal

On Nov 30, 2006, at 6:31 PM, Taylor S. wrote:

Rails went from fun ActiveRecord magic tricks to a world of ‘TEST
FAILED.’

I’m a newbie to TDD, and ran into it slightly BEFORE I hooked up with
Rails. In my “real job”, automated testing requirements came in without
the rest of the Agile approach in place, and there, it has been a real
drag to get into TDD. I was lucky to have a member of my team who was
not new to it, and he started feeding me the zen of TDD in the right
way. Not “we will now write tests for everything in the world before we
write the application”.

The job before us involved creating both a new XML based GUI layer and
also the glue and support code needed to hook that to an existing set of
“middleware” (this is phone UI stuff). I was doing the glue/support
code, and he was in charge of writing the XML stuff. He helped me
realize that the easy way for him to communicate just what he needed
from my part, was to write a test. He would send me an email something
to the effect of “I just added a test for BLAH”, and then I would go off
and write some stuff that makes his test pass, then he would hook that
up to his XML and goodness would happen.

Every now and then he would add to or change a test and say “I just
realized I also needed fooBah, so I just broke the test”, and I would go
in and instantly see from his test exactly what I needed to add to my
code. It has been a delightful way to communicate specific requirements
for our interface.

The key here is that we didn’t write “all the tests” and then write “all
the code”. Instead, we developed the app one piece at a time and used
the tests as a way to communicate what the top layer needed from the
lower layer.

Now we are into the last phase of the project where we are doing
profiling and looking for things to optimize. Taking specific large
hunks of my code and rewriting it is not a scary thing, even with the
release just days away, because I can and do run all of the tests after
I make both big and small changes, and when all the tests pass,
everything just works. Magic.

So I would say that you need to look at TDD in Rails more in line with
the Agile way of developing an app, quite like the process that the
“Dave’s” lay out in the Agile Rails book. The stuff about showing the
client and the client says “wow, that’s great, but what about yadda
yadda”, and that takes us to the next part of the development. Instead
of designing the whole thing down to the last iota of specificity before
you start, you just kind of feel your way through it, and you do the
tests as you go. Any you and the “business people” play with it a bit
and you notice something and you say, “hey, I shouldn’t be able to enter
so and so in this field” - translation “write a test that fails if the
user can successfully enter so and so in the field”, run it to verify
that it is breaking, then add the code that makes it pass.

It isn’t about spending 40 days and 40 nights writing tests before you
start on the real app. It’s just a different way of designing and
developing a product, that includes creating a “proof of the pudding” as
you go. Five minutes thinking about the state of the app and how to
take it to the next (tiny) level, followed by five minutes of writing a
few tests and five minutes of making the tests pass, and viola, we’ve
achieved a new level with our app, and we know it works right.

And because of the TDD approach, every little hunk of the project works
perfectly (within the limits of the requirements we have defined – i.e.
the tests we have written) as we go, so there just isn’t any of the old
way of “OK, it’s feature complete – in a few months we should have some
of it actually working right”.

jp

Despite all of the stuff you hear about how it will save you time in the
future, you’ll know when it breaks, etc, there is one huge benefit that
you
will soon realize that, to me, outweighs the rest:

It forces you to think about your logic twice. Once when you write your
tests, and once again when you write your code.

Unit tests let you get your business rules into code really quickly. If
you
do all of your business logic in the models, then this is more apparent.
For example… you may create a new user, but doing so will mean that he
will need to be assigned a default role and some basic rights. You
might
consider doing that in the user model’s after_save callback.

The smart thing to do (because you can’t easily see this from the web
interface) would be to write the test first.

def test_user_default_roles_created
u = User.create :username =>“homer”, :password=>1234
# user should have only one role… guest
assert_equal 1, u.roles.size
# more code would go here to actually verify that the “guest” role
is
assigned to the user by the callback
end

Doing that first helps me think about the end result and also helps me
decide if that is in fact the way I want to do it… maybe I don’t want
to
assign the role automatically… maybe I want something else to happen
instead.

Just my thoughts… I’m doing my best to convert more people to TDD and
am
working on a tutorial that helps explain how I use it to build apps…
The
Peepcode one rocks too so check that out as well.

Brian H. wrote:

It forces you to think about your logic twice.

I hate that part. I just want to claw my way from the submit_tag to the
database and then collapse.

However, I don’t want to have to do that again and again and again. I
want
my own workflow to be DRY.


Phlip
Redirecting... ← NOT a blog!!!

Even better… install ZenTest

gem install ZenTest

autotest --rails

Tests run when you save the corresponding file. Makes it almost too
easy.

Faisal N Jawdat wrote:

some people take the approach of stubbing all the tests you can think
of before you write the code (def test_should_incinerate_pie; end),
making sure the code more or less works, then running the existing
test suite to verify that you haven’t broken anyway, and last,
actually writing the contents of all those tests you stubbed out. it
isn’t as pure as tdd, but it does accomplish some of the major goals
(think about what should work and how, and be able to validate that
you have no regressions).

The goal is to make very few edits between test runs, and always predict
the
result of each test run. Either predict that all the tests pass, or
predict
what kind of error diagnostic you will see.

Don’t edit for a long time then expect tests to pass.

Configure your editor - whatever it is - to run all your tests when you
hit
F5.


Phlip
Redirecting... ← NOT a blog!!!

Jeff P. wrote:

The job before us involved creating both a new XML based GUI layer and
also the glue and support code needed to hook that to an existing set of
“middleware” (this is phone UI stuff). I was doing the glue/support
code, and he was in charge of writing the XML stuff. He helped me
realize that the easy way for him to communicate just what he needed
from my part, was to write a test. He would send me an email something
to the effect of “I just added a test for BLAH”, and then I would go off
and write some stuff that makes his test pass, then he would hook that
up to his XML and goodness would happen.

Nice - tests to define internal interfaces.

Note that fix requests to the Rails and related code repositories these
days
typically come with failing test cases.

And because of the TDD approach, every little hunk of the project works
perfectly (within the limits of the requirements we have defined – i.e.
the tests we have written) as we go, so there just isn’t any of the old
way of “OK, it’s feature complete – in a few months we should have some
of it actually working right”.

Shhhh! We need to keep that part a secret from the competition.

The few of them without pointy-haired bosses!


Phlip
Redirecting... ← NOT a blog!!!

Brian H. wrote:

Even better… install ZenTest

gem install ZenTest

autotest --rails

Tests run when you save the corresponding file. Makes it almost too easy.

My command line:

trigger ‘rake recent’ find test -name \\*.rb app//.rb
app/views//.rhtml

The utterly ugly and distastefully hacked-together contents of trigger
are
below my sig.

Any editor, folks. Any editor. I don’t even need to look at the console
to
hear the results. If the punk rock ain’t up too loud!


Phlip
Redirecting... ← NOT a blog!!!

#!/usr/bin/env ruby

lazy-loop until a file changes, then run a command

def syntax()
puts ‘syntax: trigger “command…args” files…’
exit 1
end

TODO support **

syntax() if 0 == ARGV.size

command = ARGV.shift
$fileTimes = {}

def anyFileChanged()
anyChanged = false

ARGV.each do |fn|  #  TODO  option to do Dir here
    begin
      mod = File.mtime(fn)
      anyChanged = true  if $fileTimes[fn] != mod
      $fileTimes[fn] = mod
    rescue
      puts $!
      sleep 2
    end
end

return anyChanged

end

anyFileChanged() # prime the pump

while true
sleep 0.333
if anyFileChanged()
got = system(command)

    sound  = got ?  'drumloop.wav' :   'jaguar.wav'

    weWin32 = RUBY_PLATFORM.include?('mswin32')

    if weWin32
        system('"C:\\Program Files\\Windows Media 

Player\mplayer2.exe"
/play /close s:\bin\’ + sound)
else
system(‘aplay ~/bin/’ + sound)
end

end

end

#One way is to use Win32API:

SND_MEMORY = 0x00000004 # from “mmsystem.h”
SND_FILENAME = 0x00020000

def playSound()

pPlaySound = Win32API.new(“winmm”, “PlaySound”, [‘P’, ‘L’, ‘L’], ‘I’)

play from file:

pPlaySound.call(“C:/your/sound.wav”, 0, SND_FILENAME)

play from memory:

#wav = File.open(“C:/your/sound.wav”, File::RDONLY) {|f| f.binmode;
f.read }

PlaySound.call(wav, 0, SND_MEMORY)

end

Brian H. wrote:

That’s pretty wild. I dig it.

With a little more work I’m going to get it to say “Ni!” when it passes
and
“Bad Zoot!” when it fails.


Phlip
Redirecting... ← NOT a blog!!!

That’s pretty wild. I dig it.

The more I test the less I’m afraid of having my application falling
down like a sand castle. I’ve done many sand castles before, none felt
down because I’ve been lucky.

Thanks to TDD (and Rails, because I’ve spend so many years trying to
setup TDD under J2EE with tools like Cactus without any result - I
thought I was stupid) I’m still earning my money developing applications
for customers but WITH JOY !!!

PLUS : Tests are now a commercial argument I use to convince my
clients/customers to choose me !

I’m still a dwarf at Agile development and TDD but compared to most of
the others companies/individuals here I’m a step ahead. And I dare to
say “I DO AGILE DEV, I DO TDD” every time I have the opportunity…

On 11/30/06, Taylor S. [email protected] wrote:

As a beginning Rails developer it has really taken all the fun
out of RoR development. Is TDD so much better than writing methods and
testing using a combination of the application interface and Navicat to
check the database?

Yes.

You are doing e-commerce, not an AJAX chat application or Blog on Rails.
So in theory there is money on the line. I haven’t read the book, or any
opinions on it, but it’s hardline approach to TDD in the context of
e-commerce automatically raises my opinion of it.

nuno wrote:

The more I test the less I’m afraid of having my application falling
down like a sand castle. I’ve done many sand castles before, none felt
down because I’ve been lucky.

Thanks to TDD (and Rails, because I’ve spend so many years trying to
setup TDD under J2EE with tools like Cactus without any result

Good lord I thought I was thru with this thread…

My last big project had a major issue (translation: failure) attempting
to
get Cactus working on a Tomcat project. I had more success TDDing CIAO,
but
its patron (a highly respected professor of programming) eventually
called
me a “lunatic” because I kept asking weird questions on their mailing
list.
I got CIAO (an advanced form of CORBA)completely under control…

…but I couldn’t even install Cactus. Each time I tried to configure
things, I would get stuck in some hideous error condition. Then, for
example, I couldn’t tell what the error was because I couldn’t turn on
logging, because the system wasn’t configured just right. That sick joke
of
a system lead to this page:

http://c2.com/cgi/wiki?ConfigurationHell

That’s the anti-Convention over Configuration - refusing to convene
anything, in fear that the user might override a default.

Someone will have to put a gun to my head to get me to write automated
tests
for Tomcat again, but if they do, I am ready: With Watir…

…and with a trick or two that are currently up my sleeve, folks! :wink:

PLUS : Tests are now a commercial argument I use to convince my
clients/customers to choose me !

Try “I can deploy continuously and deliver daily”…

Richard C. wrote:

You are doing e-commerce, not an AJAX chat application or Blog on Rails.
So in theory there is money on the line. I haven’t read the book, or any
opinions on it, but it’s hardline approach to TDD in the context of
e-commerce automatically raises my opinion of it.

TDD-ing the GUI Layer is very hard, so we have an excuse to slack off on
it.

Until someone fixes that. :wink:


Phlip
Redirecting... ← NOT a blog!!!

Jacob A. wrote:

I’ve heard of people doing TDD with Selenium. I’m not convinced that
having to use a browser to run your tests is not more trouble than it’s
worth especially for TDD - but people more clever than me seems to like
it.

Tip: Can we think of ways to TDD the GUI Layer without creating all of a
web
server, browser, DOM, etc.?


Phlip
Redirecting... ← NOT a blog!!!