RSpec makes me want to write better code

On Fri, Sep 26, 2008 at 6:47 PM, Mark W. [email protected] wrote:

is defined in Ruby. I don’t know DataMapper, but it sounds as if it puts the
responsibility in one place - the Ruby code.

A little rails history:

Before migrations data was defined only in sql. The argument for this
was that it was DRY to only define the data in one place. The result
was myriad comments in everybody’s model files duplicating the schema
because they didn’t want to have to look in two places to understand a
model.

Enter migrations, which move data definitions to Ruby. Yay! Their in
Ruby. Except now they are STILL in another place :slight_smile:

Now putting the attributes in the model as DataMapper and Og do comes
with its own problems. AFAIK, deploys for either require migrations
developed in sql. Nothing for free :slight_smile:

You might well ask, “how far do you go in collecting currently useless
data?” And that would be a good question. :slight_smile: I would answer that it would
have to be decided by experience in dealing with business requirements, but
not completely by whether there is a current need for it.

Again - “If you don’t need it now, or can’t even justify the need for
it in the future.” If a customer wants it, then they should be able to
tell you why. If they can’t and they still want it, then you might
have to give it to them if you want to get paid, but the conversation
is important.

Conversely, if you “know” from experience that the customer is going
to need it, then you should be able to rationalize that for them in
terms of business value.

If somebody
thinks “we might need it later” then it should be discussed as a
requirement and either introduced as one or dropped. If “we might need
it later” then probably somebody has a good argument why.

Even with a good argument, “we might need it later” is unYAGNIsh.

YAGNI is a guideline, not a law. In practice, it doesn’t mean “don’t
ever do stuff you don’t need right now” - it means anything being
imposed right now that isn’t needed right now imposes a risk that it
will never be used, and the costs of that risk should be considered
when making the decision include or exclude a given feature or, in the
context of our discussion, data field.

If that cost is understood and a decision is made to include a
feature/data field anyhow because the perceived benefits outweigh the
perceived costs, then so be it.

If nobody
can think of a good reason, then why add the extra weight to the db
AND to the examples.

Again, because you’ve only got one chance to get that data.

Ah, I misunderstood that you were talking about data collection. I
agree that data collection brings up a lot of different questions, but
I still believe that any fields that we’re adding now that we don’t
have a need for now should only be added after first seriously
exploring what the need might be and with a clear understanding of the
maintenance costs. Not to mention the impact on users who might
divulge information. If you can’t rationalize why you need my fax
number, why in hell would I supply it? And if you ask me for 10 things
you don’t really need, my interest in filling out the form decreases.

there should be a huge red flag and serious
discussion about why requirements are being imposed on a system for
which nobody can argue business value.

Agreed, absolutely.

Thank god we agree!

Seriously - thanks for the convo. This is good stuff.

Cheers,
David

On 26 Sep 2008, at 17:28, Mark W. wrote:

On Fri, Sep 26, 2008 at 8:28 AM, Ashley M.
[email protected] wrote:

One downside to STI is it forces you to leave NULL columns for
attributes that don’t exist in all models. This is also really bad
for integrity.

I think all of your comments make sense, but I did just want to
call out that “the Rails way” is not typically concerned with this
sort of integrity at the database level. It’s handled in the model.

I wouldn’t call this the ‘rails way’ particularly - I think it’s more
of a general OO design philosophy that says the database is just an
implementation detail. I have gradually moved, over the years, from
feeling like the database needed to be the foundation of my whole
domain (and therefore have tight integrity rules etc) to wishing it
would just go away and stop bothering me. I like the way ORMs let me
work in code most of my day rather than having to drop into the
database to find out what the rules are.

cheers,
Matt

http://blog.mattwynne.net

In case you wondered: The opinions expressed in this email are my own
and do not necessarily reflect the views of any former, current or
future employers of mine.

I must say, I quite enjoyed that conversation. You guys (David and
Mark) both have some very good points, and it was great to see another
discussion about client interaction. Thanks guys!

Hi all,

does anyone have any tips or examples on how to run specs
programmatically? I’d like to manually
load some example groups, then perhaps reflect on their describes and
its, and then execute them
and get back a Ruby object which I can interrogate for the results.

thanks
Dan

2008/9/26 David C. [email protected]

On Fri, Sep 26, 2008 at 12:18 PM, Mark W. [email protected] wrote:

On Fri, Sep 26, 2008 at 9:47 AM, Ashley M.
[email protected] wrote:

To me, spec’ing attributes is a red flag. It is not always a bad thing
or wrong, but it suggests that the focus is on structure instead of
behaviour

What David said. A lot.

It seems these conversations come up time and again because Rails
overloads
the idea of “model”. In a Rails app the model serves as both your domain
model and your persistence strategy, because of the coupling inherent in
the
Active Record pattern. Your domain model should evolve out of solving
problems in your domain. For any non-trivial domain model the
persistence
strategy should be an entirely separate concern.

At the risk of going off on one, Active Record scales to exactly zero
behaviour
in your model. In other words it is perfect for
data-on-the-screen apps, which to be fair is about 90% of web apps. As
soon
as your domain model becomes sufficiently interesting it becomes a
contest
between us and the AR pixies. Luckily we have the likes of David and Pat
Maddox on our side :slight_smile:

If you start by specifying what you want your application to do in the
form
of a single user example (a scenario), the model should fall out of
solving
this. Unfortunately this doesn’t fit the model-driven (generators)
approach
that Rails encourages.

I’m not sure what advice to offer here, other than to be aware that
Rails
“best practices” are usually counter to an outside-in, behaviour-driven
approach to writing applications. So if you want to use all the code-gen
magic in Rails you will always be making these trade-offs.

Cheers,
Dan

On Sat, Sep 27, 2008 at 2:29 PM, Mark W. [email protected] wrote:

butt-simple relationships between models and tables that are found (as you
I know this view puts me on the wrong side of the contest you speak of
(which I frankly didn’t even know I’d entered). And yes, using Rails the way
I (and many others) do involves trade-offs. But the one trade-off it doesn’t
require is with TSTTCPW, which is the guiding philosophy in everything I do.
I guess this makes me an AR pixie. :slight_smile:

I think Dan means underlying magic code when he uses the word pixie.

On Sat, Sep 27, 2008 at 1:32 PM, David C.
[email protected]wrote:

On Sat, Sep 27, 2008 at 2:29 PM, Mark W. [email protected] wrote:

I guess this makes me an AR pixie. :slight_smile:

I think Dan means underlying magic code when he uses the word pixie.

Oh. Right.

Never mind. :slight_smile:

///ark

On Sat, Sep 27, 2008 at 10:32 PM, David C. [email protected]
wrote:

C). Finally, I thought, I don’t have to do anything to set up the
in any particular case, I don’t have to use it.
I know this view puts me on the wrong side of the contest you speak of
(which I frankly didn’t even know I’d entered). And yes, using Rails the way
I (and many others) do involves trade-offs. But the one trade-off it doesn’t
require is with TSTTCPW, which is the guiding philosophy in everything I do.
I guess this makes me an AR pixie. :slight_smile:

I think Dan means underlying magic code when he uses the word pixie.

Dan always says pixies for stuff he doesn’t understand. They don’t
have pixies in England I think.

Aslak

On Sep 27, 2008, at 12:16 am, David C. wrote:

This is really a deficiency of ActiveRecord migrations in my view.
DataMapper, for example, offers auto-migrations. You just add a
property to your model file and it takes care of the migration for
you. Of course, the way it does this is to drop the table and re-write
it, so you don’t want to do THAT in production :slight_smile: But for agile dev,
it’s a much nicer process.

Static migrations are essential, I think. Without them, you can’t
have repeatability. But auto migrations are cool for playing around
with stuff. Hobo migrations[1] nails it. You define the attributes
in the model class, and it compares your models and development
database to generate static migration files.

Unfortunately Hobo is very tied to Rails and AR. But DataMapper
already tracks attributes, so I wonder how hard it’d be to port…

Ashley

[1] √ 10 Best Textsheet Alternatives 2023


http://www.patchspace.co.uk/

On Sep 27, 2008, at 9:17 am, Matt W. wrote:

I wouldn’t call this the ‘rails way’ particularly - I think it’s
more of a general OO design philosophy that says the database is
just an implementation detail. I have gradually moved, over the
years, from feeling like the database needed to be the foundation of
my whole domain (and therefore have tight integrity rules etc) to
wishing it would just go away and stop bothering me. I like the way
ORMs let me work in code most of my day rather than having to drop
into the database to find out what the rules are.

Matt,

I agree with you - to am extent. The thing is, with a full suite of
stories (that work through the public interface) your entire app is
an implementation detail.

So anyway, my point is, if you disparage the database on the premise
it’s an implementation detail, you should apply equally little concern
to every other part of the app.

The reality I’ve found is that you find uses and insight in data long
after you initially decided how to model it - possibly long after you
stopped maintaining your app. And I’ve been in the situation of
having to unravel garbage and data corruption because someone didn’t
enforce DB integrity.

I think every component of an app should receive the same attention to
quality. It’s impossible to know where an edge case will sneak past
and bite you, so you have to cover as much as possible.

(Sorry if that was even rantier than usual - but I have a thing for
data quality!!!)

Ashley


http://www.patchspace.co.uk/

On Sat, Sep 27, 2008 at 11:26 AM, Dan N. [email protected] wrote:

It seems these conversations come up time and again because Rails
overloads

the idea of “model”. In a Rails app the model serves as both your domain
model and your persistence strategy, because of the coupling inherent in the
Active Record pattern.

Interesting. This coupling actually brought me to one of my first
“a-ha!”
moment in Rails (similar to when I first learned about the ++ operator
in
C). Finally, I thought, I don’t have to do anything to set up the
butt-simple relationships between models and tables that are found (as
you
say) in 90% of web apps (and other applications, too). Rails allows
models
as complicated as you want, and it also allows you to do work in the
database when you need to (I know “find_by_sql” is a dirty word, but it
allows me to perform pivots on multiple tables of millions of rows,
where AR
simply could not handle the SQL). But it makes the overwhelmingly common
case simple, and I like that.

So I’ve found that this model-db coupling to be a powerful feature of
Rails.
I know it’s saved me a lot of work, because I’ve had to do it manually
so
many other times in the last 25 years. If it’s not sufficient or
appropriate
in any particular case, I don’t have to use it.

I know this view puts me on the wrong side of the contest you speak of
(which I frankly didn’t even know I’d entered). And yes, using Rails the
way
I (and many others) do involves trade-offs. But the one trade-off it
doesn’t
require is with TSTTCPW, which is the guiding philosophy in everything I
do.

I guess this makes me an AR pixie. :slight_smile:

///ark

We do have pixies! They do all the “magic” stuff.

How else do you think it happens?

:wink:

2008/9/27 aslak hellesoy [email protected]

I like them much better than the gremlins.

On Sat, Sep 27, 2008 at 5:04 PM, Ashley M.
<[email protected]

wrote:

The thing is, with a full suite of stories (that work through the public
interface) your entire app is an implementation detail.

Yep. I would go further and say that, at the end of the day, the only
interface that matters is the user interface. If a user sees (no matter
how
indirectly) the same behavior, it doesn’t matter whether there’s a
database
on the other end or a herd of monkeys typing randomly into terminals.

Given that (the primacy of user experience), the database can be of
immense
importance to the app - far more than just a means of saving state so
you
don’t have to type everything in again each time you log in to the
application. It doesn’t matter if you’ve behavior-driven your
development to
the nth degree if a report isn’t available in an acceptable amount of
time.
Maybe for 50% of web apps (SWAG), you never need to think about this.
But
for apps that deal with millions of rows, the database (and the queries
against it) may be the single most important “implementation detail”
there
is.

///ark

Fernando P. wrote:

Hi,

Today is a big day. I officially transitioned from manually testing by
clicking around in my app, to automated testing with RSpec + Autotest.

6 months since my initial post, what happened in between?

  • My controllers are getting anorexic, and that’s good. An action
    typically does only 1 call to a model and behind the scenes that model
    will make other calls to other models and do some fancy stuff, this used
    to happen in the controller which was bad. Now it has become so easy to
    write model specs.

  • I don’t spec controllers, because it’s too painful to do. I don’t spec
    views either, because I tweak them too often, and it would take me more
    time rewriting view specs then actually coding the views. If there is
    something to test for is the rendering of the css across browsers,
    because that’s terrible!

  • I use cucumber+webrat to test that some important public pages render
    without a 500 error. I don’t care if the view has such div except if it
    is a critical one. What I mean is that I won’t test, all the assignments
    that should be on the page, as some tutorials demonstrate. This is
    nearly impossible to maintain.

  • I can refactor my code, immediately spot areas where my code got
    broken, and fix it. Before some parts of my app would be broken without
    having me knowing about it for a long time until some cool customers
    report a few bugs, but this was not an acceptable situation.

  • I don’t use Autotest, it sucks too much power, and it is too much
    distracting. From time to time I run specs to check if things look good,
    and always before updating the code on the server.

  • I have written my own Factory. It’s not OOP, it could be refactored,
    but it works 100% as advertised, provides default values, can handle
    associations, etc. I am pleased with it (I tried factory girl,
    machinist, etc and got pissed off). I encourage anyone to write his own
    little factory, to get a better hang of how to write good specs. I
    totally got mad with fixtures, it is impossible to maintain specs/tests
    with fixtures. Impossible.

  • I don’t do true BDD, i.e: I still write code before specs, because
    that’s what motivates me. I consider that seeing my app living and
    writing code for my app more important than writing specs. Specs are
    still important, but only as a bug reporting tool, they don’t add any
    value for the customer. In this crisis If I wanted an employee to resign
    by himself without paying him benefits (that’s how it works in Europe),
    I would make him write specs all day long, and forbid him from seeing
    the app and play with it. He wouldn’t last 1 week doing this.

What about you?

Best regards,

By “getting”, do you mean new controllers arrive skinny? Or that you
have
refactored the same fat controllers, over time, until they are skinny?

The latter is preferred, because we should not be writing the same sites
over
and over again. In theory!

My good ole’ fat pig controllers, are now nice, slim and fancy :slight_smile:

How often do you run your tests? Your editor should help you run them
after
every couple of edits. A lot of BDD is actually “cargo cult”

It depends. Overall I try to take small steps at a time. But never ever
will I update the server code unless 100% specs pass!

But you should want to test every few edits. More important, you
should be
able to correctly predict the result of each run.
As a habit I like to abuse of the save button even if I only corrected
some typos in comments, or changed the indentation. Suddenly autotest
would kick in for nothing.

Sometimes I save 4 files one after the other because I forgot about the
keyboard short cut for saving them all at once, and autospec will run 4
times instead of only once which is stupid. And growl will be notifying
me each time which is very distracting.

Fernando P. wrote:

6 months since my initial post, what happened in between?

  • My controllers are getting anorexic, and that’s good. An action
    typically does only 1 call to a model and behind the scenes that model
    will make other calls to other models and do some fancy stuff, this used
    to happen in the controller which was bad. Now it has become so easy to
    write model specs.

By “getting”, do you mean new controllers arrive skinny? Or that you
have
refactored the same fat controllers, over time, until they are skinny?

The latter is preferred, because we should not be writing the same sites
over
and over again. In theory!

  • I don’t spec controllers, because it’s too painful to do. I don’t spec
    views either, because I tweak them too often, and it would take me more
    time rewriting view specs then actually coding the views. If there is
    something to test for is the rendering of the css across browsers,
    because that’s terrible!

We TDD, and refactor, the living shit out of controllers and views.
Tools like
assert_xhtml and form_test_helper make TDDing them easier than creating
them by
code-and-fix.

  • I use cucumber+webrat to test that some important public pages render
    without a 500 error. I don’t care if the view has such div except if it
    is a critical one. What I mean is that I won’t test, all the assignments
    that should be on the page, as some tutorials demonstrate. This is
    nearly impossible to maintain.

How often do you run your tests? Your editor should help you run them
after
every couple of edits. A lot of BDD is actually “cargo cult”
“Test-Driven
Development” (Google the terms independently to see what I mean).

Someone would get the benefits you describe doing just some of the TDD
cycle,
but if they left out other parts they might blame the views for the
remaining
irritations.

  • I can refactor my code, immediately spot areas where my code got
    broken, and fix it. Before some parts of my app would be broken without
    having me knowing about it for a long time until some cool customers
    report a few bugs, but this was not an acceptable situation.

Right: Your car now has headlights, and brakes. This means you can go
faster.

  • I don’t use Autotest, it sucks too much power, and it is too much
    distracting. From time to time I run specs to check if things look good,
    and always before updating the code on the server.

But you should want to test every few edits. More important, you
should be
able to correctly predict the result of each run.


Phlip

Fernando P. wrote:

As a habit I like to abuse of the save button even if I only corrected
some typos in comments, or changed the indentation. Suddenly autotest
would kick in for nothing.

Autotest sucks. If we have too many tests, it runs them all, and this
slows us down.

Our editor support for TDD also sucks. It should run the most recently
edited
test cases, nearly automatically. Everyone swears by Textmate, and it
simply
can’t do that. Then, the Java-based editors also can’t do it!

Hi Phlip,
On 31/03/2009, Phlip [email protected] wrote:

Our editor support for TDD also sucks. It should run the most recently
edited test cases, nearly automatically. Everyone swears by Textmate, and it
simply can’t do that. Then, the Java-based editors also can’t do it!

What editor are you then proposing? Or are you saying that all current
editors lag behind XP practices?

Aidy

On Tue, Mar 31, 2009 at 12:16 PM, Phlip [email protected] wrote:

Fernando P. wrote:

As a habit I like to abuse of the save button even if I only corrected
some typos in comments, or changed the indentation. Suddenly autotest would
kick in for nothing.

Autotest sucks. If we have too many tests, it runs them all, and this slows
us down.

Or, conversely, autotest is awesome if you take the time to learn how to
use it:

http://blog.davidchelimsky.net/2008/3/5/limiting-scope-of-autotest