I have had this thread starred since I first saw it… finally a few
minutes to participate in our community! It’s been too long!
My question is this: In a world with Cucumber what is the value of
view specs?
I’ve used view specs as a learning tool to help folks (including
myself) “get” the whole separation of concerns concept between views
and how they get their data.
In my own personal journey writing examples against views helped me
transition to a better developer. A lot of pain I saw developing real
code early on but I couldn’t understand why suddenly came into focus
when the same pain was experienced writing those view examples.
This was long before Cucumber, and I must admit, I love Cucumber. For
most things view related I find it my first tool of choice since I
like to ensure things are there as a result of the app doing something
(or the user doing something to it)!
Personally I’ve noticed quite a bit of overlap between how I’d
structure my view specs and how I structure some Cucumber steps. I
tend to write both semantically and I try to focus on particular
sections of the page rather than just on content. So if there should
be a leaderboard widget with the top 3 scorers listed I don’t have
steps like:
Then I see “Bob”
And I see “Mary”
And I see “Fred”
To me those are pretty worthless steps. What if you’re logged in as
“Bobby”? Okay, I know that might seem like a far cry, but this has
actually happened (at least to me). Where information that seemed
unique at the time ended up not being so unique has the app involved
into a smorgus board of social networking mashups. And nothing is
worse than a false positive. Instead though I’d write:
Then I see the top 3 scorers in the leaderboard are:
| 1 | Bob |
| 2 | Mary |
| 3 | Fred |
And in my step definition I’d have something similar to:
within “.leaderboard” do
response.should have_selector(“.position”, :content => 1)
response.should have_selector(“.name”, :content => “Bob”)
end
This is actually the same exact code I would put in my view specs. The
only difference is the setup. Rather than using Cucumber’s Given/When
steps to set the page up, in a view spec I’d do something similar to:
before(:each) do
@bob, @mary, @fred = people(“Bob”, “Mary”, “Fred”)
assigns[:top_scorers] = [@bob, @mary, @fred]
end
At the end of the day I find myself following the same practices that
I did with view specs, I just utilize Cucumber a lot more to make them
run. Now there are things I like to write view specs for that I don’t
think are very well-suited for cucumber scenarios.
- site-wide navigation headers and footers
- views which display polymorphic data (like system event logs)
For me these things are less pertinent to a single feature. And I
enjoy the confidence of knowing navigation headers and footers are
rendering the proper links. I’ve also gone and added super small view
specs that look like this:
describe “projects/show.html.erb”
should_render_navigation_partial
end
I have a higher level of confidence that each the application-wide
systematically applied navigation is showing up on all of the pages
its supposed to. Scenarios suck for this kind of thing IMO. Just like
scenarios suck for ensuring resources are protected by logins or
permissions. I personally get a lot more confidence (and a lot less
boilerplate redundancy in some scenarios) with ensuring that an action
won’t run when the person doesn’t have a said permission. It’s just to
easy to declare in a controller spec and feel super confident:
describe ProjectsController do
# generic login
should_require_login :get
# privilege specific
should_require_privilege :get, :privilege => [:foo, :bar, :baz]
end
When there are many permutations of a thing to provide examples for I
find lower level specs are better for broader confidence (because you
control the low level inputs) than a high level tool like Cucumber’s
scenarios. Although I did watch a screen cast recently on some Obtiva
guys driving ruby class creation with scenarios.
View specs and cucumber scenarios have another thing in common though.
They can both be brittle if you’re not writing semantic markup and
instead focusing on the literal structure of the page (ie: “div ul >
li p + a”). Writing non-semantic markup in Cucumber will succumb to
same evil has writing non-semantic markup in view specs – unnecessary
maintenance time.
In the community (railscamp, for example) there are a fair number of
people using Cucumber and skipping view specs, but still speccing
controllers, models, tricky view helpers and so on.
Cucumber definitely overlaps with view specs and in many cases
Cucumber is a better choice for many reasons. But I still find times
where I write or would like to (if I’m not on a project with rspec and
view specs) a view spec. In the past few year what I write a view spec
has gone down considerably.
Why? Because they don’t find them helpful. Indeed they are seen as a
waste of time (money) not only duplicating Cucumber coverage, but also
introducing a high-maintenance example group which designers (who
don’t run tests) will frequently break.
Some of this goes to the makeup of the team as David pointed out, but
in general if you are wasting money writing doing anything unnecessary
than stop doing it. If the makeup of your team consists of designers
who aren’t able/willing to run specs and/or know how to fix them then
that is something to be considered. Also, if you’re duplicating
considerable amounts of outcome verification between Cucumber and the
view specs, then stop. If you get the coverage with your scenario then
let those drive the implementation.
In some cases you may find the language of the scenarios is more high
level and leaves out some details that should show up on a page which
you want to get some coverage against. If it doesn’t make sense to
keep adding things to scenarios view specs are a viable option. In
addition to the language of the scenario this may also depend on who
owns the scenarios. It’s much easier to use scenarios to cover a lot
detail when developers own them.
At the end of the day I would recommend utilizing view specs until you
get a good hang of them, maybe even on a personal project. That way if
you come across a situation where it might be applicable then you’ll
have the knowledge to know to use that tool. If you find Cucumber
meets your needs then you’ll be able to make that decision, empowered
with knowledge, and you’ll be able to contribute to your team with
more thoughtful ideas on how to organize scenarios, step definitions,
views, and specs in a way that maximizes communication, productivity,
confidence, and regression.
–
Zach D.
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD
training)
@zachdennis (twitter)