3 # Copyright (c) 2019 Orange and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 """Define classes required to run any Behave test suites."""
12 from __future__ import division
21 from behave.__main__ import main as behave_main
23 from xtesting.core import testcase
25 __author__ = "Deepak Chandella <deepak.chandella@orange.com>"
28 class BehaveFramework(testcase.TestCase):
29 """BehaveFramework runner."""
30 # pylint: disable=too-many-instance-attributes
32 __logger = logging.getLogger(__name__)
33 dir_results = "/var/lib/xtesting/results"
35 def __init__(self, **kwargs):
36 super(BehaveFramework, self).__init__(**kwargs)
37 self.json_file = os.path.join(self.res_dir, 'output.json')
44 def parse_results(self):
45 """Parse output.json and get the details in it."""
48 with open(self.json_file) as stream_:
49 self.response = json.load(stream_)
51 self.__logger.error("Error reading the file %s", self.json_file)
55 self.total_tests = len(self.response)
56 for item in self.response:
57 if item['status'] == 'passed':
59 elif item['status'] == 'failed':
61 elif item['status'] == 'skipped':
64 self.__logger.error("Error in json - %s", self.response)
68 self.pass_tests / self.total_tests)
69 except ZeroDivisionError:
70 self.__logger.error("No test has been run")
73 self.details['total_tests'] = self.total_tests
74 self.details['pass_tests'] = self.pass_tests
75 self.details['fail_tests'] = self.fail_tests
76 self.details['skip_tests'] = self.skip_tests
77 self.details['tests'] = self.response
79 def run(self, **kwargs):
80 """Run the BehaveFramework feature files
83 * create the output directories if required,
84 * run behave features with parameters
85 * get the results in output.json,
88 kwargs: Arbitrary keyword arguments.
91 EX_OK if all suites ran well.
92 EX_RUN_ERROR otherwise.
95 suites = kwargs["suites"]
96 tags = kwargs.get("tags", [])
98 self.__logger.exception("Mandatory args were not passed")
99 return self.EX_RUN_ERROR
100 if not os.path.exists(self.res_dir):
102 os.makedirs(self.res_dir)
103 except Exception: # pylint: disable=broad-except
104 self.__logger.exception("Cannot create %s", self.res_dir)
105 return self.EX_RUN_ERROR
106 config = ['--tags='+','.join(tags),
107 '--junit', '--junit-directory={}'.format(self.res_dir),
108 '--format=json', '--outfile={}'.format(self.json_file)]
110 html_file = os.path.join(self.res_dir, 'output.html')
111 config += ['--format=behave_html_formatter:HTMLFormatter',
112 '--outfile={}'.format(html_file)]
113 for feature in suites:
114 config.append(feature)
115 self.start_time = time.time()
117 self.stop_time = time.time()
121 self.__logger.info("Results were successfully parsed")
122 except Exception: # pylint: disable=broad-except
123 self.__logger.exception("Cannot parse results")
124 return self.EX_RUN_ERROR