[rspec-users] Eliminating duplication from tests

David Chelimsky dchelimsky at gmail.com
Fri Apr 10 03:09:58 EDT 2009

On Fri, Apr 10, 2009 at 1:14 AM, Brandon Olivares
<programmer2188 at gmail.com> wrote:
> Hi,
> Lately I've found myself trying to reduce typing as much as possible, so
> when I have a lot of tests that only differ in a few variables, I tend to
> abstract them to reduce typing.

abstract or extract? I think you mean extract.

> For instance, I have an assert_form_errors method that I call within a
> describe block to ensure the proper errors are displaying. I have an
> assert_form_fields method to validate that the fields that have errors are
> wrapped in div.error, and the ones that don't are not (that method should
> probably be renamed now that I think of it, but I'm not sure to what). That
> one is especially useful because it can test all of the fields in one go.
> So is this necessarily bad? I've heard it's not always good to reduce
> duplication in tests, but it just seems much preferable than copy/paste.

If it's not always good, then it's probably not always bad :) It
really varies from situation to situation. You need to understand the
risks involved.

Can you please post specific examples of the use of these so we don't
have to talk in generalities?

> Also, I fear it is becoming more test-like than behavior, but that's the way
> my testing is progressing.

Of course your "testing" is progressing towards something more
"test-like." You're calling it "testing" so you're probably thinking
of it as "testing." You're using words like "ensure" instead of
"specify" and you've even named your expectations "assert_xxx" instead
of "expect_xxx."

TDD is *not a testing practice*. It is a design practice. The whole
reason BDD was created was to help get that point across, and you are
fighting it every step of the way in your example.

Don't feel bad about this. If it was easy, we wouldn't need to talk
about it. It is *very* subtle stuff. And it's confusing because the
very nature of a code example changes as soon as the code it specifies
gets written. Consider:

1. Write an example. There is no code, so the example is a
specification for code that doesn't exist.

2. Write code to pass the example. The example is now, in *addition*
to being a specification for that code, documentation of existing code
and a regression test for that code.

During step 2 the example itself does not change, yet it transforms in
its meaning. The example *is* a test, but not until after the code to
pass it is written. And that's even more confusing because we use the
terms pass and fail.

I have no idea if this is helpful :) Regardless, that is the intent.


> Brandon
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list