Ceedling icon indicating copy to clipboard operation
Ceedling copied to clipboard

Line and file path missing from JUnit report

Open NovaNekmit opened this issue 4 years ago • 8 comments

Currently the JUnit report only reports the Error message itself, ie

<testsuites ...>
  <testsuite name="test_something" ...>
    <testcase name="test_some_func" time="0.000000">
      <failure message="Element 0 Expected 0x08 Was 0x09." />
    </testcase>
    ...

For comparison, the XUnit report looks like this:

...
<TestRun>
  <Test id="1">
    <Name>tests/test_something.c::test_some_func</Name>
    <FailureType>Assertion</FailureType>
    <Location>
      <File>tests/test_something.c</File>
      <Line>62</Line>
    </Location>
    <Message>Element 0 Expected 0x08 Was 0x09.</Message>
  </Test>
...

In my case the message is displayed via Gitlab CI which does not (and can not, since it is not in the XML show the line number).

I couldn't find if JUnit.xml has a dedicated place for line number, but in case it doesn't, the line number of the failed assertion should be part of the message.

Additionally, Gitlab parses the file attribute of the testcase as file path (and converts it into a link), and classname as test suite name, so it would be great if those fields would be populated as well, ie tests/test_something.c and test_something respectively.

For reference:

Gitlab JUnit Parser: https://gitlab.com/rluna-gitlab/gitlab-ce/-/blob/master/lib/gitlab/ci/parsers/test/junit.rb This gets displayed via: https://gitlab.com/rluna-gitlab/gitlab-ce/-/blob/master/app/assets/javascripts/pipelines/components/test_reports/test_suite_table.vue

NovaNekmit avatar Apr 14 '21 12:04 NovaNekmit

Hi, I found your issue while searching why gitlab does not parse the line number.

The junit supports line number like this:

        <testcase name="testCase2-line-attrib" classname="Tests.Registration" assertions="6"
            time="1.534" file="path/foo.bar" line="101" />

Gitlab automatically adds a link to the file in the repo, but sadly ignores the line attribute.

mathieugouin avatar Dec 16 '24 20:12 mathieugouin

Hi, I found your issue while searching why gitlab does not parse the line number.

The junit supports line number like this:

    <testcase name="testCase2-line-attrib" classname="Tests.Registration" assertions="6"
        time="1.534" file="path/foo.bar" line="101" />

Gitlab automatically adds a link to the file in the repo, but sadly ignores the line attribute.

yea this is not good, some test files have 100+ tests and even if 1 fails, gitlab suggests me to rerun whole file :\

company-account-1 avatar Nov 05 '25 07:11 company-account-1

If it can be of any help, I post process the xml to update the file tag as "path/foo.bar#101".

This way the gitlab link brings me at the right line.

mathieugouin avatar Nov 06 '25 03:11 mathieugouin

If it can be of any help, I post process the xml to update the file tag as "path/foo.bar#101".

This way the gitlab link brings me at the right line.

sorry but I can't follow, how did you do it exactly?

company-account-1 avatar Nov 06 '25 13:11 company-account-1

Just some simple python with element tree.

Let me know if you need more details, I'll try to get the exact script.

mathieugouin avatar Nov 06 '25 21:11 mathieugouin

Maybe you need this: https://github.com/melexis/unity2junit

Letme avatar Nov 06 '25 21:11 Letme

Just some simple python with element tree.

Let me know if you need more details, I'll try to get the exact script.

Oh wait do you get the line number and populate fields based on the test failure message?

company-account-1 avatar Nov 07 '25 09:11 company-account-1

@mathieugouin I had to add line number also to files, "copy failed tests" button ignored output << %( line="#{escape(line_number)}")

# add line number to failing test reports

if Rails.env.test?
  require "rspec_junit_formatter"

  class RSpecJUnitFormatter < RSpec::Core::Formatters::BaseFormatter
    private

    def xml_dump_example(example)
      output << %(<testcase)
      output << %( classname="#{escape(classname_for(example))}")
      output << %( name="#{escape(description_for(example))}")

      # monkey-patch start
      if (line_number = example.example.metadata[:line_number])
        output << %( line="#{escape(line_number)}")
      end
      output << %( file="#{escape(example_group_file_path_for(example))}:#{line_number}")
      # monkey-patch end

      if (duration = duration_for(example))
        output << %( time="#{escape('%.6f' % duration)}")
      end

      output << %(>)

      yield if block_given?

      xml_dump_output(example)
      output << %(</testcase>\n)
    end
  end
end

company-account-1 avatar Nov 11 '25 09:11 company-account-1