On Thu, Jan 14, 2010 at 5:46 AM, John P. [email protected]
Normally in .Net when TDDing a controller class I would mock out other
library classes that the controller calls, such as Repository layer
classes. However I notice when using Cucumber people very rarely mock
anything and I’m assuming this is because Cucumber is meant for testing
the full stack (Integration testing).
Cucumber is intended for Acceptance Testing. The entry point into the
can vary. With Rails you can go through the browser (driving Selenium,
Watir, etc from Cucumber), start at the router, or even go directly to
model in cases where that’s appropriate.
re: Integration testing, everybody has a different definition. Before
came along, the prevalent definition that I was aware of was “testing
behaviour of two non-trivial components together.”
More recently, the definition that makes most sense to me comes from
Object Oriented Software . I don’t have the book in front of me, but
memory it is something like “testing your code with other code that you
don’t have any control over.” Because we need a database for all levels
Rails testing, this suggests that all Rails testing is Integration
In Rails’ terminology, however, “integration testing” means very
specifically testing the full stack minus the browser.
I’d normally do this with something like Selenium in .Net.
My question is, when creating a controller (or other class) that relies
on other library classes is it best to just use RSpec rather than
Cucumber to mock out the other dependencies and then bring in Cucumber
scenarios later when you know your RSpec tests are passing?
“is it best?” is always relative. YMMV. That said, the outside-in
BDD using Cucumber and RSpec together works well like this (borrowed and
modified from the 2nd post in
- Identify business need (the very outside)
- Discuss what feature would solve this need (feature injection)
- Write a Cucumber scenario that interacts with the system boundaries
have yet to be written)
- Run the scenario and watch it fail because the code doesn’t exist yet
- Write a little piece of the system boundary code that was missing and
caused the test to fail
- Run the scenario and watch it fail again, this time because the
code doesn’t do what it needs to yet
- Write a code example in RSpec
- Run the code example and watch it fail
- Write enough code to make it pass
- Run the scenario and check its status
- Repeat 7-10 until you have enough code (and not more than just
to make the scenario pass.
One catch-phrase that comes to mind is “use Cucumber to learn what code
write, use RSpec to write the right code.”
You should know that there is a trend these days among
users to not write controller specs on the basis that controllers are
covered by the Cucumber scenarios. The benefit is a faster suite that
appears to have less duplication between testing layers. The drawback is
that you lose the benefit of discovering model interfaces when you’re
specifying the controllers in isolation.
My view is that this makes sense for the boilerplate stuff, but
customizations of the controller are well served with isolated specs in
More answer than you bargained for, I imagine.