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 18
def initialize(runtime, io, options)
  @reportdir = ensure_dir(io, "junit")
  @options = options
end

Public Instance Methods

after_background(*args) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 68
def after_background(*args)
  @in_background = false
end
after_examples(*args) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 102
def after_examples(*args)
  @in_examples = false
end
after_feature(feature) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 39
def after_feature(feature)
  @testsuite = OrderedXmlMarkup.new( :indent => 2 )
  @testsuite.instruct!
  @testsuite.testsuite(
    :failures => @failures,
    :errors => @errors,
    :skipped => @skipped,
    :tests => @tests,
    :time => "%.6f" % @time,
    :name => @feature_name ) do
    @testsuite << @builder.target!
    @testsuite.tag!('system-out') do
      @testsuite.cdata! strip_control_chars(@interceptedout.buffer.join)
    end
    @testsuite.tag!('system-err') do
      @testsuite.cdata! strip_control_chars(@interceptederr.buffer.join)
    end
  end

  write_file(feature_result_filename(feature.file), @testsuite.target!)

  Interceptor::Pipe.unwrap! :stdout
  Interceptor::Pipe.unwrap! :stderr
end
after_steps(steps) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 86
def after_steps(steps)
  return if @in_background || @in_examples

  duration = Time.now - @steps_start
  if steps.failed?
    steps.each { |step| @output += "#{step.keyword}#{step.name}\n" }
    @output += "\nMessage:\n"
  end
  build_testcase(duration, steps.status, steps.exception)
end
after_table_row(table_row) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 112
def after_table_row(table_row)
  return unless @in_examples and Cucumber::Ast::OutlineTable::ExampleRow === table_row
  duration = Time.now - @table_start
  unless @header_row
    name_suffix = " (outline example : #{table_row.name})"
    if table_row.failed?
      @output += "Example row: #{table_row.name}\n"
      @output += "\nMessage:\n"
    end
    build_testcase(duration, table_row.status, table_row.exception, name_suffix)
  end

  @header_row = false if @header_row
end
before_background(*args) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 64
def before_background(*args)
  @in_background = true
end
before_examples(*args) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 97
def before_examples(*args)
  @header_row = true
  @in_examples = true
end
before_feature(feature) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 23
def before_feature(feature)
  @current_feature = feature
  @failures = @errors = @tests = @skipped = 0
  @builder = OrderedXmlMarkup.new( :indent => 2 )
  @time = 0
  # 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
before_feature_element(feature_element) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 34
def before_feature_element(feature_element)
  @in_examples = Ast::ScenarioOutline === feature_element
  @steps_start = Time.now
end
before_steps(steps) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 83
def before_steps(steps)
end
before_table_row(table_row) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 106
def before_table_row(table_row)
  return unless @in_examples

  @table_start = Time.now
end
feature_name(keyword, name) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 72
def feature_name(keyword, name)
  raise UnNamedFeatureError.new(@current_feature.file) if name.empty?
  lines = name.split(/\r?\n/)
  @feature_name = lines[0]
end
scenario_name(keyword, name, file_colon_line, source_indent) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 78
def scenario_name(keyword, name, file_colon_line, source_indent)
  @scenario = (name.nil? || name == "") ? "Unnamed scenario" : name.split("\n")[0]
  @output = "#{keyword}: #{@scenario}\n\n"
end

Private Instance Methods

basename(feature_file) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 160
def basename(feature_file)
  File.basename(feature_file.gsub(/[\\/]/, '-'), '.feature')
end
build_testcase(duration, status, exception = nil, suffix = "") click to toggle source
# File lib/cucumber/formatter/junit.rb, line 129
def build_testcase(duration, status, exception = nil, suffix = "")
  @time += duration
  classname = @feature_name
  name = "#{@scenario}#{suffix}"
  pending = [:pending, :undefined].include?(status) && (!@options[:strict])

  @builder.testcase(:classname => classname, :name => name, :time => "%.6f" % duration) do
    if status == :skipped || pending
      @builder.skipped
      @skipped += 1
    elsif status != :passed
      @builder.failure(:message => "#{status.to_s} #{name}", :type => status.to_s) do
        @builder.cdata! @output
        @builder.cdata!(format_exception(exception)) if exception
      end
      @failures += 1
    end
    @builder.tag!('system-out')
    @builder.tag!('system-err')
  end
  @tests += 1
end
feature_result_filename(feature_file) click to toggle source
# File lib/cucumber/formatter/junit.rb, line 156
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 152
def format_exception(exception)
  (["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n")
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 169
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 164
def write_file(feature_filename, data)
  File.open(feature_filename, 'w') { |file| file.write(data) }
end