class Beaker::TestCase
This class represents a single test case. A test case is necessarily contained all in one file though may have multiple dependent examples. They are executed in order (save for any teardown procs registered through {Beaker::DSL::Structure#teardown}) and once completed the status of the TestCase
is saved. Instance readers/accessors provide the test case access to various details of the environment and suite the test case is running within.
See {Beaker::DSL} for more information about writing tests using the DSL
.
Constants
- TEST_EXCEPTION_CLASS
The Exception raised by Ruby’s STDLIB’s test framework (Ruby 1.9)
Attributes
The exception that may have stopped this test’s execution.
Necessary for {Beaker::DSL::Outcomes}. Assumed to be an Array.
I don’t know why this is here
Necessary for implementing {Beaker::DSL::Helpers#confine}. Assumed to be an array of valid {Beaker::Host} objects for this test case.
The result for the last command run
Necessary for many methods in {Beaker::DSL}. Assumed to be an instance of {Beaker::Logger}.
Necessary for many methods in {Beaker::DSL::Helpers}. Assumed to be a hash.
Parsed command line options.
The path to the file which contains this test case.
The amount of time taken to execute the test
The full log for this test
An Array of Procs to be called after test execution has stopped (whether by exception or not).
A Symbol denoting the status of this test (:fail, :pending, :skipped, :pass).
The user that is running this tests home directory, needed by ‘net/ssh’.
A Hash of ‘product name’ => ‘version installed’, only set when products are installed via git or PE install steps. See the ‘git’ or ‘pe’ directories within ‘ROOT/setup’ for examples.
Public Class Methods
@param [Hosts,Array<Host>] these_hosts The hosts to execute this test
against/on.
@param [Logger] logger A logger that implements
{Beaker::Logger}'s interface.
@param [Hash{Symbol=>String}] options Parsed command line options. @param [String] path The local path to a test file to be executed.
# File lib/beaker/test_case.rb, line 87 def initialize(these_hosts, logger, options = {}, path = nil) @hosts = these_hosts @logger = logger @sublog = "" @options = options @path = path @usr_home = options[:home] @test_status = :pass @exception = nil @runtime = nil @teardown_procs = [] @metadata = {} @exports = [] set_current_test_filename(@path ? File.basename(@path, '.rb') : nil) # # We put this on each wrapper (rather than the class) so that methods # defined in the tests don't leak out to other tests. class << self def run_test @logger.start_sublog @logger.last_result = nil set_current_step_name(nil) # add arbitrary role methods roles = [] @hosts.each do |host| roles << host[:roles] end add_role_def(roles.flatten.uniq) @runtime = Benchmark.realtime do begin test = File.read(path) eval test, nil, path, 1 rescue FailTest, TEST_EXCEPTION_CLASS => e log_and_fail_test(e, :fail) rescue PassTest @test_status = :pass rescue PendingTest @test_status = :pending rescue SkipTest @test_status = :skip rescue StandardError, ScriptError, SignalException => e log_and_fail_test(e) ensure @logger.info('Begin teardown') @teardown_procs.each do |teardown| begin teardown.call rescue StandardError, SignalException, TEST_EXCEPTION_CLASS => e log_and_fail_test(e, :teardown_error) end end @logger.info('End teardown') end end @sublog = @logger.get_sublog @last_result = @logger.last_result return self end private # Log an error and mark the test as failed, passing through an # exception so it can be displayed at the end of the total run. # # We break out the complete exception backtrace and log each line # individually as well. # # @param exception [Exception] exception to fail with # @param exception [Symbol] the test status def log_and_fail_test(exception, status = :error) logger.error("#{exception.class}: #{exception.message}") bt = exception.backtrace logger.pretty_backtrace(bt).each_line do |line| logger.error(line) end # If the status is already a test failure or error, don't overwrite with the teardown failure. return if status == :teardown_error && (@test_status == :error || @test_status == :fail) status = :error if status == :teardown_error @test_status = status @exception = exception end end end
# File lib/beaker/test_case.rb, line 106 def run_test @logger.start_sublog @logger.last_result = nil set_current_step_name(nil) # add arbitrary role methods roles = [] @hosts.each do |host| roles << host[:roles] end add_role_def(roles.flatten.uniq) @runtime = Benchmark.realtime do begin test = File.read(path) eval test, nil, path, 1 rescue FailTest, TEST_EXCEPTION_CLASS => e log_and_fail_test(e, :fail) rescue PassTest @test_status = :pass rescue PendingTest @test_status = :pending rescue SkipTest @test_status = :skip rescue StandardError, ScriptError, SignalException => e log_and_fail_test(e) ensure @logger.info('Begin teardown') @teardown_procs.each do |teardown| begin teardown.call rescue StandardError, SignalException, TEST_EXCEPTION_CLASS => e log_and_fail_test(e, :teardown_error) end end @logger.info('End teardown') end end @sublog = @logger.get_sublog @last_result = @logger.last_result return self end
Private Class Methods
Log an error and mark the test as failed, passing through an exception so it can be displayed at the end of the total run.
We break out the complete exception backtrace and log each line individually as well.
@param exception [Exception] exception to fail with @param exception [Symbol] the test status
# File lib/beaker/test_case.rb, line 160 def log_and_fail_test(exception, status = :error) logger.error("#{exception.class}: #{exception.message}") bt = exception.backtrace logger.pretty_backtrace(bt).each_line do |line| logger.error(line) end # If the status is already a test failure or error, don't overwrite with the teardown failure. return if status == :teardown_error && (@test_status == :error || @test_status == :fail) status = :error if status == :teardown_error @test_status = status @exception = exception end
Public Instance Methods
The TestCase
as a hash @api public @note The visibility and semantics of this method are valid, but the
structure of the Hash it returns may change without notice
@return [Hash] A Hash representation of this test.
# File lib/beaker/test_case.rb, line 182 def to_hash hash = {} hash['HOSTS'] = {} @hosts.each do |host| hash['HOSTS'][host.name] = host.overrides end hash end