Generate robot reports 77/60677/2
authorCédric Ollivier <cedric.ollivier@orange.com>
Tue, 7 Aug 2018 05:16:57 +0000 (07:16 +0200)
committerCédric Ollivier <cedric.ollivier@orange.com>
Tue, 7 Aug 2018 07:29:02 +0000 (09:29 +0200)
Change-Id: Ib9efe14bce6227f9609200c12ded4470bd0be969
Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
xtesting/core/robotframework.py
xtesting/tests/unit/core/test_robotframework.py

index 007b962..4cba7bb 100644 (file)
@@ -17,6 +17,7 @@ import os
 
 import robot.api
 from robot.errors import RobotError
+from robot.reporting import resultwriter
 import robot.run
 from robot.utils.robottime import timestamp_to_secs
 from six import StringIO
@@ -77,6 +78,15 @@ class RobotFramework(testcase.TestCase):
         self.details['description'] = result.suite.name
         self.details['tests'] = visitor.get_data()
 
+    def generate_report(self):
+        """Generate html and xunit outputs"""
+        result = robot.api.ExecutionResult(self.xml_file)
+        writer = resultwriter.ResultWriter(result)
+        return writer.write_results(
+            report='{}/report.html'.format(self.res_dir),
+            log='{}/log.html'.format(self.res_dir),
+            xunit='{}/xunit.xml'.format(self.res_dir))
+
     def run(self, **kwargs):
         """Run the RobotFramework suites
 
@@ -113,11 +123,12 @@ class RobotFramework(testcase.TestCase):
         robot.run(*suites, variable=variable, variablefile=variablefile,
                   include=include, output=self.xml_file, log='NONE',
                   report='NONE', stdout=stream)
-        self.__logger.info("\n" + stream.getvalue())
-        self.__logger.info("Results were successfully generated")
+        self.__logger.info("\n%s", stream.getvalue())
         try:
             self.parse_results()
             self.__logger.info("Results were successfully parsed")
+            assert self.generate_report() == 0
+            self.__logger.info("Results were successfully generated")
         except RobotError as ex:
             self.__logger.error("Run suites before publishing: %s", ex.message)
             return self.EX_RUN_ERROR
index e01ada2..4cda171 100644 (file)
@@ -110,6 +110,59 @@ class ParseResultTesting(unittest.TestCase):
         self._test_result(self._config, 100)
 
 
+class GenerateReportTesting(unittest.TestCase):
+
+    """The class testing RobotFramework.generate_report()."""
+    # pylint: disable=missing-docstring
+
+    def setUp(self):
+        self.test = robotframework.RobotFramework(
+            case_name='robot', project_name='xtesting')
+
+    @mock.patch('robot.api.ExecutionResult', side_effect=Exception)
+    def test_exc1(self, *args):
+        with self.assertRaises(Exception):
+            self.test.generate_report()
+        args[0].assert_called_once_with(self.test.xml_file)
+
+    @mock.patch('robot.reporting.resultwriter.ResultWriter.__init__',
+                return_value=mock.Mock(side_effect=Exception))
+    @mock.patch('robot.api.ExecutionResult')
+    def test_exc2(self, *args):  # pylint: disable=unused-argument
+        with self.assertRaises(Exception):
+            self.test.generate_report()
+        args[0].assert_called_once_with(self.test.xml_file)
+        args[1].assert_called_once_with(args[0].return_value)
+
+    @mock.patch('robot.reporting.resultwriter.ResultWriter.write_results',
+                return_value=1)
+    @mock.patch('robot.reporting.resultwriter.ResultWriter.__init__',
+                return_value=None)
+    @mock.patch('robot.api.ExecutionResult')
+    def test_err(self, *args):
+        self.assertEqual(self.test.generate_report(), 1)
+        args[0].assert_called_once_with(self.test.xml_file)
+        args[1].assert_called_once_with(args[0].return_value)
+        args[2].assert_called_once_with(
+            report='{}/report.html'.format(self.test.res_dir),
+            log='{}/log.html'.format(self.test.res_dir),
+            xunit='{}/xunit.xml'.format(self.test.res_dir))
+
+    @mock.patch('robot.reporting.resultwriter.ResultWriter.write_results',
+                return_value=0)
+    @mock.patch('robot.reporting.resultwriter.ResultWriter.__init__',
+                return_value=None)
+    @mock.patch('robot.api.ExecutionResult')
+    def test_ok(self, *args):  # pylint: disable=unused-argument
+        self.assertEqual(self.test.generate_report(), 0)
+        args[0].assert_called_once_with(self.test.xml_file)
+        args[1].assert_called_once_with(args[0].return_value)
+        args[2].assert_called_once_with(
+            report='{}/report.html'.format(self.test.res_dir),
+            log='{}/log.html'.format(self.test.res_dir),
+            xunit='{}/xunit.xml'.format(self.test.res_dir))
+
+
 class RunTesting(unittest.TestCase):
 
     """The class testing RobotFramework.run()."""
@@ -129,7 +182,8 @@ class RunTesting(unittest.TestCase):
 
     @mock.patch('robot.run')
     def _test_makedirs_exc(self, *args):
-        with mock.patch.object(self.test, 'parse_results') as mock_method:
+        with mock.patch.object(self.test, 'parse_results') as mock_method, \
+                mock.patch.object(self.test, 'generate_report') as mmethod:
             self.assertEqual(
                 self.test.run(
                     suites=self.suites, variable=self.variable,
@@ -137,6 +191,7 @@ class RunTesting(unittest.TestCase):
                 self.test.EX_RUN_ERROR)
             args[0].assert_not_called()
             mock_method.asser_not_called()
+            mmethod.asser_not_called()
 
     @mock.patch('os.makedirs', side_effect=Exception)
     def test_makedirs_exc(self, *args):
@@ -150,7 +205,9 @@ class RunTesting(unittest.TestCase):
 
     @mock.patch('robot.run')
     def _test_makedirs(self, *args):
-        with mock.patch.object(self.test, 'parse_results') as mock_method:
+        with mock.patch.object(self.test, 'parse_results') as mock_method, \
+                mock.patch.object(self.test, 'generate_report',
+                                  return_value=0) as mmethod:
             self.assertEqual(
                 self.test.run(suites=self.suites, variable=self.variable),
                 self.test.EX_OK)
@@ -159,6 +216,7 @@ class RunTesting(unittest.TestCase):
                 report='NONE', stdout=mock.ANY, variable=self.variable,
                 variablefile=self.variablefile, include=self.include)
             mock_method.assert_called_once_with()
+            mmethod.assert_called_once_with()
 
     @mock.patch('os.makedirs', side_effect=OSError(errno.EEXIST, ''))
     def test_makedirs_oserror17(self, *args):
@@ -186,15 +244,53 @@ class RunTesting(unittest.TestCase):
 
     def test_parse_results_exc(self):
         with mock.patch.object(self.test, 'parse_results',
-                               side_effect=Exception) as mock_method:
+                               side_effect=Exception) as mock_method, \
+                mock.patch.object(self.test, 'generate_report') as mmethod:
             self._test_parse_results(self.test.EX_RUN_ERROR)
             mock_method.assert_called_once_with()
+            mmethod.asser_not_called()
 
     def test_parse_results_robot_error(self):
         with mock.patch.object(self.test, 'parse_results',
-                               side_effect=RobotError('foo')) as mock_method:
+                               side_effect=RobotError('foo')) as mock_method, \
+                mock.patch.object(self.test, 'generate_report') as mmethod:
             self._test_parse_results(self.test.EX_RUN_ERROR)
             mock_method.assert_called_once_with()
+            mmethod.asser_not_called()
+
+    @mock.patch('os.makedirs')
+    @mock.patch('robot.run')
+    def _test_generate_report(self, status, *args):
+        with mock.patch.object(self.test, 'parse_results') as mock_method:
+            self.assertEqual(
+                self.test.run(
+                    suites=self.suites, variable=self.variable,
+                    variablefile=self.variablefile, include=self.include),
+                status)
+        args[0].assert_called_once_with(
+            *self.suites, log='NONE', output=self.test.xml_file,
+            report='NONE', stdout=mock.ANY, variable=self.variable,
+            variablefile=self.variablefile, include=self.include)
+        args[1].assert_called_once_with(self.test.res_dir)
+        mock_method.assert_called_once_with()
+
+    def test_generate_report_exc(self):
+        with mock.patch.object(self.test, 'generate_report',
+                               side_effect=Exception) as mmethod:
+            self._test_generate_report(self.test.EX_RUN_ERROR)
+            mmethod.assert_called_once_with()
+
+    def test_generate_report_err(self):
+        with mock.patch.object(self.test, 'generate_report',
+                               return_value=1) as mmethod:
+            self._test_generate_report(self.test.EX_RUN_ERROR)
+            mmethod.assert_called_once_with()
+
+    def test_generate_report(self):
+        with mock.patch.object(self.test, 'generate_report',
+                               return_value=0) as mmethod:
+            self._test_generate_report(self.test.EX_OK)
+            mmethod.assert_called_once_with()
 
 
 if __name__ == "__main__":