Unit testing advice

So should we write code first, or tests first?

Tests are themselves bits of code, so they may have bugs in them. No
really, I’ve put them there myself so I know. It’s galling to discover
that your “real” code is correct but the test is failing because you got
it wrong. Duh, I was looking for the bug in completely the wrong place!

This realisation puts code and tests on a more parallel footing. The
upshot is that code and tests should be written in parallel as far as
possible; certainly at method level. Most of the time I like to write a
test or two to exercise the few lines of code I’ve just written. By few
I mean typically 5…10.

I like to write my code first, tests second. Otherwise how do I know
what I’m supposed to be testing? (There’s no spec, I make things up as I
go along. This is a hobby, not work.)

Other people probably do things differently. :slight_smile:

Dave

Hi –

On Tue, 5 Aug 2008, Avdi G. wrote:

point of getting confused when you start talking about models that
don’t derive from ActiveRecord::Base. They’ve begun to identify
“Model” with “table in the database” rather than “model of a domain
entity”.

I repeat: if I’m creating an Order model and I know that it’s going
to belong to Customer, etc. That’s not the only possible scenario, but
it can happen. Obviously it has no bearing on non-AR models, and so
forth. There’s definitely an issue with over-identification of models
and tables, but we’ve been talking rather specifically about the case
where the associations and table structure are already known (or at
least a piece of them), and whether or not it makes sense, in the
presence of that knowledge, to refrain from implementing those things
until there are failing tests for them. The question of whether to use
belongs_to and so forth in the first place is important but different.

I challenge any Rails developer to start a a web app without a
database, leaving persistence for iteration 2. It can be an
eye-opening experience, forcing you to think more about domain
concerns and less about keeping MySQL happy.

I usually do it sort of the other way around: model the domain first,
then think about how that will play out in a database schema, and then
start to think about it as a Web app. I often spend a lot of time in
the console before I create a controller. Some people like to work
view-first. I’m the opposite.

I’ve never thought about keeping MySQL happy, I have to admit. I
expect it to keep me happy :slight_smile:

David

On Sun, Aug 3, 2008 at 2:23 PM, David A. Black [email protected]
wrote:

I’m afraid I don’t see the advantage of that, at least in every case,
over bootstrapping at least part of a database schema and model
structure first. Certainly the kind of thing you’re describing does
happen, but if I’m creating an Order model and I know that it’s going
to belong to Customer, I’m not averse to saying so up front. Also,
with a large table, you could get into an awful lot of migrations.

I’ve seen a lot of Rails coders completely lose track of the fact that
“Model” means “Domain Model” because of thinking like that. To the
point of getting confused when you start talking about models that
don’t derive from ActiveRecord::Base. They’ve begun to identify
“Model” with “table in the database” rather than “model of a domain
entity”.

I challenge any Rails developer to start a a web app without a
database, leaving persistence for iteration 2. It can be an
eye-opening experience, forcing you to think more about domain
concerns and less about keeping MySQL happy.


Avdi

Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com

Hi –

On Tue, 5 Aug 2008, Avdi G. wrote:

point of getting confused when you start talking about models that
don’t derive from ActiveRecord::Base. They’ve begun to identify
“Model” with “table in the database” rather than “model of a domain
entity”.

Just another follow-up (see also my earlier post, which addresses your
concerns directly): there’s a new screencast at railscasts.com today,
on exactly that topic: models that are not ActiveRecord models. It’s
here:

http://media.railscasts.com/videos/121_non_active_record_model.mov

I’m glad to see it, as this is something that people often don’t
realize is possible, and when they do it can be quite a revelation.

David

Hi –

On Tue, 5 Aug 2008, Phlip wrote:

realize is possible, and when they do it can be quite a revelation.

It don’t mean nothin’ if you can’t use the validators. We tried recently, and
could not get them working in a non-ActiveRecord model. After exceeding our
time-box, we simply made the model into an ActiveRecord table, with no
records in the database yet. It’s speculative coding, because we will need to
save the records for our next iteration.

But, in theory, most of the validators have nothing to do with the
persistence itself, so the ActiveRecord maintainers could go decouple them…

Couldn’t you just write a #valid? method for the class, or something
like that? If we’re talking about non-AR models, they’re probably not
going to have #save or #update_attributes and so on, so you presumably
wouldn’t be depending on a save-time validation suite. In other words,
what is the point in the life-cycle of the object that’s analogous to
saving an AR object, and can’t you intervene at that point?

David

David A. Black wrote:

Couldn’t you just write a #valid? method for the class, or something
like that?

Obviously yes but why should we have to? validates_presence_of :foo only
needs
to peek at self.foo, so why should we have to rewrite it?

I’m not talking about the advanced stuff like :scope => …

Hi –

On Tue, 5 Aug 2008, Phlip wrote:

David A. Black wrote:

Couldn’t you just write a #valid? method for the class, or something
like that?

Obviously yes but why should we have to? validates_presence_of :foo only
needs to peek at self.foo, so why should we have to rewrite it?

I think it’s reasonable for ActiveRecord::Validations to be fairly
hard-wired to ActiveRecord, so it might just be less trouble in the
end to roll your own for non-AR classes. Or maybe write
ActiveSupport::Validations, which could be more general (and not get
into the create/update/save distinctions and all that).

David

David A. Black wrote:

Just another follow-up (see also my earlier post, which addresses your
concerns directly): there’s a new screencast at railscasts.com today,
on exactly that topic: models that are not ActiveRecord models. It’s
here:

http://media.railscasts.com/videos/121_non_active_record_model.mov

I’m glad to see it, as this is something that people often don’t
realize is possible, and when they do it can be quite a revelation.

It don’t mean nothin’ if you can’t use the validators. We tried
recently, and
could not get them working in a non-ActiveRecord model. After exceeding
our
time-box, we simply made the model into an ActiveRecord table, with no
records
in the database yet. It’s speculative coding, because we will need to
save the
records for our next iteration.

But, in theory, most of the validators have nothing to do with the
persistence
itself, so the ActiveRecord maintainers could go decouple them…

On Sun, Aug 3, 2008 at 7:20 AM, David A. Black [email protected]
wrote:

The model generation just gives you a file with an empty class definition for
your tests, and I think something similar happens with RSpec. (Just to
clarify: I’m talking about model generation, not scaffold generation,
which does give you all sorts of tests and which I dislike strongly
and consider manifestly counter-productive.)

Hi David - I’m curious to know more about why you find this
counter-productive, if you wouldn’t mind sharing.

Cheers,
David

On Sat, Aug 23, 2008 at 6:24 PM, David A. Black [email protected]
wrote:

which does give you all sorts of tests and which I dislike strongly
was ever intended to), nor serves as a good learning tool (which I
believe it is supposed to be). It’s a one-trick pony, and there’s much
too much of a history of people getting confused or stymied because
they assume that what the scaffolding does is somehow a “default” or
authoritative application skeleton.

Hey David,

Thanks for the response. And here’s my late response to yours for much
the same reason…

I understood your previous comment to mean you found the code examples
generated by rspec to be counter productive, but now I’m sensing its
actually the scaffolding.

Forgetting about rspec or rails, my take is that generated code is
just like your own code as far as the ruby runtime is concerned, and
that if you are using generated code and maintaining it, that it
should be accompanied by a robust set of generated tests.

Agree? Disagree?

Thanks for playing,
David

Hi –

On Thu, 14 Aug 2008, David C. wrote:

On Sun, Aug 3, 2008 at 7:20 AM, David A. Black [email protected] wrote:

The model generation just gives you a file with an empty class definition for
your tests, and I think something similar happens with RSpec. (Just to
clarify: I’m talking about model generation, not scaffold generation,
which does give you all sorts of tests and which I dislike strongly
and consider manifestly counter-productive.)

Hi David - I’m curious to know more about why you find this
counter-productive, if you wouldn’t mind sharing.

Sorry – I didn’t spot this among the unread for some reason.

I don’t want to go into depth since we’re not in a Rails forum, but in
brief, it’s my experience that the scaffolding neither provides a good
starting point for a production application (which I don’t believe it
was ever intended to), nor serves as a good learning tool (which I
believe it is supposed to be). It’s a one-trick pony, and there’s much
too much of a history of people getting confused or stymied because
they assume that what the scaffolding does is somehow a “default” or
authoritative application skeleton.

David

David C. wrote:

Forgetting about rspec or rails, my take is that generated code is
just like your own code as far as the ruby runtime is concerned, and
that if you are using generated code and maintaining it, that it
should be accompanied by a robust set of generated tests.

Agree? Disagree?

Rails (you know - that web framework thingey) has a plugin that
generates a
scaffold, with good tests, and then you play with the code to add your
custom
features.

We were looking for a scaffold, and found this one had notes saying it
was
“officially” deprecated on behalf of another scaffold.

That one you could not edit. It was a framework inside a framework, and
you had
to research and apply every tweak to every (runaway) argument to their
entry
points, just to change anything.

We went with the “obsolete” version of the scaffold. (-:

Hi –

On Thu, 11 Sep 2008, David C. wrote:

clarify: I’m talking about model generation, not scaffold generation,
starting point for a production application (which I don’t believe it

I understood your previous comment to mean you found the code examples
generated by rspec to be counter productive, but now I’m sensing its
actually the scaffolding.

Yes, I meant the scaffolding.

Forgetting about rspec or rails, my take is that generated code is
just like your own code as far as the ruby runtime is concerned, and
that if you are using generated code and maintaining it, that it
should be accompanied by a robust set of generated tests.

Agree? Disagree?

It’s an interesting question. I’m trying to puzzle through whether
there might ever be a case where you’d be generating code but
generating the tests for it was for some reason prohibitively more
difficult. I think that if not then it makes sense to generate tests.
Or do the tests sometimes themselves involve code generation? (Maybe
just dynamic code generation.)

David

On Wed, Sep 10, 2008 at 7:04 PM, David A. Black [email protected]
wrote:

too much of a history of people getting confused or stymied because
actually the scaffolding.
It’s an interesting question. I’m trying to puzzle through whether
there might ever be a case where you’d be generating code but
generating the tests for it was for some reason prohibitively more
difficult. I think that if not then it makes sense to generate tests.
Or do the tests sometimes themselves involve code generation? (Maybe
just dynamic code generation.)

I meant the question more generally, but in the case of the rspec
generators, they do generate tests using the same command line
arguments that rails uses generate the application code. So if you
generate a resource with a ‘name’ attribute, the generated tests for
the new and edit forms expect there to be a form with an input for
‘name’.

render “/companies/new.html.erb”

response.should have_tag(“form[action=?][method=post]”, companies_path)
do
with_tag(“input#company_name[name=?]”, “company[name]”)
end

What’s your gut reaction to that? “Too much”? “Oh, cool”? “Ewwwwww”?
“Awesome”?

Hi –

On Thu, 11 Sep 2008, David C. wrote:

On Thu, 14 Aug 2008, David C. wrote:

and consider manifestly counter-productive.)
believe it is supposed to be). It’s a one-trick pony, and there’s much
generated by rspec to be counter productive, but now I’m sensing its

generate a resource with a ‘name’ attribute, the generated tests for
the new and edit forms expect there to be a form with an input for
‘name’.

render “/companies/new.html.erb”

response.should have_tag(“form[action=?][method=post]”, companies_path) do
with_tag(“input#company_name[name=?]”, “company[name]”)
end

What’s your gut reaction to that? “Too much”? “Oh, cool”? “Ewwwwww”? “Awesome”?

I have trouble getting past the concept of “generating a resource”, at
least as reflected in Rails scaffolding and usage generally; see:

http://dablog.rubypal.com/2008/3/23/splitting-hairs-over-resource
http://dablog.rubypal.com/2008/4/24/splitting-hairs-over-resource-part-2

Having the test certainly makes sense if you’ve definitely decided
that the generated code is what you want. In this case I think for me
the problem is more in the underlying code generation step itself.

David

On Thu, Sep 11, 2008 at 5:14 AM, David A. Black [email protected]
wrote:

The model generation just gives you a file with an empty class

difficult. I think that if not then it makes sense to generate tests.
render “/companies/new.html.erb”

http://dablog.rubypal.com/2008/3/23/splitting-hairs-over-resource
http://dablog.rubypal.com/2008/4/24/splitting-hairs-over-resource-part-2

Thanks for those excellent posts. I confess that I have not yet read
Fielding’s dissertation and you’ve piqued my interest. Although I had
to laugh when the link from your blog post
(Index of /~fielding/pubs/dissertation) led me to a
directory index rather than the resource (the dissertation) whose
representation I sought.

Hi –

On Sat, 13 Sep 2008, David C. wrote:

had to laugh when the link from your blog post
(Index of /~fielding/pubs/dissertation) led me to a
directory index rather than the resource (the dissertation) whose
representation I sought.

I guess I should have tested it first :slight_smile:

David

On Fri, Sep 12, 2008 at 4:08 PM, David A. Black [email protected]
wrote:

representation I sought.

I guess I should have tested it first :slight_smile:

Well, it just means that that URI points to a collection resource!
Nothing
technically wrong with that.


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/