207

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
Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
Josiah Kiehl
  • 3,593
  • 3
  • 26
  • 28
  • 4
    8 years later and for rails 5+ users `rails test path/to/test_file.rb:25` see @Derek_Hill ans - taken from https://guides.rubyonrails.org/testing.html#the-rails-test-runner – notapatch Sep 08 '19 at 11:03

16 Answers16

239

The command should be:

% rake test TEST=test/test_foobar.rb TESTOPTS="--name=test_foobar1 -v"
Simon
  • 31,675
  • 9
  • 80
  • 92
jduan
  • 2,784
  • 2
  • 15
  • 9
  • 7
    +1 - this is what you wanna do. If you want to test all the test in a specific file, just leave `TESTOPTS=...` away – awenkhh Sep 04 '15 at 14:04
  • Very usefull answer. I make MinitestReporter to show rerun commands of failed tests at the end of test report. See: https://gist.github.com/foton/141b9f73caccf13ccfcc – Foton Feb 15 '16 at 13:10
  • 2
    What does the `-v` do? – Jon Schneider Aug 15 '18 at 21:22
172

Have you tried:

ruby path/to/test_file.rb --name test_method_name
Alan W. Smith
  • 24,647
  • 4
  • 70
  • 96
Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
  • 10
    What about for tests using Minispec, defined like `specify {}`? Those just show up as `test_0001_anonymous`... and there could be multiple `test_0001_anonymous`s if the same syntax is used in multiple describe blocks... any suggestions for running single tests in this kind of environment? – neezer Oct 21 '11 at 17:05
  • 1
    "tc" stands for "test case". – Andrew Grimm May 06 '14 at 13:08
  • 5
    It says `cannot load such file -- test_helper`. – x-yuri Mar 13 '15 at 21:46
  • 13
    use `ruby -Itest path/to/tc_file.rb --name test_method_name` like http://stackoverflow.com/a/15714985/327786 – TlmaK0 Jul 10 '15 at 13:11
  • 2
    `bundle exec ruby -I lib path/to --name test_fit` – puchu Sep 25 '17 at 14:41
61

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

randomor
  • 5,329
  • 4
  • 46
  • 68
52

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/
fguillen
  • 36,125
  • 23
  • 149
  • 210
  • 9
    regex version of -n parameter was the clutch piece of info, thanks! – Woahdae Jan 19 '13 at 18:56
  • Note that you can check this by calling `__method__` within the context of the currently executing method (your test, in this instance). The present implementation results in something like `"does not break my stuff".gsub(" ", "_").prepend("test_")`. Then run, for example, `ruby -Itest test/integration/stuff_flow_test.rb --name test_does_not_break_my_stuff`. – TK-421 Dec 14 '16 at 05:02
46

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
Jim U
  • 3,318
  • 1
  • 14
  • 24
Elliot Winkler
  • 2,336
  • 20
  • 17
  • 4
    While the answer works and was exactly what was asked :-) The Mini-test way of running a single test is by name matching (see Mr Grimm's answer). If you've tried this and rejected it then it's time to try the none-standard alternatives - such as Nick's Gem. – notapatch Dec 04 '13 at 13:18
  • 3
    True, I agree. I actually wish m let you also pass in -n as an option... or that MiniTest just supported using line numbers as well as method names. – Elliot Winkler Dec 05 '13 at 07:41
  • 15
    Heads up! `m` [currently doesn't work this Minitest 5.0](https://github.com/qrush/m/issues/35). – davetapley May 15 '14 at 06:06
  • while this gem make things similar to rspec way of run a single test, Minitest has a built-in way to run a single test that was exactly the question. The dependency is not necessary. It is good to know that could be easier with an accessory gem (like may have many around) but I think that for this question, the pure minitest answers like from jduan or randomor would fit better – cefigueiredo Sep 21 '17 at 17:31
  • Passing filename and line number to the test runner is trivially easy to automate from your editor, specifying a test name is not. – Adam Lassek May 15 '23 at 19:43
41

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

Derek Hill
  • 5,965
  • 5
  • 55
  • 74
  • 3
    FYI this is not working for me in rails 5.0.7. The command ends up running all the test in the file no matter what line number I enter. – momo Oct 06 '20 at 05:44
  • I had the same issue. If you redefine the `:test` task it seems to cause issues with the rails runner. – iloveitaly Aug 11 '21 at 20:52
25

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.

tuhaj
  • 527
  • 7
  • 9
13

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.

Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
Rimian
  • 36,864
  • 16
  • 117
  • 117
12

There are 2 ways to do it:

  1. Run tests 'manually' (see Andrew Grimm's answer).
  2. 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
Alexander Gromnitsky
  • 2,949
  • 2
  • 33
  • 38
  • 3
    Note that the initial example does work correctly with a more recent `rake` (0.9.2) and no monkey patch is required. – Confusion Dec 24 '11 at 15:58
  • 1
    When I tried with rake version 10.5.0 `TESTOPTS="--name test_foobar"` does not work, but `TESTOPTS="--name=test_foobar"` works. – kangkyu Feb 18 '16 at 21:59
2

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.

sloneorzeszki
  • 1,274
  • 3
  • 12
  • 22
  • Can you explain that further? What does that `-n` parameter mean? – Nico Haase Mar 18 '19 at 08:33
  • It's a shorthand for `--name`. Just a convenience thing. Especially useful with the /regex/, I usually just put some random word into a test name (that I know won't be present in other tests' descriptions). – sloneorzeszki Mar 18 '19 at 08:50
  • 1
    Please add some explanation about that to the answer itself, not to the comment section – Nico Haase Mar 18 '19 at 12:52
2

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

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.

Laknath
  • 470
  • 5
  • 5
  • This was the hint I needed to realize that Turn is what was swallowing the `name` option. Thanks! Being that Turn is no longer being maintained, I plan to migrate to minitest-reporters – pdobb Jul 27 '15 at 18:05
1

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

Community
  • 1
  • 1
wteuber
  • 1,208
  • 9
  • 15
  • Hi @ChrisHough, could you describe what exactly isn't working (e.g. an error message)? The minitest-line gem's purpose is solely to run a single test in MiniTest. If it's not working you might have found a bug in minitest-line. – wteuber Apr 03 '19 at 20:36
1

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
0

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.

par
  • 817
  • 8
  • 21
0

Rails 7.1 introduce new syntax for specific lines for tests

Now you can run not only specific tests by single line

bin/rails test test/models/user_test.rb:10 # by line 10

but also by lines range

bin/rails test test/models/user_test.rb:10-20 # by lines 10..20

or even by few ranges

bin/rails test test/models/user_test.rb:10-20:25-30 # by lines 10..20 and 25..30
mechnicov
  • 12,025
  • 4
  • 33
  • 56