minitest/minitest

Focus On A Single Test

metaskills opened this issue · 16 comments

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

This would be extremely handy.

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.

@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.

@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.

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

👍

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.

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

released

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

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?

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.

@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?

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

@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.

Will do thanks!

On Apr 18, 2014, at 12:27 AM, Ryan Davis notifications@github.com wrote:

@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.


Reply to this email directly or view it on GitHub.