[rspec-users] Did I write my specs as I should?

David Chelimsky dchelimsky at gmail.com
Sun Nov 18 14:02:22 UTC 2012

On Sat, Nov 17, 2012 at 3:51 PM, dougui <dougui_bzh at hotmail.com> wrote:
> Hello,
> I read a lot about rails and BDD and I think I've found my own path. I want
> to share my method and to know what you think about that.
> This is my workflow :
> Creation of feature specs (example 1);
> Only the happy path
> Test only things than the user can view;

^^ This is a good guideline if you're not sharing these w/ non-tech
business folk. If you are, however, there are going to be cases
they'll want specified so you'll need to decide whether you want to
share the whole rspec suite or just those in the features directory.

> Don't test the number of records of the database, if an email is sent or other things like that;
> Keep it very simple;

^^ This can mean a lot of different things. I'd phrase this "keep
things very high level".

> Watch the feature specs fails;
> Create views and routes;

^^ This depends on _how_ the feature fails. What you do next is
completely dependent upon the failure message you get. What I often
find is that the first failure says "no route .." so I add a route.
The next failure is "no controller action ..." so I add an empty
controller action. Next is there's no view so I create an empty view
template. Now we get a logical failure instead of an error, saying the
content couldn't be found. At this point I'll start driving things out
in controller specs and view specs as necessary. If there is no
conditional logic in either place, I might bypass those
(controller/view specs) for the moment, but as soon as a new scenario
appears that forces any conditional logic into the controller or view,
they get their own specs.

> Watch the feature specs fail again;
> Create the controllers specs (example 2);

If you're just outlining them with pending examples (i.e. no bodies)
that's fine.

> Write the specs in complete isolation;
> Use Factory Girl's build_stubbed;
> Write a context for all conditons in ifs;
> Create the code for the controllers specs;

Not all at once. They idea is to implement one example, watch it fail,
then implement the code to make it pass, then on to the next example.

> Create the specs for all model's methods I stubbed;
> Write the code to pass the model's specs;
> Refactor;
> Continue to the next feature;
> I try to respect the single responsability principle (SRP) and Keep It
> Simple, Stupid (KISS).
> With the SRP, the controller should manage the majority of objects and it
> should not be a lot of depth. The models are used only for an interface with
> the database and do validation. All other things should have their own
> classes.

This is an implementation decision which is neither correct, nor
incorrect in the context of BDD.

> I write specs for mailers, helpers and all other classes.
> I found this mail :
> http://www.mail-archive.com/rspec-users@rubyforge.org/msg03883.html. And I
> think it's similar.
> I don't like Cucumber and I prefer Capybara.

You're comparing too different kinds of things. Cucumber supports a
language (Gherkin) for expressing requirements at a high level and
then binding those expressions to executable code. Capybara supports
interaction with a browser (real or simulated). You can't replace
Cucumber's role with Capybara. You can choose to bypass
Cucumber/Gherkin if you like, but if you're not replacing it with high
level language for expressing requirements, you're not doing BDD as it
is described by it's thought leaders (mostly Liz Keogh -
http://lunivore.com/liz-keogh) today.

This is not to suggest that what you're doing something has no value.
It's just not BDD.

> I read this :
> http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html
> but I just must moved my request in a feature folder. I don't want to create
> request tests. I think it test the same thing

I'd recommend you read
in which José Valim explains the different kinds of things he thinks
should go in feature specs and what he calls "api specs" (which spec
request object internals like headers and response codes).

> than my feature specs and it
> will be slow to create two integration tests.
> Example 1 : A Request Spec
> describe 'Create' do
>   it 'add a new project' do
>     sign_in
>     visit new_project_path
>     within('#new_project') do
>       fill_in("Title", with: "My Project")
>       fill_in("Url", with: "http://www.google.com")
>       select("Ruby", from: "Type")
>       click_button "Create"
>     end
>     page.should have_content("Your project was created")
>   end
> end
> Example 2 : A Controller Spec
> describe "#create" do
>     context "with valid data" do
>         it "redirect to project's path"
>         it "save the project"
>         it "set a flash message"
>     end
>     context "with invalid data" do
>         it "render new template"
>     end
> end
> What do you think about that? Did I write my specs as I should?

You're definitely on a good path, but it's difficult to judge by
looking at only an incomplete outcome. The answer to that question
lies in your own experience. Did the process help you clarify the
requirements and design for yourself? Do the existing specs give you
confidence that the code works properly? If you decided to support
oauth, how many specs would need to change? If you decided to move
from a sql database to a json api, how much of your spec suite would
have to change? Etc, etc.


> Thanks and bye!
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users

More information about the rspec-users mailing list