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-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 self.stream.write(' %7.2f s for %s\n' % (-self.time, test_name))
192 193 194
195 -class GuiTestResult(RelaxTestResult):
196 """A replacement for the TextTestResult class for the GUI.""" 197
198 - def stopTest(self, test):
199 """Override of the RelaxTestResult.stopTest() method. 200 201 The end of STDOUT and STDERR capture occurs here. 202 """ 203 204 # Execute the RelaxTestResult.stopTest() method. 205 super(GuiTestResult, self).stopTest(test) 206 207 # Yield to allow the GUI to be updated. 208 wx.GetApp().Yield(True)
209 210 211
212 -class RelaxTestRunner(TextTestRunner):
213 """A replacement unittest runner. 214 215 This runner is designed to catch STDOUT during the execution of each test and to prepend the 216 output to the failure and error reports normally generated by TextTestRunner. 217 """ 218 219 # Variable for specifying the type of test being performed, to change the printout. 220 category = None 221
222 - def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False):
223 """Initialise the class, storing the timing flag. 224 225 @keyword timing: A flag which if True will enable timing of individual tests. 226 @type timing: bool 227 """ 228 229 # Execute the base method (with different Python version compatibility). 230 if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6): 231 super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity) 232 else: 233 super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass) 234 235 # Store the flag. 236 self.timing_flag = timing
237 238
239 - def _makeResult(self):
240 """Override of the TextTestRunner._makeResult() method.""" 241 242 return RelaxTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag, category=self.category)
243 244 245
246 -class GuiTestRunner(TextTestRunner):
247 """A replacement unittest runner. 248 249 This runner is designed to catch STDOUT during the execution of each test and to prepend the 250 output to the failure and error reports normally generated by TextTestRunner. 251 """ 252
253 - def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False):
254 """Initialise the class, storing the timing flag. 255 256 @keyword timing: A flag which if True will enable timing of individual tests. 257 @type timing: bool 258 """ 259 260 # Execute the base method. 261 if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6): 262 super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity) 263 else: 264 super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass) 265 266 # Store the flag. 267 self.timing_flag = timing
268 269
270 - def _makeResult(self):
271 """Override of the TextTestRunner._makeResult() method.""" 272 273 return GuiTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag)
274