class Cucumber::Formatter::Junit

The formatter used for --format junit

Public Class Methods

new(_runtime, io, options) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 19
def initialize(_runtime, io, options)
  @reportdir = ensure_dir(io, "junit")
  @options = options
end

Public Instance Methods

after_test_case(test_case, result) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 42
def after_test_case(test_case, result)
  test_case_name = NameBuilder.new(test_case)
  scenario = test_case_name.scenario_name
  scenario_designation = "#{scenario}#{test_case_name.name_suffix}"
  output = create_output_string(test_case, scenario, result, test_case_name.row_name)
  build_testcase(result, scenario_designation, output)

  Interceptor::Pipe.unwrap! :stdout
  Interceptor::Pipe.unwrap! :stderr
end
after_test_step(test_step, result) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 36
def after_test_step(test_step, result)
  return if @failing_step_source

  @failing_step_source = test_step.source.last unless result.ok?(@options[:strict])
end
before_test_case(test_case) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 24
def before_test_case(test_case)
  unless same_feature_as_previous_test_case?(test_case.feature)
    end_feature if @current_feature
    start_feature(test_case.feature)
  end
  @failing_step_source = nil
  # In order to fill out <system-err/> and <system-out/>, we need to
  # intercept the $stderr and $stdout
  @interceptedout = Interceptor::Pipe.wrap(:stdout)
  @interceptederr = Interceptor::Pipe.wrap(:stderr)
end
done() click to toggle source
# File lib/cucumber/formatter/junit.rb, line 53
def done
  end_feature if @current_feature
end

Private Instance Methods

basename(feature_file) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 150
def basename(feature_file)
  File.basename(feature_file.gsub(/[\\/]/, '-'), '.feature')
end
build_testcase(result, scenario_designation, output) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 103
def build_testcase(result, scenario_designation, output)
  duration = ResultBuilder.new(result).test_case_duration
  @time += duration
  classname = @current_feature.name
  name = scenario_designation

  @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
    if !result.passed? && result.ok?(@options[:strict])
      @builder.skipped
      @skipped += 1
    elsif !result.passed?
      status = result.to_sym
      exception = get_backtrace_object(result)
      @builder.failure(:message => "#{status} #{name}", :type => status) do
        @builder.cdata! output
        @builder.cdata!(format_exception(exception)) if exception
      end
      @failures += 1
    end
    @builder.tag!('system-out') do
      @builder.cdata! strip_control_chars(@interceptedout.buffer.join)
    end
    @builder.tag!('system-err') do
      @builder.cdata! strip_control_chars(@interceptederr.buffer.join)
    end
  end
  @tests += 1
end
create_output_string(test_case, scenario, result, row_name) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 87
def create_output_string(test_case, scenario, result, row_name)
  output = "#{test_case.keyword}: #{scenario}\n\n"
  return output if result.ok?(@options[:strict])
  if test_case.keyword == "Scenario"
    output += "#{@failing_step_source.keyword}" unless hook?(@failing_step_source)
    output += "#{@failing_step_source.name}\n"
  else
    output += "Example row: #{row_name}\n"
  end
  output + "\nMessage:\n"
end
end_feature() click to toggle source
# File lib/cucumber/formatter/junit.rb, line 71
def end_feature
  @testsuite = Builder::XmlMarkup.new(:indent => 2)
  @testsuite.instruct!
  @testsuite.testsuite(
    :failures => @failures,
    :errors => @errors,
    :skipped => @skipped,
    :tests => @tests,
    :time => "%.6f" % @time,
    :name => @current_feature.name ) do
    @testsuite << @builder.target!
  end

  write_file(feature_result_filename(@current_feature.file), @testsuite.target!)
end
feature_result_filename(feature_file) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 146
def feature_result_filename(feature_file)
  File.join(@reportdir, "TEST-#{basename(feature_file)}.xml")
end
format_exception(exception) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 142
def format_exception(exception)
  (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
end
get_backtrace_object(result) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 132
def get_backtrace_object(result)
  if result.failed?
    return result.exception
  elsif result.backtrace
    return result
  else
    return nil
  end
end
hook?(step) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 99
def hook?(step)
  ["Before hook", "After hook", "AfterStep hook"].include? step.name
end
same_feature_as_previous_test_case?(feature) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 59
def same_feature_as_previous_test_case?(feature)
  @current_feature && @current_feature.file == feature.file && @current_feature.location == feature.location
end
start_feature(feature) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 63
def start_feature(feature)
  raise UnNamedFeatureError.new(feature.file) if feature.name.empty?
  @current_feature = feature
  @failures = @errors = @tests = @skipped = 0
  @builder = Builder::XmlMarkup.new(:indent => 2)
  @time = 0
end
strip_control_chars(cdata) click to toggle source

strip control chars from cdata, to make it safe for external parsers

# File lib/cucumber/formatter/junit.rb, line 159
def strip_control_chars(cdata)
  cdata.scan(/[[:print:]\t\n\r]/).join
end
write_file(feature_filename, data) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 154
def write_file(feature_filename, data)
  File.open(feature_filename, 'w') { |file| file.write(data) }
end