# frozen_string_literal: true module GitlabQuality module TestTooling module Report # Uses the API to: # - create or update test cases # - create or update issues # based on the results of tests from RSpec run result files. class ReportResults < ReportAsIssue attr_accessor :testcase_project_reporter, :results_issue_project_reporter, :files, :test_case_project, :results_issue_project, :gitlab def initialize( token:, input_files:, test_case_project: nil, results_issue_project: nil, dry_run: false, **kwargs) @testcase_project_reporter = GitlabQuality::TestTooling::Report::ResultsInTestCases.new( token: token, input_files: input_files, project: test_case_project, dry_run: dry_run, **kwargs) @results_issue_project_reporter = GitlabQuality::TestTooling::Report::ResultsInIssues.new( token: token, input_files: input_files, project: results_issue_project, dry_run: dry_run, **kwargs) @test_case_project = test_case_project @results_issue_project = results_issue_project @files = Array(input_files) @gitlab = testcase_project_reporter.gitlab end def invoke! validate_input! run! end def validate_input! assert_input_files!(files) gitlab.assert_user_permission! end def assert_input_files!(files) return if Dir.glob(files).any? abort "Please provide valid JUnit report files. No files were found matching `#{files.join(',')}`" end # rubocop:disable Metrics/AbcSize def run! puts "Reporting test results in `#{files.join(',')}` as test cases in project `#{test_case_project}` " \ "and issues in project `#{results_issue_project}` via the API at `#{Runtime::Env.gitlab_api_base}`." TestResults::Builder.new(files).test_results_per_file do |test_results| puts "Reporting tests in #{test_results.path}" test_results.each do |test| next if test.file.include?('/features/sanity/') || test.skipped puts "Reporting test: #{test.file} | #{test.name}\n" report_test(test) end test_results.write end end # rubocop:enable Metrics/AbcSize private def report_test(test) testcase = testcase_project_reporter.find_or_create_testcase(test) # The API returns the test case with an issue URL since it is technically a type of issue. # This updates the URL to a valid test case link. test.testcase = testcase.web_url.sub('/issues/', '/quality/test_cases/') issue, is_new = results_issue_project_reporter.get_related_issue(testcase, test) testcase_project_reporter.add_issue_link_to_testcase(testcase, issue, test) if is_new testcase_project_reporter.update_testcase(testcase, test) results_issue_project_reporter.update_issue(issue, test) end end end end end