Ruby Rspec. Get list of all Test - ruby

I have some test on Rspec, which looks like this:
describe "description" do
before :each do
do_before()
end
it "something_1" do
...
end
it "something_2" do
...
end
end
I know that I can get name of current test ("something_1") by using
example.description
Is there any way to get array of all descriptions in before :each area?

rspec -f d --color --dry-run filename
Works for me in rspec 3.5.2, lists all tests without running them

There used to be a way to do this using the tag --dry-run, but that has been removed and no longer works.
You can use the -fd which is for format = documentation. This will show you a long list of all the specs that you've done and what they look like. It does, however, still run the test and show you any errors you have in the process. That said it's still a great way to list of all of your tests.

Related

Rspec documentation output format

According to this piece of documentation, it is possible to achieve the following output format by selecting the format documentation:
something
does something that passes
does something that fails (FAILED - 1)
does something that is pending (PENDING: Not Yet Implemented)
Is it possible to slightly edit this so it outputs as:
something
does something (SUCCESS)
does something (FAIL)
does something (PENDING)
Basically I would like the result of the test displayed no matter what - instead of just logging explicitly the failures and the pending ones.
I was able to do this by subclassing RSpec::Core::Formatters::DocumentationFormatter. Create the following file as spec/formatters/custom_formatter.rb:
class CustomFormatter < RSpec::Core::Formatters::DocumentationFormatter
RSpec::Core::Formatters.register self
private
def passed_output(example)
format_output(example, 'SUCCESS', :success)
end
def pending_output(example, _message)
format_output(example, 'PENDING', :pending)
end
def failure_output(example)
format_output(example, 'FAILED', :failure)
end
def format_output(example, status_text, code_or_symbol)
RSpec::Core::Formatters::ConsoleCodes.wrap(
"#{current_indentation}#{example.description.strip} (#{status_text})",
code_or_symbol
)
end
end
Then run the specs using this:
rspec --require formatters/custom_formatter --format CustomFormatter
Instead of --require formatters/custom_formatter, you can also require the formatter on spec/spec_helper.rb, e.g.
require_relative 'formatters/custom_formatter'
Then you only need to run this:
rspec --format CustomFormatter
If you want CustomFormatter to be the default formatter, you can add the command line options to .rspec configuration file at your project root. Here's how it should look like:
--require spec_helper
--require /path/to/custom_formatter.rb
--format CustomFormatter
With that, you no longer need to specify any command line arguments to use CustomFormatter.
Documentations and references:
https://relishapp.com/rspec/rspec-core/v/3-6/docs/formatters/custom-formatters
http://www.rubydoc.info/gems/rspec-core/RSpec/Core/Formatters
https://github.com/rspec/rspec-core/blob/v3.7.0/lib/rspec/core/formatters/documentation_formatter.rb
You can not change the existing RSpec formatters, but you can create your own
When RSpec's built-in output formatters don't, however, give you everything
you need, you can write your own custom formatter and tell RSpec to use that
one instead. The simplest way is to subclass RSpec's BaseTextFormatter, and
then override just the methods that you want to modify.

Run/exclude specs where tag is present

I know I can run specs given some_tag is value with --tag some_tag:value or where tag is added, but doesn't have a value (defaults to true) with --tag some_tag. I also know I can exclude specs with the above syntax and ~.
How do I run all specs with a tag present/missing?
For example:
If I have specs marked with slow: :external_service, slow: :manual_confirmation or slow: :some_other_reason (these are just made up names), I want to do something like:
rspec --tag ~slow
and run all specs that are not slow.
The above doesn't work since it filters out specs where slow == true instead of !slow.nil?
Is there a way to achieve exactly this with or without extra configuration?
What is the idiomatic way to do a such thing? I would guess add two tags, one boolean and one containing the value (for example :slow, pending_on: :external_service)
This should help. Basically call
rspec --tag ~slow:external_service
and it won't run tests tagged with slow: :external_service
Exclude with multiple tags can be of some help here.
rspec --tag ~slow:external_service --tag ~slow:manual_confirmation
Refer this article for other options.

Recursively glob for RSpec test files at runtime

I have a suite of RSpec tests I want to group under the following hierarchy:
tests/
featA/
t1.rb
t2.rb
featB/
t3.rb
but when I run
$ rspec tests
I get the following:
rspec tests
No examples were matched. Perhaps {:unless=>#<Proc:0x00007f318919cc08#/usr/lib/ruby/gems/1.8/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:51>, :if=>#<Proc:0x00007f318919cdc0#/usr/lib/ruby/gems/1.8/gems/rspec-core-2.5.1/lib/rspec/core/configuration.rb:50>} is excluding everything?
Finished in 0.00003 seconds
0 examples, 0 failures
I feel like I'm going mad, but there doesn't seem to be a way to get RSpec to recursively glob for test files? Does this functionality exist?
EDIT:
I have a workaround by doing this:
$ rspec `find tests -name "*.rb"`
but I suspect I shouldn't have to. Am I right?
You've exposed an oversight on my part! In rspec-1, you could say this:
spec test --pattern "**/*.rb"
But the --pattern option is missing in rspec-2. I've just added it (in development) and it will be included in the rspec-2.6.0 release.
I usually manage running RSpec on my specs via rake. The relevant portion of my Rakefile looks something like this:
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new(:spec) do |t|
t.rspec_opts = ['--color', '-f progress', '-r ./spec/spec_helper.rb']
t.pattern = 'spec/**/*_spec.rb'
t.fail_on_error = false
end
Now rake spec runs RSpec with the appropriate options; you'll need to change t.pattern to match the specs you want to run.
Be sure to check out the RSpec2 site for more information.

How do you run a specific test with test/spec (not a specific file, but a spec within a given file)?

With Test::Unit, I can run:
ruby path/to/test.rb --name=test_name_that_i_want_to_run
Thus far, I have not been able to figure out how to do this with test/spec specifications. I am wondering if the way that specifications are automatically named does not allow me to do something like this.
Take the following spec for example:
require 'rubygems'
require 'spec'
describe 'tests' do
it 'should be true' do
1.should == 1
end
it 'should be false' do
1.should_not == 2
end
end
You can execute a single spec by using the -e flag and providing the portion specified by the it block. e.g. ruby my_spec.rb -e 'should be false'
After contacting the gem maintainer, Christian Neukirchen, I found out how to do this, so I am documenting it here for future reference.
specrb path/to/test.rb --name ".*should behave this way.*"
I needed to use the specrb test runner, an extended version Test::Unit's test runner, rather than just the ruby command.
You can also do this with the ruby command:
ruby path/to/test.rb -n "/should behave this way/"

How do you run a single test/spec file in RSpec?

I want to be able to run a single spec file's tests — for the one file I'm editing, for example. rake spec executes all the specs. My project is not a Rails project, so rake spec:doc doesn't work.
Don't know if this matters, but here is my directory structure.
./Rakefile
./lib
./lib/cushion.rb
./lib/cushion
./lib/cushion/doc.rb
./lib/cushion/db.rb
./spec
./spec/spec.opts
./spec/spec_helper.rb
./spec/db_spec.rb
Or you can skip rake and use the 'rspec' command:
bundle exec rspec path/to/spec/file.rb
In your case I think as long as your ./spec/db_spec.rb file includes the appropriate helpers, it should work fine.
If you're using an older version of rspec it is:
bundle exec spec path/to/spec/file.rb
The raw invocation:
rake spec SPEC=spec/controllers/sessions_controller_spec.rb \
SPEC_OPTS="-e \"should log in with cookie\""
Now figure out how to embed this into your editor.
This question is an old one, but it shows up at the top of Google when searching for how to run a single test. I don't know if it's a recent addition, but to run a single test out of a spec you can do the following:
rspec path/to/spec:<line number>
where -line number- is a line number that contains part of your test. For example, if you had a spec like:
1:
2: it "should be awesome" do
3: foo = 3
4: foo.should eq(3)
5: end
6:
Let's say it's saved in spec/models/foo_spec.rb. Then you would run:
rspec spec/models/foo_spec.rb:2
and it would just run that one spec. In fact, that number could be anything from 2 to 5.
You can also use the actual text of the *e*xample test case with -e !
So for:
it "shows the plane arrival time"
you can use
rspec path/to/spec/file.rb -e 'shows the plane arrival time'
./scripts/spec path/to/spec/file.rb -e 'shows the plane arrival time'
no need for rake here.
from help (spec -h):
-l, --line LINE_NUMBER Execute example group or example at given line.
(does not work for dynamically generated examples)
Example: spec spec/runner_spec.rb -l 162
To run all of your rspec files: rspec
note: you must be in the root of your project
To run one rspec file: rspec 'path_to/spec.rb'
note: replace 'path_to/spec.rb' with your path. Quotation marks optional.
To run one rspec test from one file: rspec 'path_to/spec.rb:7'
note: :7 is the line number where the test starts
If you installed rspec as a plugin rather than as a gem, then you won't have the spec executable.
At any rate, All you need to do is run the file using ruby. The rspec code is clever enough to run the tests for you.
eg:
ruby myclass_spec.rb
http://github.com/grosser/single_test lets you do stuff like..
rake spec:user #run spec/model/user_spec.rb (searches for user*_spec.rb)
rake test:users_c #run test/functional/users_controller_test.rb
rake spec:user:token #run the first spec in user_spec.rb that matches /token/
rake test:user:token #run all tests in user_test.rb that match /token/
rake test:last
rake spec:last
Ruby 1.9.2 and Rails 3 have an easy way to run one spec file:
ruby -I spec spec/models/user_spec.rb
Explanation:
ruby command tends to be faster than the rake command
-I spec means "include the 'spec' directory when looking for files"
spec/models/user_spec.rb is the file we want to run.
Although many great answers were written to this question, none of them uses the Rspec tags approach.
I use tags to run one or more specs in different files -- only those related to my current development task.
For example, I add the tag "dev" with the value "current":
it "creates an user", dev: :current do
user = create(:user)
expect(user.persisted?).to be_truthy
end
then I run
bundle exec rspec . --tag dev:current
Different tags/values can be set in individual specs or groups.
I was having trouble getting any of these examples to work, maybe because the post is old and the commands have changed?
After some poking around I found this works:
rspec spec/models/user_spec.rb
That will run just the single file and provides useful output in the terminal.
specky.vim
Alternatively, have a look at autotest.
Running autotest in a command window will mean that the spec file will be executed whenever you save it. Also, it will be run whenever the file you are speccing is run.
For instance, if you have a model spec file called person_spec.rb, and a model file that it is speccing called person.rb, then whenever you save either of these files from your editor, the spec file will be executed.
Lets say, you're running test for creating todo. You can always run that specific todo spec code using the file crete_spec.rb file as below.
rspec/spec/features/controller/spec_file_name.rb
Example:
Creating rspec spec/features/todos/create_spec.rb
Editing rspec spec/features/todos/edit_spec.rb
Deleting rspec spec/features/todos/destroy_spec.rb
If you want to run all the specs in one single short.
rspec
If you want to run all the specs in a specific controller user this.
rspec/spec/feaures/controller_name
Example: rspec/spec/features/todos
Hope it gives you more understanding!
And you can run specific line into your test file
rspec spec/models/model_spec.rb:47

Resources