"Fossies" - the Fresh Open Source Software Archive

Member "relax-5.0.0/test_suite/relax_test_runner.py" (6 Dec 2019, 12893 Bytes) of package /linux/privat/relax-5.0.0.src.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "relax_test_runner.py": 4.1.3_vs_5.0.0.

    1 ###############################################################################
    2 #                                                                             #
    3 # Copyright (C) 2008,2011,2013-2014,2019 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 traceback import print_exception
   28 from unittest import TextTestRunner
   29 if dep_check.wx_module:
   30     import wx
   31 
   32 # relax module imports.
   33 from lib.compat import StringIO
   34 from lib.compat import TextTestResult
   35 from status import Status; status = Status()
   36 from test_suite.formatting import divider, format_test_name, test_title
   37 
   38 
   39 class RelaxTestResult(TextTestResult):
   40     """A replacement for the TextTestResult class.
   41 
   42     This class is designed to catch STDOUT and STDERR during the execution of each test and to
   43     prepend the output to the failure and error reports normally generated by TextTestRunner.
   44     """
   45 
   46     def __init__(self, stream, descriptions, verbosity, category=None, timing=False, io_capture=True):
   47         """Initialise the RelaxTestResult object with relax specific variables.
   48 
   49         @param stream:          The IO stream to write all output to.
   50         @type stream:           writable object
   51         @param descriptions:    A flag which if True will cause the test description to be printed out, when the verbosity is > 1.
   52         @type descriptions:     bool
   53         @param verbosity:       The verbosity level.
   54         @type verbosity:        int
   55         @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'.
   56         @type category:         str
   57         @keyword timing:        A flag which if True will enable timing of individual tests.
   58         @type timing:           bool
   59         @keyword io_capture:    A flag which if True will cause all IO to be captured and only printed out for failing or error tests.
   60         @type io_capture:       bool
   61         """
   62 
   63         # Normal setup.
   64         super(RelaxTestResult, self).__init__(stream, descriptions, verbosity)
   65 
   66         # Store the flags and category.
   67         self.timing_flag = timing
   68         self.io_capture = io_capture
   69         self.category = category
   70 
   71         # Set the separator widths.
   72         self.separator1 = '=' * status.text_width
   73         self.separator2 = '-' * status.text_width
   74 
   75 
   76     def addError(self, test, err):
   77         """Override of the TestResult.addError() method.
   78 
   79         The STDOUT and STDERR captured text is prepended to the error text here.
   80 
   81 
   82         @param test:    The test object.
   83         @type test:     TestCase instance
   84         @param err:     A tuple of values as returned by sys.exc_info().
   85         @type err:      tuple of values
   86         """
   87 
   88         # Extra formatting for no IO capture.
   89         if not self.io_capture:
   90             self.stream.write(self._exc_info_to_string(err, test))
   91             divider('-', width=status.text_width)
   92 
   93         # Execute the base class method to print the 'E' and handle the error.
   94         super(RelaxTestResult, self).addError(test, err)
   95 
   96         # Prepend the STDOUT and STDERR messages to the second element of the tuple.
   97         if self.io_capture:
   98             self.errors[-1] = (self.errors[-1][0], self.capt.getvalue() + self.errors[-1][1])
   99 
  100         # Write out timing info.
  101         if self.timing_flag or not self.io_capture:
  102             self.write_time(test.id())
  103 
  104 
  105     def addFailure(self, test, err):
  106         """Override of the TestResult.addFailure() method.
  107 
  108         The STDOUT and STDERR captured text is prepended to the failure text here.
  109 
  110 
  111         @param test:    The test object.
  112         @type test:     TestCase instance
  113         @param err:     A tuple of values as returned by sys.exc_info().
  114         @type err:      tuple of values
  115         """
  116 
  117         # Extra formatting for no IO capture.
  118         if not self.io_capture:
  119             self.stream.write(self._exc_info_to_string(err, test))
  120             divider('-', width=status.text_width)
  121 
  122         # Execute the base class method to print the 'F' and handle the failure.
  123         super(RelaxTestResult, self).addFailure(test, err)
  124 
  125         # Prepend the STDOUT and STDERR messages to the second element of the tuple.
  126         if self.io_capture:
  127             self.failures[-1] = (self.failures[-1][0], self.capt.getvalue() + self.failures[-1][1])
  128 
  129         # Write out timing info.
  130         if self.timing_flag or  not self.io_capture:
  131             self.write_time(test.id())
  132 
  133 
  134     def addSuccess(self, test):
  135         """The method for a successful test.
  136 
  137         @param test:    The test object.
  138         @type test:     TestCase instance
  139         """
  140 
  141         # Extra formatting for no IO capture.
  142         if not self.io_capture:
  143             divider('-', width=status.text_width)
  144 
  145         # Execute the base class method to print the '.'.
  146         super(RelaxTestResult, self).addSuccess(test)
  147 
  148         # Write out timing info.
  149         if self.timing_flag or not self.io_capture:
  150             self.write_time(test.id())
  151 
  152 
  153     def startTest(self, test):
  154         """Override of the TextTestResult.startTest() method.
  155 
  156         The start of STDOUT and STDERR capture occurs here.
  157         """
  158 
  159         # IO capture.
  160         if self.io_capture:
  161             # Store the original STDOUT and STDERR for restoring later on.
  162             self.orig_stdout = sys.stdout
  163             self.orig_stderr = sys.stderr
  164 
  165             # Catch stdout and stderr.
  166             self.capt = StringIO()
  167             sys.stdout = self.capt
  168             sys.stderr = self.capt
  169 
  170         # No capture.
  171         else:
  172             test_title(format_test_name(test.id()), desc=test.shortDescription(), width=status.text_width)
  173 
  174         # Place the test name in the status object.
  175         status.exec_lock.test_name = str(test)
  176 
  177         # Store the starting time.
  178         if self.timing_flag or not self.io_capture:
  179             self.time = time()
  180 
  181         # Execute the normal startTest method.
  182         super(RelaxTestResult, self).startTest(test)
  183 
  184 
  185     def stopTest(self, test):
  186         """Override of the TextTestResult.stopTest() method.
  187 
  188         The end of STDOUT and STDERR capture occurs here.
  189         """
  190 
  191         # Restore the IO streams.
  192         if self.io_capture:
  193             sys.stdout = self.orig_stdout
  194             sys.stderr = self.orig_stderr
  195 
  196 
  197     def write_time(self, test_name):
  198         """Write the timing of the test to the stream.
  199 
  200         @param test_name:   The TestCase name.
  201         @type test_name:    str
  202         """
  203 
  204         # Subtract the end time from the start time.
  205         self.time -= time()
  206 
  207         # Format the name.
  208         test_name = format_test_name(test_name)
  209 
  210         # The printout.
  211         if self.category == 'unit':
  212             time_str = '%7.2f ms' % (abs(self.time) * 1000)
  213         else:
  214             time_str = '%7.2f s' % abs(self.time)
  215         self.stream.write('  %s for %s\n' % (time_str, test_name))
  216 
  217 
  218 
  219 class GuiTestResult(RelaxTestResult):
  220     """A replacement for the TextTestResult class for the GUI."""
  221 
  222     def stopTest(self, test):
  223         """Override of the RelaxTestResult.stopTest() method.
  224 
  225         The end of STDOUT and STDERR capture occurs here.
  226         """
  227 
  228         # Execute the RelaxTestResult.stopTest() method.
  229         super(GuiTestResult, self).stopTest(test)
  230 
  231         # Yield to allow the GUI to be updated.
  232         wx.GetApp().Yield(True)
  233 
  234 
  235 
  236 class RelaxTestRunner(TextTestRunner):
  237     """A replacement unittest runner.
  238 
  239     This runner is designed to catch STDOUT during the execution of each test and to prepend the
  240     output to the failure and error reports normally generated by TextTestRunner.
  241     """
  242 
  243     # Variable for specifying the type of test being performed, to change the printout.
  244     category = None
  245 
  246     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False, io_capture=True):
  247         """Initialise the class, storing the timing flag.
  248 
  249         @param stream:          The IO stream to write all output to.
  250         @type stream:           writable object
  251         @param descriptions:    A flag which if True will cause the test description to be printed out, when the verbosity is > 1.
  252         @type descriptions:     bool
  253         @param verbosity:       The verbosity level.
  254         @type verbosity:        int
  255         @keyword timing:        A flag which if True will enable timing of individual tests.
  256         @type timing:           bool
  257         @keyword io_capture:    A flag which if True will cause all IO to be captured and only printed out for failing or error tests.
  258         @type io_capture:       bool
  259         """
  260 
  261         # Execute the base method (with different Python version compatibility).
  262         if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6):
  263             super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity)
  264         else:
  265             super(RelaxTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass)
  266 
  267         # Store the flags.
  268         self.timing_flag = timing
  269         self.io_capture = io_capture
  270 
  271 
  272     def _makeResult(self):
  273         """Override of the TextTestRunner._makeResult() method."""
  274 
  275         return RelaxTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag, io_capture=self.io_capture, category=self.category)
  276 
  277 
  278 
  279 class GuiTestRunner(TextTestRunner):
  280     """A replacement unittest runner.
  281 
  282     This runner is designed to catch STDOUT during the execution of each test and to prepend the
  283     output to the failure and error reports normally generated by TextTestRunner.
  284     """
  285 
  286     def __init__(self, stream=sys.stderr, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, timing=False, io_capture=True):
  287         """Initialise the class, storing the timing flag.
  288 
  289         @param stream:          The IO stream to write all output to.
  290         @type stream:           writable object
  291         @param descriptions:    A flag which if True will cause the test description to be printed out, when the verbosity is > 1.
  292         @type descriptions:     bool
  293         @param verbosity:       The verbosity level.
  294         @type verbosity:        int
  295         @keyword timing:        A flag which if True will enable timing of individual tests.
  296         @type timing:           bool
  297         @keyword io_capture:    A flag which if True will cause all IO to be captured and only printed out for failing or error tests.
  298         @type io_capture:       bool
  299         """
  300 
  301         # Execute the base method.
  302         if (sys.version_info[0] == 3 and sys.version_info[1] == 1) or (sys.version_info[0] == 2 and sys.version_info[1] <= 6):
  303             super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity)
  304         else:
  305             super(GuiTestRunner, self).__init__(stream=stream, descriptions=descriptions, verbosity=verbosity, failfast=failfast, buffer=buffer, resultclass=resultclass)
  306 
  307         # Store the flags.
  308         self.timing_flag = timing
  309         self.io_capture = io_capture
  310 
  311 
  312     def _makeResult(self):
  313         """Override of the TextTestRunner._makeResult() method."""
  314 
  315         return GuiTestResult(self.stream, self.descriptions, self.verbosity, timing=self.timing_flag, io_capture=self.io_capture)