diff --git a/plugins/html_tests_report/README.md b/plugins/html_tests_report/README.md new file mode 100644 index 00000000..939c066d --- /dev/null +++ b/plugins/html_tests_report/README.md @@ -0,0 +1,38 @@ +html_tests_report +================ + +## Overview + +The html_tests_report plugin creates an HTML file of test results, +which makes the results easier to read. The HTML file is output to the appropriate +`/artifacts/` directory (e.g. `artifacts/test/` for test tasks, +`artifacts/gcov/` for gcov, or `artifacts/bullseye/` for bullseye runs). + +## Setup + +Enable the plugin in your project.yml by adding `html_tests_report` to the list +of enabled plugins. + +``` YAML +:plugins: + :enabled: + - html_tests_report +``` + +## Configuration + +Optionally configure the output / artifact filename in your project.yml with +the `artifact_filename` configuration option. The default filename is +`report.html`. + +You can also configure the path that this artifact is stored. This can be done +by setting `path`. The default is that it will be placed in a subfolder under +the `build` directory. + +If you use some means for continuous integration, you may also want to add +.xsl file to CI's configuration for proper parsing of .xml report. + +``` YAML +:html_tests_report: + :artifact_filename: report_test.html +``` diff --git a/plugins/html_tests_report/lib/html_tests_report.rb b/plugins/html_tests_report/lib/html_tests_report.rb new file mode 100644 index 00000000..31b5440d --- /dev/null +++ b/plugins/html_tests_report/lib/html_tests_report.rb @@ -0,0 +1,198 @@ +require 'ceedling/plugin' +require 'ceedling/constants' + +class HtmlTestsReport < Plugin + def setup + @results_list = {} + @test_counter = 0 + end + + def post_test_fixture_execute(arg_hash) + context = arg_hash[:context] + + @results_list[context] = [] if @results_list[context].nil? + + @results_list[context] << arg_hash[:result_file] + end + + def post_build + @results_list.each_key do |context| + results = @ceedling[:plugin_reportinator].assemble_test_results(@results_list[context]) + + artifact_filename = @ceedling[:configurator].project_config_hash[:html_tests_report_artifact_filename] || 'report.html' + artifact_fullpath = @ceedling[:configurator].project_config_hash[:html_tests_report_path] || File.join(PROJECT_BUILD_ARTIFACTS_ROOT, context.to_s) + file_path = File.join(artifact_fullpath, artifact_filename) + + @ceedling[:file_wrapper].open(file_path, 'w') do |f| + @test_counter = 1 + write_results(results, f) + end + end + end + + private + + def write_results(results, stream) + write_header(stream) + write_statistics(results[:counts], stream) + write_failures(results[:failures], stream) + write_tests(results[:ignores], stream, "Ignored Tests", "ignored") + write_tests(results[:successes], stream, "Success Tests", "success") + write_footer(stream) + end + + def write_header(stream) + stream.puts "" + stream.puts '' + stream.puts '' + stream.puts '' + stream.puts '' + stream.puts '' + stream.puts 'Test Overview' + stream.puts '' + stream.puts '' + stream.puts '' + end + + def write_statistics(counts, stream) + stream.puts '

Summary

' + stream.puts '' + stream.puts '' + stream.puts '' + stream.puts "" + stream.puts "" + stream.puts "" + stream.puts "" + stream.puts "" + stream.puts "" + stream.puts "" + stream.puts "
TotalPassedIgnoredFailed
#{counts[:total]}#{counts[:total] - counts[:ignored] - counts[:failed]}#{counts[:ignored]}#{counts[:failed]}
" + end + + def write_failures(results, stream) + if results.size.zero? + return + end + + stream.puts '

Failed Test

' + stream.puts '' + stream.puts '' + stream.puts '' + + results.each do |result| + filename = result[:source][:path] + result[:source][:file] + @first_row = true + + result[:collection].each do |item| + + stream.puts "" + + if @first_row + stream.puts "" + @first_row = false + end + + stream.puts "" + if item[:message].empty? + stream.puts "" + else + if item[:message].size > 150 + stream.puts "" + else + stream.puts "" + end + end + stream.puts "" + end + end + + stream.puts "" + stream.puts "
FileLocationMessage
#{filename}#{item[:test]}::#{item[:line]}
Message hidden due to long length.#{item[:message]}
#{item[:message]}
" + end + + def write_tests(results, stream, title, style) + if results.size.zero? + return + end + + stream.puts "

#{title}

" + stream.puts "" + stream.puts '' + stream.puts '' + + results.each do |result| + filename = result[:source][:path] + result[:source][:file] + @first_row = true + + result[:collection].each do |item| + stream.puts "" + + if @first_row + stream.puts "" + @first_row = false + end + + stream.puts "" + if item[:message].empty? + stream.puts "" + else + if item[:message].size > 150 + stream.puts "" + else + stream.puts "" + end + end + stream.puts "" + end + end + + stream.puts "" + stream.puts "
FileNameMessage
#{filename}#{item[:test]}
Message hidden due to long length.#{item[:message]}
#{item[:message]}
" + end + + def write_footer(stream) + stream.puts '' + stream.puts '' + end +end