Package test_suite :: Module relax_test_runner
[hide private]
[frames] | no frames]

Source Code for Module test_suite.relax_test_runner

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2008,2011,2013-2014 Edward d'Auvergne                         # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Python module imports. 
 23  import dep_check 
 24  from re import search, split 
 25  import sys 
 26  from time import time 
 27  from unittest import TextTestRunner 
 28  if dep_check.wx_module: 
 29      import wx 
 30   
 31  # relax module imports. 
 32  from lib.compat import StringIO 
 33  from lib.compat import TextTestResult 
 34  from status import Status; status = Status() 
 35   
 36   
37 -class RelaxTestResult(TextTestResult):
38 """A replacement for the TextTestResult class. 39 40 This class is designed to catch STDOUT and STDERR during the execution of each test and to 41 prepend the output to the failure and error reports normally generated by TextTestRunner. 42 """ 43
44 - def __init__(self, stream, descriptions, verbosity, timing=False, category=None):
45 """Initialise the RelaxTestResult object with relax specific variables. 46 47 @keyword timing: A flag which if True will enable timing of individual tests. 48 @type timing: bool 49 @keyword category: The type of test being performed, to allow the printouts to be changed. This can be one of 'system', 'unit', 'gui', or 'verification'. the printout. 50 @type category: str 51 """ 52 53 # Normal setup. 54 super(RelaxTestResult, self).__init__(stream, descriptions, verbosity) 55 56 # Store the timing flag and category. 57 self.timing_flag = timing 58 self.category = category
59 60
61 - def addError(self, test, err):
62 """Override of the TestResult.addError() method. 63 64 The STDOUT and STDERR captured text is prepended to the error text here. 65 66 67 @param test: The test object. 68 @type test: TestCase instance 69 @param err: A tuple of values as returned by sys.exc_info(). 70 @type err: tuple of values 71 """ 72 73 # Execute the base class method to print the 'E' and handle the error. 74 super(RelaxTestResult, self).addError(test, err) 75 76 # Prepend the STDOUT and STDERR messages to the second element of the tuple. 77 self.errors[-1] = (self.errors[-1][0], self.capt.getvalue() + self.errors[-1][1]) 78 79 # Write out timing info. 80 if self.timing_flag: 81 self.write_time(test.id())
82 83
84 - def addFailure(self, test, err):
85 """Override of the TestResult.addFailure() method. 86 87 The STDOUT and STDERR captured text is prepended to the failure text here. 88 89 90 @param test: The test object. 91 @type test: TestCase instance 92 @param err: A tuple of values as returned by sys.exc_info(). 93 @type err: tuple of values 94 """ 95 96 # Execute the base class method to print the 'F' and handle the failure. 97 super(RelaxTestResult, self).addFailure(test, err) 98 99 # Prepend the STDOUT and STDERR messages to the second element of the tuple. 100 self.failures[-1] = (self.failures[-1][0], self.capt.getvalue() + self.failures[-1][1]) 101 102 # Write out timing info. 103 if self.timing_flag: 104 self.write_time(test.id())
105 106
107 - def addSuccess(self, test):
108 """The method for a successful test. 109 110 @param test: The test object. 111 @type test: TestCase instance 112 """ 113 114 # Execute the base class method to print the '.'. 115 super(RelaxTestResult, self).addSuccess(test) 116 117 # Write out timing info. 118 if self.timing_flag: 119 self.write_time(test.id())
120 121
122 - def startTest(self, test):
123 """Override of the TextTestResult.startTest() method. 124 125 The start of STDOUT and STDERR capture occurs here. 126 """ 127 128 # Store the original STDOUT and STDERR for restoring later on. 129 self.orig_stdout = sys.stdout 130 self.orig_stderr = sys.stderr 131 132 # Catch stdout and stderr. 133 self.capt = StringIO() 134 if not status.debug: 135 sys.stdout = self.capt 136 sys.stderr = self.capt 137 138 # Place the test name in the status object. 139 status.exec_lock.test_name = str(test) 140 141 # Store the starting time. 142 if self.timing_flag: 143 self.time = time() 144 145 # Execute the normal startTest method. 146 super(RelaxTestResult, self).startTest(test)
147 148
149 - def stopTest(self, test):
150 """Override of the TextTestResult.stopTest() method. 151 152 The end of STDOUT and STDERR capture occurs here. 153 """ 154 155 # Restore the IO streams. 156 sys.stdout = self.orig_stdout 157 sys.stderr = self.orig_stderr
158 159
160 - def write_time(self, test_name):
161 """Write the timing of the test to the stream. 162 163 @param test_name: The TestCase name. 164 @type test_name: str 165 """ 166 167 # Subtract the end time from the start time. 168 self.time -= time() 169 170 # Change the test name for all but unit tests. 171 if self.category != 'unit': 172 test_name = test_name.split('.') 173 test_name = "%s.%s" % (test_name[-2], test_name[-1]) 174 175 # Handle errors. 176 elif search('Error', test_name): 177 pass 178 179 # Modify the unit test name printout. 180 else: 181 # Strip out the leading 'test_suite.unit_tests.' text. 182 test_name = test_name.replace('test_suite.unit_tests.', '') 183 184 # Split out the module name from the test name. 185 module_name, test_name = split('.Test_', test_name) 186 187 # Rebuild the test name. 188 test_name = "module %s, test Test_%s" % (module_name, test_name) 189 190 # The printout. 191 if self.category == 'unit': 192 time_str = '%7.2f ms' % (abs(self.time) * 1000) 193 else: 194 time_str = '%7.2f s' % abs(self.time) 195 self.stream.write(' %s for %s\n' % (time_str, test_name))
196 197 198
199 -class GuiTestResult(RelaxTestResult):
200 """A replacement for the TextTestResult class for the GUI.""" 201
202 - def stopTest(self, test):
203 """Override of the RelaxTestResult.stopTest() method. 204 205 The end of STDOUT and STDERR capture occurs here. 206 """ 207 208 # Execute the RelaxTestResult.stopTest() method. 209 super(GuiTestResult, self).stopTest(test) 210 211 # Yield to allow the GUI to be updated. 212 wx.GetApp().Yield(True)
213 214 215
216 -class RelaxTestRunner(TextTestRunner):
217 """A replacement unittest runner. 218 219 This runner is designed to catch STDOUT during the execution of each test and to prepend the 220 output to the failure and error reports normally generated by TextTestRunner. 221 """ 222 223 # Variable for specifying the type of test being performed, to change the printout. 224 category = None 225
226 - def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False):
227 """Initialise the class, storing the timing flag. 228 229 @keyword timing: A flag which if True will enable timing of individual tests. 230 @type timing: bool 231 """ 232 233 # Execute the base method (with different Python version compatibility). 234 if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6): 235 super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity) 236 else: 237 super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass) 238 239 # Store the flag. 240 self.timing_flag = timing
241 242
243 - def _makeResult(self):
244 """Override of the TextTestRunner._makeResult() method.""" 245 246 return RelaxTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag, category=self.category)
247 248 249
250 -class GuiTestRunner(TextTestRunner):
251 """A replacement unittest runner. 252 253 This runner is designed to catch STDOUT during the execution of each test and to prepend the 254 output to the failure and error reports normally generated by TextTestRunner. 255 """ 256
257 - def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False):
258 """Initialise the class, storing the timing flag. 259 260 @keyword timing: A flag which if True will enable timing of individual tests. 261 @type timing: bool 262 """ 263 264 # Execute the base method. 265 if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6): 266 super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity) 267 else: 268 super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass) 269 270 # Store the flag. 271 self.timing_flag = timing
272 273
274 - def _makeResult(self):
275 """Override of the TextTestRunner._makeResult() method.""" 276 277 return GuiTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag)
278