Skip to content

Instantly share code, notes, and snippets.

@mkorpela
Created August 23, 2014 08:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkorpela/2cf3a48ad14328494d96 to your computer and use it in GitHub Desktop.
Save mkorpela/2cf3a48ad14328494d96 to your computer and use it in GitHub Desktop.
result_merger.py
# Copyright 2014 Mikko Korpela
# Partly based on work of Pekka
# under Copyright 2008-2014 Nokia Solutions and Networks
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from robot.api import ExecutionResult
from robot.model import SuiteVisitor
class ResultMerger(SuiteVisitor):
def __init__(self, result):
self.root = result.suite
self.current = None
self._skip_until = None
def merge(self, merged):
try:
merged.suite.visit(self)
except:
print 'Error while merging result %s' % merged.source
raise
def start_suite(self, suite):
if self._skip_until and self._skip_until != suite:
return
if not self.current:
self.current = self._find_root(suite)
assert self.current
else:
next = self._find(self.current.suites, suite.name)
if next is None:
self.current.suites.append(suite)
suite.parent = self.current
self._skip_until = suite
else:
self.current = next
def _find_root(self, suite):
if self.root.name != suite.name:
raise ValueError('self.root.name "%s" != suite.name "%s"' % (self.root.name, suite.name))
return self.root
def _find(self, items, name):
for item in items:
if item.name == name:
return item
return None
def end_suite(self, suite):
if self._skip_until and self._skip_until != suite:
return
if self._skip_until == suite:
self._skip_until = None
return
self.current = self.current.parent
def visit_test(self, test):
pass
def merge(*result_files):
assert len(result_files) > 0
out = ExecutionResult(result_files[0])
merger = ResultMerger(out)
for result in result_files[1:]:
merger.merge(ExecutionResult(result))
return out
if __name__ == '__main__':
merge('../tmp/passing.xml', '../tmp/failing.xml').save('../tmp/merged.xml')
@email2vimalraj
Copy link

Hi mkorpela,

I have a test suite "my_test_suite.robot" like this:

*** Test Cases ***
Test Case 1
    Log  Test 1

Test Case 2
    Log  Test 2

Then I run the pybot command twice as like this:

pybot --timestampoutputs my_test_suite.robot

So I get the reports two times. Now after that I ran the rebot command as follows:

rebot --name RebotCombined *.xml

It produced the neat combined report.html file where the high-level test suite is RebotCombined and two child test suites with the same name as "My Test Suite". i.e.,

RebotCombined
|
--- My Test Suite
|   |
|   --- Test Case 1
|   --- Test Case 2
--- My Test Suite
|   |
|   --- Test Case 1
|   --- Test Case 2

But what I was expecting is:

RebotCombined
|
--- My Test Suite
|   |
|   --- Test Case 1
|   --- Test Case 1
|   --- Test Case 2
|   --- Test Case 2

How can I achieve this?
I tried using the result_merger.py also, but getting the same output. Please help me in this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment