class MiniAutobot::TestCase
An MiniAutobot-specific test case container, which extends the default ones, adds convenience helper methods, and manages page objects automatically.
Attributes
@!attribute [rw] options
@return [Hash] test case options
Public Class Methods
@param suite [String] type of test suite @param tags [Array] an array of tags a test has @return [Boolean]
# File lib/mini_autobot/test_case.rb, line 217 def exclude_by_tag?(suite, tags) tag_to_exclude = @@test_suite_data[suite]['tag_to_exclude'] if tags.include? tag_to_exclude true else false end end
Filter methods in a runnable based on our tag selection
# File lib/mini_autobot/test_case.rb, line 118 def filter_methods(methods, selected) # If no tags are selected, run all tests if selected.nil? || selected.empty? return methods end selected_methods = methods.select do |method| # If the method's tags match any of the tag sets, allow it to run selected.any? do |tag_set| # Retrieve the tags for that method method_options = self.options[method.to_sym] rescue nil tags = method_options[:tags] rescue nil # If the method's tags match ALL of the tags in the tag set, allow # it to run; in the event of a problem, allow the test to run tag_set.all? do |tag| if tag =~ %r/^!/ !tags.include?(tag[%r/^!(.*)/,1].to_sym) || nil else tags.include?(tag.to_sym) || nil end rescue true end end end selected_methods end
Explicitly remove all tests from the current class. This will also remove inherited test cases.
@return [TestCase] self
# File lib/mini_autobot/test_case.rb, line 42 def remove_tests klass = class <<self; self; end public_instance_methods.grep(/^test_/).each do |method| klass.send(:undef_method, method.to_sym) end self end
Call this at the top of your test case class in order to run all tests in alphabetical order
@return [TestCase] self @example
class SomeName < TestCase run_in_order! test :feature_search_01 { ... } test :feature_search_02 { ... } end
# File lib/mini_autobot/test_case.rb, line 61 def run_in_order! # `self` is the class, so we want to reopen the metaclass instead, and # redefine the methods there class <<self undef_method :test_order if method_defined? :test_order define_method :test_order do :alpha end end # Be nice and return the class back self end
Filter out anything not matching our tag selection, if any.
If it's parallel run, only add filtered methods from each runnable to a list of to run methods, instead of running them one by one right away, and finally when all runnable methods are traversed, call parallel to run that list of methods.
@return [Enumerable<Symbol>] the methods marked runnable
# File lib/mini_autobot/test_case.rb, line 83 def runnable_methods methods = super selected = MiniAutobot.settings.tags filtered_methods = filter_methods(methods, selected) if MiniAutobot.settings.parallel unless filtered_methods.empty? if selected.nil? || selected.empty? @@selected_methods = @@regression_suite else methods_to_add = filtered_methods.map { |method| method.to_sym if @@regression_suite.include?(method.to_sym) } @@selected_methods += methods_to_add end end @@runnables_count += 1 mini_autobot_runnables = Minitest::Runnable.runnables - [Minitest::Test, Minitest::Unit::TestCase] if @@runnables_count == mini_autobot_runnables.size parallel = Parallel.new(MiniAutobot.settings.parallel, @@selected_methods) parallel.clean_result! parallel.run_in_parallel! parallel.remove_redundant_tap if MiniAutobot.settings.rerun_failure parallel.aggregate_tap_results exit end return [] # no test will run else filtered_methods end end
Install a setup method that runs before every test.
@return [void]
# File lib/mini_autobot/test_case.rb, line 149 def setup(&block) define_method(:setup) do super() instance_eval(&block) end end
Install a teardown method that runs after every test.
@return [void]
MiniAutobot::Utils::PageObjectHelper#teardown
# File lib/mini_autobot/test_case.rb, line 159 def teardown(&block) define_method(:teardown) do super() instance_eval(&block) end end
Defines a test case.
It can take the following options:
-
`tags`: An array of any number of tags associated with the test case.
When not specified, the test will always be run even when only certain tags are run. When specified but an empty array, the test will only be run if all tags are set to run. When the array contains one or more tags, then the test will only be run if at least one tag matches.
-
`serial`: An arbitrary string that is used to refer to all a specific
test case. For example, this can be used to store the serial number for the test case.
@param name [String, Symbol] an arbitrary but unique name for the test,
preferably unique across all test classes, but not required
@param opts [Hash] @param block [Proc] the testing logic @return [void]
# File lib/mini_autobot/test_case.rb, line 185 def test(name, **opts, &block) # Ensure that the test isn't already defined to prevent tests from being # swallowed silently method_name = test_name(name) check_not_defined!(method_name) # Add an additional tag, which is unique for each test class, to all tests # To allow user to run tests with option '-t class_name_of_the_test' without # duplicate run for all tests in NameOfTheTest. The namespace of the class # is ignored here. opts[:tags] << ('class_'+ self.name.demodulize.underscore).to_sym # Flunk unless a logic block was provided if block_given? self.options ||= {} self.options[method_name.to_sym] = opts.deep_symbolize_keys define_method(method_name, &block) else flunk "No implementation was provided for test '#{method_name}' in #{self}" end # add all tests to @@regression_suite # excluding the ones with tags in tags_to_exclude defined in config unless exclude_by_tag?('regression', opts[:tags]) @@regression_suite << method_name @@serials << opts[:serial] end end
Protected Class Methods
Check that method_name
hasn't already been defined as an instance method in the current class, or in any superclasses.
@param method_name [Symbol] the method name to check @return [void]
# File lib/mini_autobot/test_case.rb, line 232 def check_not_defined!(method_name) already_defined = instance_method(method_name) rescue false raise TestAlreadyDefined, "Test #{method_name} already exists in #{self}" if already_defined end
Private Class Methods
Sanitize the name
by removing consecutive non-word characters into a single whitespace.
@param name [#to_s] the name to sanitize @return [String] the sanitized value @example
sanitize_name('The Best Thing [#5]') # => 'The Best Thing 5' sanitize_name(:ReallySuper___awesome) # => 'ReallySuper Awesome'
# File lib/mini_autobot/test_case.rb, line 258 def sanitize_name(name) name.to_s.gsub(/\W+/, ' ').strip end
Transform the test name
into a snake-case name, prefixed with “test_”.
@param name [#to_s] the test name @return [Symbol] the transformed test name symbol @example
test_name(:search_zip) # => :test_search_zip
# File lib/mini_autobot/test_case.rb, line 244 def test_name(name) undercased_name = sanitize_name(name).gsub(/\s+/, '_') "test_#{undercased_name}".to_sym end