Manage a hierarchy of shared contexts based on spec file location
RSpec's shared contexts are a great way to organize group's shared stuff like examples and defs. Sadly enough, there aren't many public sources which guide how to organize shared contexts properly.
include_dir_context
is a nice hack you can use straight ahead to have a hierarchy of autoloaded shared contexts.
No gems or other dependencies are required, all you need is this README page.
- Copy code from spec_helper.rb to your top-level
spec_helper.rb
. - To define a shared "sub-context", use
shared_context __dir__ do
in aspec_helper.rb
at appropriate level. - To load shared contexts, use
include_dir_context __dir__
in an example group.
The demo contains a simple structure of specs which uses include_dir_context
just like any real project would.
Run this to see it in action:
$ bundle install --path vendor/bundle
$ bundle exec rspec
RSpec generates numerous warnings in case example group name is reused at different hierarchy levels.
$ bundle exec rspec
WARNING: Shared example group 'hierarchical' has been previously defined at:
/path/to/spec/demo/spec_helper.rb:11
...and you are now defining it at:
/path/to/spec/demo/group1/spec_helper.rb:7
The new definition will overwrite the original one.
WARNING: Shared example group 'hierarchical' has been previously defined at:
/path/to/spec/demo/spec_helper.rb:11
...and you are now defining it at:
/path/to/spec/demo/subdir1/group11/spec_helper.rb:7
The new definition will overwrite the original one.
WARNING: Shared example group 'hierarchical' has been previously defined at:
/path/to/spec/demo/spec_helper.rb:11
...and you are now defining it at:
/path/to/spec/demo/subdir2/spec_helper.rb:11
The new definition will overwrite the original one.
Well, RSpec is historically somewhat "procedural" and often expects you to use unique names for everything. Please drop me a line if you discover any affordable workarounds for this issue.
A minimum version of Ruby 2.0+ is required due to usage of __dir__
.
For older versions of Ruby use this clunky replacement:
File.realpath(File.expand_path("..", __FILE__)) # Poor man's `__dir__` for Ruby 2.0-.
— Alex Fortuna, © 2017