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

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

Related

Cucumber.yml was found, but can't be parsed for Parallel_Tests

When running multiple features with the Ruby gem Parallel_Tests in cucumber using this command:
parallel_cucumber features/
with a cucumber.yml file under my project root>config folder, which looks like:
default: --format html --out report<%= ENV['TEST_ENV_NUMBER'] %>.html
I receive the following error message:
cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.
I have looked into this and some others have thought it was due to a rerun.txt file, but i have not created this file and a project file search returns nothing. I am currently at a loss of what is causing cucumber to fail reading in the yaml file. Any help would be great.
As described by another post, I went into lib/
cucumber/cli/profile_loader.rb and added a STDERR output like so:
begin
#cucumber_yml = YAML::load(#cucumber_erb)
rescue StandardError => e
STDERR.puts #cucumber_erb
raise(YmlLoadError,"cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.\n")
end
Here is the result:
#parallel_reports: --format html --out reports/cukes_.html
cucumber.yml was found, but could not be parsed. Please refer to cucumber's documentation on correct profile usage.
#
default: --format htm#l
-
oduetf aruelpto:r t-2-.fhotrmmla #hptamrla l-l-eolu_tr erpeoprotrst:4 .-h-tfmolr a#tp ahrtamlll e-l-_oruetp orretpso:r t-s-/fcourkmeast_ .hhttmmll - ouctu cruempboerrt.sy/mclu kweass_ .fhotumnld, buctu ccuomubledr .nyomtl bwea sp afrosuendd., Pblueta sceo urledf enro tt ob ec upcaurmsbeedr.' sP ldeoacsuem ernetfaetri otno ocnu ccuomrbreerc'ts pdroocfuimleen tu astaigoen.
n correct profile usage.
I stumbled upon this problem and only found solutions that suggested removing rerun.txt. That was not an option for me because I rely on that file to rerun failing scenarios.
For some reason Cucumber outputs failing scenarios separated by \n in rerun.txt which is not accepted by the default command found in cucumber.yml.
My solution was to change the first line of cucumber.yml to substitute \n with a space:
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt').gsub(/\n/, ' ') : ""
I had the same issue with the tests of Rails-Cucumber itself. In my case, just running this line fixed the problem:
rm .cucumber.rerun
Caution, sometimes the rerun file can have a different name.
There is a suggestion to use gem update –system
For me, the error
cucumber.yml was found, but could not be parsed with ERB
meant that I was running my tests from RubyMine, and had set my Features folder not to the root of my project, but to a subfolder in the project called features.
When I changed this to the root of my project, it worked out fine!

Minitest: Programmatically access name and time a test took to run

At the moment, when using minitest, if you do:
bundle exec rake TESTOPTS='--verbose'
you get an output like this:
Text you typed in the describe#test_0001_test description = 0.11 s = .
Text you typed in the describe#test_0003_another test description = 0.10 s = .
...etc.
I want to have acces to this programmatically, so that I can select the slowest tests, sort them by the time they took to run, and print them out to stdout in any format I want. Ideally I would define a new Rake task for this and then run something like:
bundle exec rake mytask
or something.
However, I can't seem to find anything online on how to access this information programmatically. I searched about custom reporters, but apparently you have to monkey-patch Minitest for that, and I don't want to do that. The other option is to install the minitest-reporters gem, but I don't want nor need all that functionality, what I want to do is very simple. I've also read through the code in the Minitest repo, but couldn't wrap my head around what to inherit from if I wanted to create my own class, and what to access in order to get the time spent running and the name of the test.
Is there any way to have access to this information programmatically? For example accessing the reports produced by minitest once all tests have finished running? How do you do it, those of you who write custom reporters without requiring a gem or monkey-patching minitest? I feel like this should be an easy thing to do.
You can write your own reporter (no need to monkey-patch, or use minitest-reporters), but there is an easier way. The verbose output is formatted in such a way that you can parse it using sort:
bundle exec rake TESTOPTS='--verbose' | sort -t = -k 2 -g

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.

Is it possible to run a single test in MiniTest?

I can run all tests in a single file with:
rake test TEST=path/to/test_file.rb
However, if I want to run just one test in that file, how would I do it?
I'm looking for similar functionality to:
rspec path/to/test_file.rb -l 25
The command should be:
% rake test TEST=test/test_foobar.rb TESTOPTS="--name=test_foobar1 -v"
Have you tried:
ruby path/to/test_file.rb --name test_method_name
No gem required:
ruby -Itest test/lib/test.rb --name /some_test/
Source: http://blog.arvidandersson.se/2012/03/28/minimalicous-testing-in-ruby-1-9
This is one of the things that bother me about the string name definition in tests.
When you have:
def test_my_test
end
you always know how your test is named so you can execute it like this:
ruby my_test -n test_my_test
But when you have something like:
it "my test" do
end
you are never sure how this test is really named internally so you can not use the -n option just directly.
To know how this test is named internally you only have an option: execute the whole file to try to figure out looking in the logs.
My workaround is (temporally) add something to the test name very unique like:
it "my test xxx" do
end
and then use the RegEx version of the '-n' parameter like:
ruby my_test.rb -n /xxx/
I'm looking for similar functionality to rspec path/to/file.rb -l 25
With Nick Quaranto's "m" gem, you can say:
m spec/my_spec.rb:25
If you are using MiniTest with Rails 5+ the best way to run all tests in a single file is:
bin/rails test path/to/test_file.rb
And for a single test (e.g. on line 25):
bin/rails test path/to/test_file.rb:25
See http://guides.rubyonrails.org/testing.html#the-rails-test-runner
You can use this to run a single file:
rake test TEST=test/path/to/file.rb
I also used
ruby -I"lib:test" test/path/to/file.rb
for better display.
There are 2 ways to do it:
Run tests 'manually' (see Andrew Grimm's answer).
Hack Rake::TestTask target to use a different tests loader.
Rake::TestTask (from rake 0.8.7) theoretically is able to pass additional options to MiniTest::Unit with a "TESTOPTS=blah-blah" command line option, for example:
% rake test TEST=test/test_foobar.rb TESTOPTS="--name test_foobar1 -v"
In practice, the option --name (a filter for test names) won't work, due to rake internals. To fix that you'll need to write a small monkey patch in your Rakefile:
# overriding the default rake tests loader
class Rake::TestTask
def rake_loader
'test/my-minitest-loader.rb'
end
end
# our usual test terget
Rake::TestTask.new {|i|
i.test_files = FileList['test/test_*.rb']
i.verbose = true
}
This patch requires you to create a file test/my-minitest-loader.rb:
ARGV.each { |f|
break if f =~ /^-/
load f
}
To print all possible options for Minitest, type
% ruby -r minitest/autorun -e '' -- --help
You can pass --name to run a test by its name or a number within its name:
-n, --name PATTERN Filter run on /regexp/ or string.
e.g.:
$ ruby spec/stories/foo_spec.rb --name 3
FAIL (0:00:00.022) test_0003_has foo
Expected: "foo"
Actual: nil
This flag is documented in Minitest’s README.
I am in Rails Version 4.2.11.3 and Ruby Version 2.4.7p357
Below one worked for me.
ruby -Itest <relative_minitest_file_path> --name /<test_name>/
If you are using Turn gem with minitest, just make sure to use Turn.config.pattern option since Turn Minitest runner doesn't respect --name option in ARGs.
I'm looking for similar functionality to:
rspec path/to/test_file.rb -l 25
There is a gem that does exactly that: minitest-line.
gem install minitest-line
ruby test/my_file -l 5
from https://github.com/judofyr/minitest-line#minitest-line
I use ruby /path/to/test -n /distinguishable word/
Edit:
-n is a shorthand for --name. distinguishable word can be any string you put in the test description, I usually use some random word that I know won't be present in other tests' descriptions.
Following will work
def test_abc
end
test "hello world"
end
This can run by
bundle exec ruby -I test path/to/test -n test_abc
bundle exec ruby -I test path/to/test -n test_hello_word
Install gem minitest-focus and use the keyword focus on test/spec like below to run only the specific test.
focus
def test
end
focus
it "test" do
end
This would not need any command line argument to be passed.

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/"

Resources