How to use multiple spec_helper.rb files - ruby

I would like to create and use more than one "spec_helper.rb" to set up different block of codes for each project.
Is that possible? If so, how can I call a specific "spec_helper.rb" in my test file?

spec_helper.rb is not special, it's just a ruby file that you then require from other files (generally the files that define your specs). You can change the name (or have multiple differently named files) that you then require when needed.
Beyond that your question asking about setting up different blocks of code for different projects doesn't make a lot of sense since different projects would each have their own spec_helper.rb by default.

Related

Organizing Cucumber Steps

I am dealing with huge code base where features are grouped by domain in and are kept in separate packages.
+ServicesDomain
    |---+features
         |+step_definitions
+SalesDomain
    |---+features
         |+step_definitions
But there are always some common steps and I could not find a way to keep the common step definitions in some common steps package.
What I would like to know is that, if there is way to keep all the generic steps in some common package and make my domain package depend on generic steps package to leverage the generic steps.
One way of doing it would be to set up a file called features/support/env.rb and add a 'require' statement to this file to include your common steps each time. For instance, the file could contain:
require File.join(File.dirname(__FILE__), ​'..'​, ​'common'​, ​'common_steps'​)
That way your common_steps.rb would be loaded each time.
env.rb is the first file to be run on each Cucumber run.
Have you also heard of the Pickle gem? That might be worth a look as it does something similar by putting common steps into a file called 'pickle_steps.rb'. This comes with handy step definitions for testing models but there would be nothing stopping you editing that file and adding your own.
Hope that is of some help?
Cucumber has a command line option -r that allows you to include specific files. If you run cucumber --help, you can get more information about all the command line options. In ruby you can combine this with a config.yml file to setup globally how cucumber is run in the project. However I suspect you are using java, and I don't know if that applies. You could ask on the cucumber mailing list if thats the case.
An alternative would be to place a file in each support directory e.g. ServicesDomain/features/support and SalesDomian/features/support that just has a require statement that pulls in all the common steps. Cucumber automatically loads all the files in features/support (when it is run from features/..).

Cucumber step definition folder naming

I have just started using cucumber and am seeking clarification whether the folder having my step definitions must be named exactly as step_defnitions or can it be anything (e.g. my_defs). I tried renaming in my local machine but sometimes it works and sometimes doesn't.
features/
|
|-- step_definitions/
Cucumber will automatically load any files within the features folder. This means that your step definition files can be located in any folder name/structure as long as they are in the features folder.
Note that it is possible to override this setting and explicitly state the location of your steps by doing:
cucumber -r your/steps/folder/location
For more details you can see the help - cucumber -h:
-r: Require files before executing the features. If this option is not specified, all *.rb files that are siblings or
below the features will be loaded auto-matically. Automatic loading is
disabled when this option is specified, and all loading becomes
explicit. Files under directories named "support" are always loaded
first. This option can be specified multiple times.
In every reference I've seen (including the RSpec Book), they always have a "step_definitions" folder for definitions. A lot of things in Ruby (and especially Rails) utilize a "convention over configuration" philosophy, and I believe this is one of those things. I think it'd be less hassle for you to just make the "step_definitions" folder inside the "features" folder and know that it should work than to try and figure out how to change the configuration.

rspec require spec_helper in .rspec file

I've noticed that projects such as bundler do a require spec_helper in each spec file
I've also noticed that rspec takes the option --require, which allows you to require a file when rspec is bootstrapped. You can also add this to the .rspec file, so it is added whenever you run rspec with no arguments.
Are there any disadvantages to using the above method which might explain why projects such as bundler choose to require spec_helper in each spec file?
I don't work on Bundler so I can't speak directly about their practices. Not all projects check-in the .rspec file. The reason is this file, generally by current convention, only has personal configuration options for general output / runner preferences. So if you only required spec_helper there, others wouldn't load it, causing tests to fail.
Another reason, is not all tests may need the setup performed by spec_helper. More recently there have been groups of Rubyists who are trying to move away from loading too many dependencies into the test. By making it explicit when spec_helper is required in the test people have an idea what may be going on. Also, running a single test file or directory that doesn't need that setup will be faster.
In reality, if all of your tests are requiring spec_helper and you've make it a clear convention on the project there's no technical reason you can't or shouldn't do it. It just may be an initial surprise for new people who join the project.
With a proper setup, there's no downside at all.
The .rspec file is meant to be project related (and should be commited like any other project source file).
Meanwhile, the .rspec-local is for overriding with personalized settings (and it will let the user override some options only).
(see: https://www.relishapp.com/rspec/rspec-core/v/3-2/docs/configuration/read-command-line-configuration-options-from-files)
Rails projects even use a separate --require rails_helper for Rails-specific RSpec settings.
Both the .rspec and --require options have existed since 2011 at least (which is ages ago).
And, RSpec is especially not a tool for people needing training wheels - you want people to understand how RSpec works and what the options are, because you want people to know e.g. when and where to temporarily set the --seed option, how to change the formatter, switch on --fail-fast, use specific tags to work on a feature, etc.
The test environment also has to have a consistent configuration, so you do not want people tweaking the spec_helper file or the .rspec file (for the same reason).
In short: if it doesn't apply to every spec in the project, it shouldn't be in the spec_helper file. Which is why you should make sure it is included by every spec file. And the .rspec file is the best way to do that.
The only reason to not to switch to this is when the project is being actively maintained by many people (and any project wide change just creates annoyances by e.g. forcing people to rebase their work for no reason related to what they were working on).
Bundler fits into this category - to many people potentially working concurrently.
P.S. I also recommend using rspec --init on an empty project and checking out the generated config.

How to load a spec_helper.rb automatically in RSpec 2

When developing gems in Ruby, I almost always need a file in which I can configure RSpec to my needs and maybe before doing that, require some helper modules which should be available in all my spec examples.
In Rails applications a file named spec/spec_helper.rb is used for that. One thing that annoys me is that in the typical Rails environment, you have to require this spec_helper.rb file in every file that contains examples for it to be loaded. In the past I had a lot of problems with this related to changing load paths and relative require paths inside the example files.
Now for my gems, I would wish to have a way to just say RSpec to require the spec_helper.rb file before loading any of the examples files. Independent of the fact if I call rspec executable, or the rake spec task which I may define in my Rakefile.
I know I can tell RSpec only the location of my spec_helper.rb is this spec_helper.rb requires all the example files manually, but I would also like to avoid the additional maintenance of that approach.
Is there a nicer way to accomplish this?
In RSpec 2, the /spec folder is always automatically on your load path. This means that all you need is:
require 'spec_helper'
at the top of your spec files. This will always load /spec/spec_helper.rb, and is the minimum you'll be able to get away with.
This means you don't need a horrid approach such as:
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_helper.rb')
(which needs to be updated for different nesting levels).
Also you can add to your .rspec file the option: --require spec_helper, which will require this file in each spec file, without the manual require statement at the top.
The --require spec_helper line is automatically added to the .rspec file for RSpec 3.0 when you do rspec --init.

Is there a location for custom Ruby libraries to be stored so Ruby can find them?

I have written a module that has some generic, reusable code that I would like to be able to use in other projects. Is there a place I could put this file on computer so that Ruby can find it regardless of where I saved the file that is including it? I am using a Mac.
There's no standard place to put code like this. You could put all your code in a gem and install the gem, or create a directory to put this code in. Once you create the directory, alter the LOAD_PATH global variable to include this directory. You can do this either in each script that uses these, or with the RUBYOPT environment variable. For example, you could put ~/my_ruby_stuff in your path and put your files there. One warning if you do that, make sure the path you add is at the end of the gem path and try to avoid any name conflicts with existing Ruby libraries or gems.
Consider making a "gem" out of your code. The advantages are: separate project, better defined interface, separate source control, can share with other developers in your company, etc

Resources