Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ivantsepp committed Jan 23, 2016
0 parents commit 84db60f
Show file tree
Hide file tree
Showing 11 changed files with 339 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
@@ -0,0 +1,14 @@
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in minitest-skip.gemspec
gemspec
22 changes: 22 additions & 0 deletions LICENSE.txt
@@ -0,0 +1,22 @@
Copyright (c) 2016 Ivan Tse

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
82 changes: 82 additions & 0 deletions README.md
@@ -0,0 +1,82 @@
# Minitest Skip

This gem provides alternative ways of skipping a test. Normally a skipped test in Minitest looks like:

```ruby
def test_that_is_flaky
skip "Figure out why this flakes"
end
```

The gotcha for skipping tests with the `skip` keyword is that the `setup` and `teardown` blocks are still executed. This can be costly for acceptance tests since their setup usually involves starting a browser among other slow things.

This gem will allow you to use methods that begin with `skip_` to mark a test as skipped. It modifies Minitest such that it will recognize these skip methods and correctly report the results.

```
require "minitest/autorun"
class TestSkip < Minitest::Test
def setup
sleep 2 # costly setup block
end
def skip_test_that_is_temporarily_broken
# ...
end
end
# ruby test/test_skip.rb
# Run options: --seed 54134
# # Running:
# S
# Finished in 0.001663s, 601.3537 runs/s, 0.0000 assertions/s.
# 1 runs, 0 assertions, 0 failures, 0 errors, 1 skips
# You have skipped tests. Run with --verbose for details.
```

This gem also adds `xit` and `xdescribe` if you prefer the spec style syntax for Minitest.

```ruby
require "minitest/autorun"
require "minitest/spec"
require "minitest/skip_dsl"

describe "Test" do
it "normal" do assert true end
xit "skipped" do assert false end
xdescribe "All skipped" do
it "nested skip" do assert false end
end
end

```

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'minitest-skip'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install minitest-skip

And that's it! This is a Minitest plugin which means that it will be autoloaded. In order to use `xit` and `xdescribe`, you also need to `require "minitest/skip_dsl"`.

## Contributing

1. Fork it ( https://github.com/ivantsepp/minitest-skip/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
2 changes: 2 additions & 0 deletions Rakefile
@@ -0,0 +1,2 @@
require "bundler/gem_tasks"

54 changes: 54 additions & 0 deletions lib/minitest/skip_dsl.rb
@@ -0,0 +1,54 @@
require 'minitest/spec'

module Minitest
module SkipDSL
def xit desc = "anonymous", &block
block ||= proc { skip "(no tests defined)" }

@specs ||= 0
@specs += 1

name = "skip_%04d_%s" % [ @specs, desc ]

undef_klasses = self.children.reject { |c| c.public_method_defined? name }

define_method name, &block

undef_klasses.each do |undef_klass|
undef_klass.send :undef_method, name
end

name
end

def nuke_test_methods! # :nodoc:
self.public_instance_methods.grep(/^test_|skip_/).each do |name|
self.send :undef_method, name
end
end
end

Spec.extend(SkipDSL)
end

module Kernel
def xdescribe(desc, *additional_desc, &block)
stack = Minitest::Spec.describe_stack
name = [stack.last, desc, *additional_desc].compact.join("::")
sclas = stack.last || if Class === self && kind_of?(Minitest::Spec::DSL) then
self
else
Minitest::Spec.spec_type desc, *additional_desc
end

cls = sclas.create name, desc

stack.push cls
cls.singleton_class.send(:define_method, :it, cls.method(:xit))
cls.class_eval(&block)
stack.pop
cls
end

private :xdescribe
end
22 changes: 22 additions & 0 deletions lib/minitest/skip_plugin.rb
@@ -0,0 +1,22 @@
module Minitest
module SkipPlugin
def run(reporter, options = {})
super
methods_matching(/^skip_/).each do |method_name|
test = self.new(method_name)
test.time = 0

skip = Skip.new("Skipped from SkipPlugin")
source = test.method(method_name).source_location
skip.set_backtrace(["#{source[0]}:#{source[1]}"])
test.failures << skip

reporter.record(test)
end
end
end

def self.plugin_skip_init(options)
Runnable.singleton_class.prepend(SkipPlugin)
end
end
22 changes: 22 additions & 0 deletions minitest-skip.gemspec
@@ -0,0 +1,22 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)

Gem::Specification.new do |spec|
spec.name = "minitest-skip"
spec.version = "0.0.1"
spec.authors = ["Ivan Tse"]
spec.email = ["ivan.tse1@gmail.com"]
spec.summary = %q{Alternative ways to skip tests in Minitest}
spec.description = %q{Adds skip_* methods and xit/xdescribe spec style methods.}
spec.homepage = "https://github.com/ivantsepp/minitest-skip"
spec.license = "MIT"

spec.files = `git ls-files -z`.split("\x0")
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 1.7"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_dependency "minitest", "~> 5.0"
end
3 changes: 3 additions & 0 deletions test/test_helper.rb
@@ -0,0 +1,3 @@
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)

require 'minitest/autorun'
56 changes: 56 additions & 0 deletions test/test_skip_dsl.rb
@@ -0,0 +1,56 @@
require_relative 'test_helper'
require 'minitest/skip_dsl'

class TestSkipDSL < Minitest::Test

def setup
@output = StringIO.new("")

@reporter = Minitest::CompositeReporter.new
@reporter << @summary_reporter = Minitest::SummaryReporter.new(@output)
@reporter << @progress_reporter = Minitest::ProgressReporter.new(@output)
@reporter.start
end

def test_xit
test = describe "Test" do
it "normal" do assert true end
xit "skipped" do assert false end
end
test.run(@reporter)
@reporter.report

assert_includes @output.string.dup, "2 runs, 1 assertions, 0 failures, 0 errors, 1 skips"
end

def test_xdescribe
test = xdescribe "Test" do
it "normal" do assert true end
xit "skipped" do assert false end
end
test.run(@reporter)
@reporter.report

assert_includes @output.string.dup, "2 runs, 0 assertions, 0 failures, 0 errors, 2 skips"
end

def test_nested_describes
nested_1 = nested_2 = nil
test = describe "Test" do
it "normal" do assert true end
xit "skipped" do assert false end
nested_1 = xdescribe "All skipped" do
it "nested skip" do assert false end
nested_2 = describe "nested describe" do
it "nested 2 levels skip" do assert false end
end
end
end
test.run(@reporter)
nested_1.run(@reporter)
nested_2.run(@reporter)
@reporter.report

assert_includes @output.string.dup, "4 runs, 1 assertions, 0 failures, 0 errors, 3 skips"
end
end
58 changes: 58 additions & 0 deletions test/test_skip_methods.rb
@@ -0,0 +1,58 @@
require_relative 'test_helper'

class TestSkipMethods < Minitest::Test

def setup
@@ran = false
@test = Class.new(Minitest::Test) do
def skip_test_name
@@ran = true
end
end
@output = StringIO.new("")

@reporter = Minitest::CompositeReporter.new
@reporter << @summary_reporter = Minitest::SummaryReporter.new(@output)
@reporter << @progress_reporter = Minitest::ProgressReporter.new(@output)
@reporter.start
end

def test_run_skip
@test.run(@reporter)
@reporter.report
assert_includes @output.string.dup, "1 runs, 0 assertions, 0 failures, 0 errors, 1 skips"
end

def test_run_skip_verbose
Object.const_set("ExampleSkipTest", @test)
@progress_reporter.options = { verbose: true }
@summary_reporter.options = { verbose: true }

@test.run(@reporter)
@reporter.report

assert_includes @output.string.dup, "#skip_test_name = 0.00 s = S"
assert_includes @output.string.dup, <<-EOM.gsub(/^ {4}/, "")
1) Skipped:
ExampleSkipTest#skip_test_name [test/test_skip_methods.rb:8]:
Skipped from SkipPlugin
EOM

end

def test_skip_methods_are_recorded
@test.run(@reporter)
result = @summary_reporter.results.first
failure = result.failures.first
assert result.skipped?
assert_equal Minitest::Skip, failure.error.class
assert_equal "Skipped from SkipPlugin", failure.error.message
assert_equal "test/test_skip_methods.rb:8", failure.location
end

def test_skip_methods_are_not_executed
@test.run(@reporter)
refute @@ran, "skip methods should not be executed"
end

end

0 comments on commit 84db60f

Please sign in to comment.