aboutsummaryrefslogtreecommitdiffstats
path: root/xtesting/core
diff options
context:
space:
mode:
authorCédric Ollivier <cedric.ollivier@orange.com>2018-12-26 11:23:02 +0100
committerCédric Ollivier <cedric.ollivier@orange.com>2018-12-27 11:03:08 +0100
commit07d8b10d394d1632742c16e4f1f45a29879cf7c1 (patch)
tree5ba44eae034cb97d457322efd2b02257db99af82 /xtesting/core
parent250774f753476dcc1c507d6cca9e0cf6b879875d (diff)
Generate reports for unit tests
It now leverages on subunit to generate html and xml reports. Change-Id: I3f5a4fe5547e743b122b63e0b8530c9d9677cdbd Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
Diffstat (limited to 'xtesting/core')
-rw-r--r--xtesting/core/unit.py65
1 files changed, 58 insertions, 7 deletions
diff --git a/xtesting/core/unit.py b/xtesting/core/unit.py
index 27773679..f874d01f 100644
--- a/xtesting/core/unit.py
+++ b/xtesting/core/unit.py
@@ -12,9 +12,13 @@
from __future__ import division
import logging
+import os
+import shutil
+import subprocess
import time
import unittest
+from subunit.run import SubunitTestRunner
import six
from xtesting.core import testcase
@@ -30,8 +34,46 @@ class Suite(testcase.TestCase):
def __init__(self, **kwargs):
super(Suite, self).__init__(**kwargs)
+ self.res_dir = "/var/lib/xtesting/results/{}".format(self.case_name)
self.suite = None
+ @classmethod
+ def generate_stats(cls, stream):
+ """Generate stats from subunit stream
+
+ Raises:
+ Exception
+ """
+ stream.seek(0)
+ stats = subprocess.Popen(
+ ['subunit-stats'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+ output, _ = stats.communicate(stream.read())
+ cls.__logger.info("\n\n%s", output)
+
+ def generate_xunit(self, stream):
+ """Generate junit report from subunit stream
+
+ Raises:
+ Exception
+ """
+ stream.seek(0)
+ with open("{}/results.xml".format(self.res_dir), "w") as xml:
+ stats = subprocess.Popen(
+ ['subunit2junitxml'], stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ output, _ = stats.communicate(stream.read())
+ xml.write(output)
+
+ def generate_html(self, stream):
+ """Generate html report from subunit stream
+
+ Raises:
+ CalledProcessError
+ """
+ cmd = ['subunit2html', stream, '{}/results.html'.format(self.res_dir)]
+ output = subprocess.check_output(cmd)
+ self.__logger.debug("\n%s\n\n%s", ' '.join(cmd), output)
+
def run(self, **kwargs):
"""Run the test suite.
@@ -53,8 +95,8 @@ class Suite(testcase.TestCase):
Args:
kwargs: Arbitrary keyword arguments.
- Returns:
- TestCase.EX_OK if any TestSuite has been run,
+ Return:
+ TestCase.EX_OK if any TestSuite has been run
TestCase.EX_RUN_ERROR otherwise.
"""
try:
@@ -69,16 +111,22 @@ class Suite(testcase.TestCase):
try:
assert self.suite
self.start_time = time.time()
+ if not os.path.isdir(self.res_dir):
+ os.makedirs(self.res_dir)
stream = six.StringIO()
- result = unittest.TextTestRunner(
- stream=stream, verbosity=2).run(self.suite)
- self.__logger.debug("\n\n%s", stream.getvalue())
+ result = SubunitTestRunner(
+ stream=stream, verbosity=2).run(self.suite).decorated
+ self.generate_stats(stream)
+ self.generate_xunit(stream)
+ with open('{}/subunit_stream'.format(self.res_dir), 'w') as subfd:
+ stream.seek(0)
+ shutil.copyfileobj(stream, subfd)
+ self.generate_html('{}/subunit_stream'.format(self.res_dir))
self.stop_time = time.time()
self.details = {
"testsRun": result.testsRun,
"failures": len(result.failures),
- "errors": len(result.errors),
- "stream": stream.getvalue()}
+ "errors": len(result.errors)}
self.result = 100 * (
(result.testsRun - (len(result.failures) +
len(result.errors))) /
@@ -90,3 +138,6 @@ class Suite(testcase.TestCase):
except ZeroDivisionError:
self.__logger.error("No test has been run")
return testcase.TestCase.EX_RUN_ERROR
+ except Exception: # pylint: disable=broad-except
+ self.__logger.exception("something wrong occurs")
+ return testcase.TestCase.EX_RUN_ERROR