Title / Description
Code require 'csv' require 'fileutils' require 'pathname' require 'nokogiri' require 'pp' class IBMTestReporter attr_reader :xml_runners, :test_result, :report attr_writer :test_result, :report PidResult = Struct.new(:pid, :fail, :pass, :total, :suite) TestCaseResult = Struct.new(:runner, :log, :suite, :results) def initialize(root_dir) @root_dir = File.expand_path(root_dir) @xml_runner_dir = File.join(@root_dir, 'xml_runner') @xml_runners = Dir.glob("#{@root_dir}/**/*.xml") @log_dir = @root_dir @csv_report_data = nil @csv_report_file = File.join(@root_dir, 'report_output.csv') @test_case_result = {} @report = {} end def list_xml_runners puts "XML Runner files in directory: \"#{@root_dir}\":" @xml_runners.each { |f| puts " #{f}"} end def get_status(msg) return "PASS" if msg.include? 'passed' return "FAIL" if msg.include? 'FAILED' 'info' end def parse(line) line.strip! return if line.empty? # TODO: test with and without this commented log_entry = line.split(' - ') log_event = {} log_event[:pid] = log_entry[0][/\d+/] log_event[:test_suite] = log_entry[2] log_event[:tc_within_suite] = log_entry[3][/\d+/] log_event[:status] = get_status(log_entry[4]) log_event end def do_analytics(log_path) all_log_events = File.readlines(log_path).collect do |line| parse(line) end.compact results_by_pid = {} all_log_events.each do |event| if results_by_pid.key?(event[:pid]) # update Struct if event[:status] == "PASS" results_by_pid[event[:pid]].pass += 1 results_by_pid[event[:pid]].total += 1 elsif event[:status] == "FAIL" results_by_pid[event[:pid]].fail += 1 results_by_pid[event[:pid]].total += 1 end else # create new Struct as value # PidResult = Struct.new(:pid, :fail, :pass, :total, :suite) results_by_pid[event[:pid]] = PidResult.new(event[:pid], 0, 0, 0, event[:test_suite]) end @test_case_result[log_path] = results_by_pid end end def process_logs @xml_runners.each do |runner| doc = File.open(runner) { |f| Nokogiri::XML(f) } doc.xpath("//TestCase").each do |tc| # log_path = File.join(@log_dir, (tc.attr('logpath').sub /^.{2}/,'')) # regex alternate may be more log_path = File.join(@log_dir, tc.attr('logpath')[2..-1]) # read-able than slice do_analytics(log_path) @report[tc.attr('name')] = TestCaseResult.new(runner, log_path, 'suite', @test_case_result[log_path]) end end end def make_report process_logs puts 'Formatting CSV report...' @csv_report_data = [] @report.each_key do |k| @report[k][:results].each_key do |pid| @csv_report_data << [@report[k][:results][pid][:pid], @report[k][:runner], k, @report[k][:results][pid][:suite], @report[k][:results][pid][:fail], @report[k][:results][pid][:pass], @report[k][:results][pid][:total]] end end end def write_csv if @csv_report_data == nil make_report end puts 'Final reports for QA Managers are always improving!' puts "Writing CSV report to file:\n #{@csv_report_file}" File.open(@csv_report_file, 'w') { |f| f << @csv_report_data.map(&:to_csv).join } end def create_directory_structure puts "Creating log directory structure in directory: \"#{@root_dir}\":" @report.each_key do |k| xml_file_dir = [].tap{|x| Pathname.new(@report[k][:runner]).each_filename{|d| x << d}}[-1] xml_tc_dir = "#{@root_dir}/QA_MANAGER_DIR/#{(xml_file_dir.sub /\.xml/,'')}/#{k}" FileUtils::mkdir_p xml_tc_dir @report[k][:results].each_key do |pid| FileUtils::mkdir_p "#{xml_tc_dir}/#{pid}" FileUtils.cp(@report[k][:log], File.join(xml_tc_dir, pid) ) end end end end # -------------- main ---------------- test_reporter = IBMTestReporter.new(ARGV[0]) test_reporter.list_xml_runners test_reporter.write_csv test_reporter.create_directory_structure puts 'hello world'
Author
Highlight as C C++ CSS Clojure Delphi ERb Groovy (beta) HAML HTML JSON Java JavaScript PHP Plain text Python Ruby SQL XML YAML diff code