I enjoy writing code using BDD by starting from a user story and writing a cucumber feature to define what I want to see on the page. From there I drop down several levels from Cucumber to RSpec and back again as I go.
When creating a new cucumber feature using declarative steps, it’s normal to frequently have undefined steps. It’d be helpful if our editor could show us which steps are already matched (and thus defined in our step definitions) and which steps are undefined as a sort of progress bar to track feature step implementation.
This is possible with Vim and Syntastic. I’ll provide details about how to get this all working in the context of a Rails 4 application with Ruby 2.2.1.
Step 1
Alter your cucumber.yml
file to include a syntastic profile and use
the -r
flag to require the files contained within the step_definitions
directory.
1 2 3 4 5 6 7 8 9 |
|
Note: if your feature files are in a non-standard folder (features/steps
perhaps),
be sure to use that folder name instead of features/step_definitions
Step 2
Setup Vim to use the newly added syntastic cucumber profile in your .vimrc
:
1 2 3 4 5 |
|
syntastic_ruby_checkers
specifies both mri
and rubocop, which I highly recommend.
If you don’t want to use rubocop, just remove it from the array.
The last option is commented out, but is useful if syntastic isn’t working
properly. Just uncomment it, then save a feature file, and check the messages
output from vim in Command-line mode
with :messages
. This will show you the cucumber command that syntastic just
ran. Executing the command that syntastic tried to run yourself at the command
line is a great troubleshooting resource if something isn’t working right.
Here’s what syntastic should be trying to do at this point when running
a single feature file.
1
|
|
If you don’t use any gems that define methods that need to be available in step definitions then you’re done!
Working with gems that define methods that implement regex patterns
If you use the pickle gem or another gem that defines methods to help with regex matching in step definitions, then you’ll need to add a few more tweaks to get proper undefined step status reported from syntastic.
Notice the env var specified in the above cucumber.yml
file,
CUCUMBER_PROFILE='syntastic'
. This is so that we can conditionally require
some extra code in a few step definition files that need methods defined from
within the pickle gem to be available.
The “highlight undefined steps” feature of syntastic takes advantage of the
ability for cucumber to do a ‘dry run’ where it doesn’t actually execute any of
the code inside of the steps. It will, however, let you know if a step is
undefined. One caveat with --dry-run
is that it
doesn’t load the rails environment,
so the pickle steps that need to reach into the gem for some regex matching
will be shown as undefined. Initially I took the path of just defining these
methods inline in the file like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
However, the --guess
flag is required for cucumber with this setup. That
proved to be problematic and I had a lot of false positives that matched when
they shouldn’t have.
Since the rails environment isn’t loaded we need to manually require the necessary files to allow our pickle steps to call their gem’s methods.
Step 3
Create a features/support/pickle_dry_run.rb
with the following:
1 2 3 4 5 6 7 8 9 10 |
|
Step 4
In the pickle_steps.rb
file add this to the top:
1 2 3 4 |
|
This will conditionally require and includes the PickleDryRun
module during
a syntastic check so that the steps in pickle_steps.rb
can call out to the
methods contained within the pickle gem.
If you generated the pickle email steps, then we need to add something similar.
The top of my email_steps.rb
looks like this:
1 2 3 4 5 6 7 8 9 10 11 |
|
Step 5
To allow for factory_girl to work properly with pickle inside of a dry-run triggered by syntastic, we need to execute cucumber with spring.
Luckily, the ability to change the syntastic cucumber executable exists and is
easily configurable. Just beneath the syntastic_cucumber_cucumber_args
specify this in your .vimrc
:
1
|
|
This will use the cucumber binstub which relies on spring having already loaded the rails environment. The first request can be slow-ish, since spring has to spin up rails (if it hasn’t yet), but subsequent executions are very fast.
Just make sure that there is a cucumber binstub in the bin folder at the root
of the rails app. If there isn’t, be sure to check out
spring’s setup guide which mentions
the need to run bundle exec spring binstub --all
. The
spring-commands-cucumber
gem is also required as noted in the
spring readme.
With all of this in place, things should be working properly. As with most things vim though, closing completely out re-launching vim is usually necessary.
Now if you turn syntastic debug mode on, it’ll show cucumber executing from the binstub. Nice!
1
|
|
Next time you create an undefined step and save your feature file, it’ll look like this!