Skip to content

Loading…

Focus On A Single Test #213

Closed
metaskills opened this Issue · 16 comments

6 participants

@metaskills

Every now and then when running tests, especially using guard-minitest, I would like to focus on a single test so that I can quickly get feedback. I am looking for some advice, existing MiniTest extension, or clues at how I might go about this or if there is any interest in support this feature. Potential interface:

focus
it 'does something' do
  # ...
end
@futurechimp

This would be extremely handy.

@zenspider
Seattle Ruby Brigade member

ZenTest has focus.rb. I did notice that it needs a couple tweaks for 1.9 but that's easy enough. The way it works is to mention the names of the tests you want to focus on for now:

focus :test_whatever

It could be extended to take partial hits / regexps / etc.

@metaskills

@zenspider Are you proposing using ZenTest vs an extension? One tool we already have is @qrush's m test runner that can run single tests using line number. However, possibly using ZenTest orM` while TDD'ing during a refactor is not what I am looking for.

Ideally when the fit hits the shan and I am running guard-minitest, I have suite that is failing due to a common reason and I want to focus on a single test to run from my editor and watching a slim console output on that single test till I get it to a passing state again.

If this is something you are not interested in seeing in MiniTest, I would be happy to work on an extension with some pointers if you have the time.

@tenderlove
Seattle Ruby Brigade member

@metaskills this is kind of weird, but you can append to ARGV:

require 'minitest/autorun'

class MyTest < MiniTest::Unit::TestCase
  def self.focus name
    ARGV.concat ['-n', name.to_s]
  end

  focus :test_fail
  def test_fail; flunk; end
  def test_pass; assert true; end
end

MiniTest clears out the options hash, so this implementation won't work:

def self.focus name
  MiniTest::Unit.runner.options[:filter] = name.to_s
end

With the ARGV solution, you'll need to be careful if you have more than one focus line. I don't think minitest handles multiple -n options. If we patch minitest like this:

diff --git a/lib/minitest/unit.rb b/lib/minitest/unit.rb
index 71e30a9..179cd09 100644
--- a/lib/minitest/unit.rb
+++ b/lib/minitest/unit.rb
@@ -1035,7 +1035,7 @@ module MiniTest
     # Top level driver, controls all output and filtering.

     def _run args = []
-      self.options = process_args args
+      self.options.merge! process_args args

       puts "Run options: #{help}"

Then you can mutate the options hash, without scanning through ARGV to merge -n:

class MyTest < MiniTest::Unit::TestCase
  def self.focus name
    options = MiniTest::Unit.runner.options
    old     = options[:filter]
    filter  = if old
                Regexp.union(/\/(.*)\//.match(old)[1], name.to_s)
              else
                name.to_s
              end
    options[:filter] = "/#{filter.to_s}/"
  end

  focus :test_fail
  focus :test_tenderlove

  def test_fail; flunk;       end
  def test_tenderlove; flunk; end
  def test_pass; assert true; end
end

You still have to deal with the fact that _run_suite expects :filter to be a string, but at least this works.

HTH.

@metaskills

Thanks @tenderlove, I'll take a look at this soon. In context, here is a link on focus in guard-cucumber that I found today that I am booking here. guard/guard-cucumber#6

@zenspider zenspider was assigned
@zenspider
Seattle Ruby Brigade member

I should also point out that this is exactly how autotest is better than guard: brains.

That said, I'm working on this as an add-on gem. About done.

@zenspider
Seattle Ruby Brigade member

Done. Thanks. minitest 4.4.0 has the needed change to options. minitest-focus will come out shortly.

@zenspider zenspider closed this
@zenspider
Seattle Ruby Brigade member

released

@metaskills

Thanks Ryan! FWIW, I just re-released minitest-spec-rails!!!
https://github.com/metaskills/minitest-spec-rails#readme

@subimage

This is nice - but how do we focus on a single file, or files? I have a huge test suite I'd like to use with guard...but in autotest now I have it configured where I can pass filenames via command line and it just runs those.

Anything similar with guard / minitest?

@metaskills

Well, it all just being ruby, why would this not work?

$ ruby -I "lib:test" test/foo.rb
$ ruby -I "lib:test" test/foo.rb test/bar.rb

Using guard, you can automate this by telling either file foo.rb or bar.rb run both.

@zenspider
Seattle Ruby Brigade member

@metaskills the latter won't work because that's not how ruby works (nor test/foo.rb, I presume).

@subimage I dunno about guard. I use autotest and use it the same way you do. Why/how does that not suffice?

@subimage

@zenspider Unrelated to this bug - but I was just investigating guard to see if it offered advantages over autotest. Thanks guys.

@zenspider
Seattle Ruby Brigade member

@subimage take a look at seattlerb/minitest-autotest (unreleased gem, needs eyeballs). It communicates with autotest directly and allows you to mix and match other reporters into minitest without affecting autotest.

@subimage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.