Create SonarQube report from Rails minitest
Create reporter class for SonarQube Generic Test Data export By: Dániel Sipos onRails makes it super easy to write tests. It starts by producing skeleton test code while you are creating your models and controllers. Rails default test framework is Minitest.
SonarQube supports generic formats for test coverage and test execution import. The native output of Minitest coverage tool is not supported by SonarQube, so must convert it to Generic Test Data format.
Minitest-reporters gem will swap out the Minitest runner to the custom one used by minitest-reporters and use the correct reporters for Textmate, Rubymine, and the console. This gem is great, but does not include reporter for SonarQube. So I wrote own reporter, just include Minitest::Reporter and I override the methods.
Create sonar_qube_reporter.rb in your lib directory:
require 'minitest/reporters'
# A reporter for writing SonarQube test reports (Generic Test Data)
class SonarQubeReporter < Minitest::Reporters::JUnitReporter
def report
puts "Writing XML reports to #{@reports_path}"
suites = tests.group_by do |test|
test_class(test)
end
if @single_file
xml = Builder::XmlMarkup.new(:indent => 2)
xml.instruct!
xml.testExecutions(:version => 1) do
suites.each do |suite, tests|
parse_xml_for(xml, suite, tests)
end
end
File.open(filename_for('minitest'), 'w') { |file| file << xml.target! }
else
suites.each do |suite, tests|
xml = Builder::XmlMarkup.new(:indent => 2)
xml.instruct!
xml.testExecutions(:version => 1) do
parse_xml_for(xml, suite, tests)
end
File.open(filename_for(suite), 'w') { |file| file << xml.target! }
end
end
end
private
def parse_xml_for(xml, _suite, tests)
file_path = get_relative_path(tests.first)
xml.file(:path => file_path) do
tests.each do |test|
xml.testCase(:name => test.name, :duration => (test.time * 1000).to_i) do
xml << xml_message_for(test) unless test.passed?
end
end
end
end
end
Use the previously defined class in your test/test_helper.rb file, such as the following example.
require 'minitest/reporters'
require 'sonar_qube_reporter'
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new, SonarQubeReporter.new('test/reports', true, { single_file: true })] unless ENV.fetch('RM_INFO', false)
Finally, the following properties must be set in the project file sonar-project.properties to be processed.
sonar.testExecutionReportPaths=test/reports/TEST-minitest.xml
Conclusion
A very clean and easy-to-use solution was created for the Minitest report problem.