kmiyashiro / grunt-mocha

[MOVED] Grunt task for running mocha specs in a headless browser (PhantomJS)
MIT License
370 stars 106 forks source link

XUnit: invalid XML if running multiple suites #141

Open givankin opened 9 years ago

givankin commented 9 years ago

Hi, the resulting XML for multiple suites is

<testsuite>...</testsuite>
<testsuite>...</testsuite>

Which is invalid XML (can't be parsed by Jenkins e.g.). According to XUnit Spec, it has to be:

<testsuites>
  <testsuite>...</testsuite>
  <testsuite>...</testsuite>
<testsuites>

From looking at code, I see the reason as this: as suites run one by one in a loop, reporter doesn't "know" anything about other suites and always acts as if there was a single suite - then the (valid) results for each suite are just concatenated. I would be glad to submit a PR, but I even don't know where to start because from the point of view of the reporter it works as expected. In my Gruntfile I currently just use fs to wrap final XML it <testsuites>.

shwangste commented 8 years ago

+1

kmiyashiro commented 8 years ago

Is wrapping the output in <testsuites> actually what the XUnit spec declares? I don't use XUnit so I'm not sure if adding this wrapper will break whatever consumes the output for those that are running single suites.

givankin commented 8 years ago

I can't find any mention of a testuite in XUnit Specs now (v1: http://xunit.codeplex.com/wikipage?title=XmlFormat&referringTitle=Home, v2: https://xunit.github.io/docs/format-xml-v2.html). All I can say is that making this change manually fixes Jenkins reporter for me. So it looks like the problem is not that we don't conform with the XUnit here, but that we produce an invalid XML in case of multiple suites...

givankin commented 8 years ago

Just in case, if anybody is interested, here's what I use for Grunt:

  grunt.registerTask('fixXunitXml', function () {
    var fs = require('fs'),
      path = 'report/xunit.xml',
      xml = fs.readFileSync(path, 'utf8');
    xml = '<testsuites>' + xml + '</testsuites>';
    fs.writeFileSync(path, xml);
  });