Module: Tap::Test::SubsetTest

Includes:
EnvVars
Defined in:
lib/tap/test/subset_test.rb

Overview

SubsetTest provides methods to conditionally run tests, or to skip a test suite entirely.

require 'tap/test'

class Test::Unit::TestCase
  # only true if running on windows
  condition(:windows) { match_platform?('mswin') }

  # only true if running on anything but windows
  condition(:non_windows) { match_platform?('non_mswin') }
end

class WindowsOnlyTest < Test::Unit::TestCase
  skip_test unless satisfied?(:windows)
end

Here the WindowsOnlyTest will only run on a Windows platform. Conditions like these may be targeted at specific tests when only some tests need to be skipped.

class RunOnlyAFewTest < Test::Unit::TestCase
  include SubsetTest

  def test_runs_all_the_time
    assert true
  end

  def test_runs_only_if_non_windows_condition_is_true
    condition_test(:non_windows) { assert true }
    end
  end

  def test_runs_only_when_ENV_variable_EXTENDED_is_true
    extended_test { assert true }
  end

  def test_runs_only_when_ENV_variable_BENCHMARK_is_true
    benchmark_test do |x|
      x.report("init speed") { 10000.times { Object.new } }
    end
  end

  def test_runs_only_when_ENV_variable_CUSTOM_is_true
    subset_test('CUSTOM') { assert true }
  end
end

In the example, the ENV variables EXTENDED, BENCHMARK, and CUSTOM act as flags to run specific tests. If you’re running your test using Rake, ENV variables can be set from the command line like so:

% rake test EXTENDED=true
% rake test BENCHMARK=true

Since tap and rap can run rake tasks as well, these are equivalent:

% tap run test EXTENDED=true
% rap test BENCHMARK=true

In so far as SubsetTest is concerned, the environment variables are case-insensitive. As in the example, additional ENV-based tests can be defined using the subset_test method. To run all tests that get switched using an ENV variable, set ALL=true.

# also runs benchmark tests
% rap test BenchMark=true

# runs all tests
% rap test all=true

See Test::Unit::TestCase and SubsetTestClass for more information.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from EnvVars

#env, #env_true?

Class Method Details

.included(base) ⇒ Object



83
84
85
86
# File 'lib/tap/test/subset_test.rb', line 83

def self.included(base)
  super
  base.extend SubsetTestClass
end

Instance Method Details

#benchmark_test(length = 10, &block) ⇒ Object

Declares a subset_test for the ENV variable ‘BENCHMARK’. If run, benchmark_test sets up benchmarking using the Benchmark.bm method using the input length and block. Prints ‘b’ if the test is not run.

include Benchmark
def test_speed
  benchmark_test(10) {|x| ... }
end


220
221
222
223
224
225
226
# File 'lib/tap/test/subset_test.rb', line 220

def benchmark_test(length=10, &block) 
  subset_test("BENCHMARK") do
    puts
    puts method_name
    Benchmark.bm(length, &block)
  end
end

#condition_test(*condition_names) ⇒ Object

Conditonal test. Only runs if the specified conditions are satisfied. If no conditons are explicitly set, condition_test only runs if ALL conditions for the test are satisfied.

condition(:is_true) { true }
condition(:is_false) { false }

def test_only_if_true_is_satisfied
  condition_test(:is_true) { # runs }
end

def test_only_if_all_conditions_are_satisfied
  condition_test {  # does not run }
end

See SubsetTestClass#condition for more details.



141
142
143
144
145
146
147
# File 'lib/tap/test/subset_test.rb', line 141

def condition_test(*condition_names)
  if self.class.unsatisfied_conditions(*condition_names).empty?
    yield
  else
    print ' '
  end
end

#extended_test(&block) ⇒ Object

Declares a subset_test for the ENV variable ‘EXTENDED’. Prints ‘x’ if the test is not run.

def test_some_long_process
  extended_test { ... }
end


208
209
210
# File 'lib/tap/test/subset_test.rb', line 208

def extended_test(&block) 
  subset_test("EXTENDED", "x", &block)
end

#match_regexp?(type, str, default = true) ⇒ Boolean

Returns true if the input string matches the regexp specified in env_var(type). Returns the default value if ‘ALL’ is specified in ENV or type is not specified in ENV.

Returns:

  • (Boolean)


102
103
104
105
106
107
# File 'lib/tap/test/subset_test.rb', line 102

def match_regexp?(type, str, default=true)
  return true if env_true?("ALL")
  return default unless env(type)
    
  str =~ Regexp.new(env(type)) ? true : false
end

#platform_test(*platforms) ⇒ Object

Platform-specific test. Useful for specifying test that should only be run on a subset of platforms. Prints ‘ ’ if the test is not run.

def test_only_on_windows
  platform_test('mswin') { ... }
end

See SubsetTestClass#match_platform? for matching details.



117
118
119
120
121
122
123
# File 'lib/tap/test/subset_test.rb', line 117

def platform_test(*platforms)
  if self.class.match_platform?(*platforms)
    yield
  else
    print ' '
  end
end

#prompt_test(*keys, &block) ⇒ Object

Declares a subset_test for the ENV variable ‘PROMPT’. When run, prompts the user for each input specified in array. Inputs will then be passed as a hash to the block. Prints ‘p’ unless run.

def test_requiring_inputs
  prompt_test(:a, :b, :c) {|a, b, c| ... }
end

If run, the command line prompt will be like the following:

test_requiring_inputs: Enter values or 'skip'
a: avalue
b: bvalue      
c: cvalue

The block recieves [‘avalue’, ‘bvalue’, ‘cvalue’].



244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/tap/test/subset_test.rb', line 244

def prompt_test(*keys, &block)
  subset_test("PROMPT", "p") do
    puts "\n#{method_name} -- Enter values or 'skip'."
  
    values = keys.collect do |key|
      print "#{key}: "
      value = gets.strip
      flunk "skipped test" if value =~ /skip/i
      value
    end
  
    yield(*values)
  end
end

#run_subset?(type) ⇒ Boolean

Returns true if the subset type (ex ‘BENCHMARK’) or ‘ALL’ is specified in ENV.

Returns:

  • (Boolean)


95
96
97
# File 'lib/tap/test/subset_test.rb', line 95

def run_subset?(type)
  self.class.run_subset?(type)
end

#satisfied?(*condition_names) ⇒ Boolean

Returns true if the specified conditions are satisfied.

Returns:

  • (Boolean)


89
90
91
# File 'lib/tap/test/subset_test.rb', line 89

def satisfied?(*condition_names)
  self.class.satisfied?(*condition_names)
end

#subset_test(type, skip = type[0..0].downcase) ⇒ Object

Defines a subset test. The provided block will only run if:

  • the subset type is specified in ENV

  • the subset ‘ALL’ is specified in ENV

  • the test method name matches the regexp provided in the <TYPE>_TEST ENV variable

Otherwise the block will be skipped and skip will be printed in the test output. By default skip is the first letter of type.

For example, with these methods:

def test_one
  subset_test('CUSTOM') { assert true }
end

def test_two
  subset_test('CUSTOM') { assert true }
end

Condition                    Tests that get run
ENV['ALL']=true              test_one, test_two
ENV['CUSTOM']=true           test_one, test_two
ENV['CUSTOM_TEST']=test_     test_one, test_two
ENV['CUSTOM_TEST']=test_one  test_one
ENV['CUSTOM']=nil            no tests get run

If you’re running your tests with rake (or rap), ENV variables may be set from the command line.

# all tests
% rap test all=true

# custom subset tests
% rap test custom=true

# just test_one (it is the only test
# matching the '.est_on.' pattern)
% rap test custom_test=.est_on.


188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/tap/test/subset_test.rb', line 188

def subset_test(type, skip=type[0..0].downcase)
  type = type.upcase
  type_test = "#{type}_TEST"
  if run_subset?(type) || env(type_test)
    if match_regexp?(type_test, method_name.to_s)
      yield
    else
      print skip
    end
  else
    print skip
  end
end