Changeset 17

Show
Ignore:
Timestamp:
Wed Mar 29 21:42:57 2006
Author:
jpellerin
Message:
  • Fix for #29 (loader incorrectly tried to load non-module dir in package as module)
  • Implement #30 (plugins now get capt arg in addError and addFailure)
  • Work on #25 (options added for profiler output control; options for profile data file and output to desired stream still needed)


Files:

Legend:

Unmodified
Added
Removed
Modified
  • trunk/nose/plugins/base.py

    r15 r17  
    159 159         pass  
    160 160  
    161       def addError(self, test, err):  
      161     def addError(self, test, err, capt):  
    161 161         """Called when a test raises an uncaught exception. DO NOT return a  
    162 162         value unless you want to stop other plugins from seeing that the  
     
    169 169          * err:  
    170 170            sys.exc_info() tuple  
      171          * capt:  
      172            Captured output, if any  
    171 173         """  
    172 174         pass  
    173 175  
    174       def addFailure(self, test, err, tb_info):  
      176     def addFailure(self, test, err, capt, tb_info):  
    174 176         """Called when a test fails. DO NOT return a value unless you  
    175 177         want to stop other plugins from seeing that the test has failed.  
     
    181 183          * err:  
    182 184            sys.exc_info() tuple  
      185          * capt:  
      186            Captured output, if any  
    183 187          * tb_info:  
    184 188            Introspected traceback info, if any  
  • trunk/nose/plugins/profile.py

    r14 r17  
    1 1 """FIXME module docs  
      2  
      3 FIXME change module name to profiler to avoid conflict w/builtin profile.py  
    2 4 """  
    3 5  
    4 6 import hotshot, hotshot.stats  
      7 import logging  
      8 import os  
    5 9 from nose.plugins.base import Plugin  
    6 10  
      11 log = logging.getLogger('nose.plugins')  
      12  
    7 13 class Profile(Plugin):  
    8 14     """FIXME usage help  
    9 15     """  
    10       # FIXME formatting options -- sort, restrict func names, % of list  
    11       # FIXME prof data filename option  
    12       # FIXME print/no print report  
      16     def add_options(self, parser, env=os.environ):  
      17         super(Profile, self).add_options(parser, env)                 
      18         parser.add_option('--profile-sort',action='store',dest='profile_sort',  
      19                           default=env.get('NOSE_PROFILE_SORT','cumulative'),  
      20                           help="Set sort order for profiler output")  
      21         parser.add_option('--profile-stats-file',action='store',  
      22                           dest='profile_stats_file',  
      23                           default=env.get('NOSE_PROFILE_STATS_FILE'),  
      24                           help='Profiler stats file; default is a new'  
      25                           'temp file on each run')  
      26         parser.add_option('--profile-restrict',action='append',  
      27                           dest='profile_restrict',  
      28                           default=env.get('NOSE_PROFILE_RESTRICT'),  
      29                           help="Restrict profiler output. See help for "  
      30                           "pstats.stats for details")  
    13 31      
    14 32     def begin(self):  
    15           self.pfile = 'nosetests.prof'  
    16 33         self.prof = hotshot.Profile(self.pfile)  
    17 34  
      35     def configure(self, options, conf):  
      36         super(Profile, self).configure(options, conf)  
      37         self.options = options  
      38         self.conf = conf  
      39  
      40         if options.profile_stats_file:  
      41             self.pfile = options.profile_stats_file  
      42         else:  
      43             # FIXME use a temp file  
      44             self.pfile = 'FIXME'  
      45         self.sort = options.profile_sort  
      46         self.restrict = self.tolist(options.profile_restrict)  
      47              
    18 48     def prepareTest(self, test):  
      49         log.debug('preparing test %s' % test)  
    19 50         def run_and_profile(result, prof=self.prof, test=test):  
    20 51             prof.runcall(test, result)  
     
    22 53          
    23 54     def report(self, stream):  
    24           # FIXME sort  
    25           # FIXME how to print to the stream?  
    26           # FIXME only if wanted  
    27    
    28           self.pct = 10  
    29            
      55         log.debug('printing profiler report')  
    30 56         self.prof.close()  
    31 57         stats = hotshot.stats.load(self.pfile)  
    32           stats.print_stats(self.pct)  
      58         stats.sort_stats(self.sort)  
      59         # FIXME capt. stdout, redirect to stream  
      60         stats.print_stats(*self.restrict)  
  • trunk/nose/result.py

    r15 r17  
    60 60             self.addSkip(test)  
    61 61         else:  
      62             capt = buffer.getvalue()  
    62 63             if self.conf.debugErrors:  
    63 64                 if self.capture:  
     
    68 69             self.errors.append((test,  
    69 70                                 self._exc_info_to_string(err, test),  
    70                                   buffer.getvalue()))  
      71                                 capt))  
    70 71             self.resetBuffer()  
    71 72             self.writeRes('ERROR','E')  
    72               call_plugins(self.conf.plugins, 'addError', test, err)  
      73             call_plugins(self.conf.plugins, 'addError', test, err, capt)  
    72 73              
    73 74     def addFailure(self, test, err):  
      75         capt = buffer.getvalue()  
    74 76         if self.conf.debugFailures:  
    75 77             if self.capture:  
     
    89 91         self.failures.append((test,  
    90 92                               self._exc_info_to_string(err, test) + tb,  
    91                                 buffer.getvalue()))  
      93                               capt))  
    91 93         self.resetBuffer()  
    92 94         self.writeRes('FAIL','F')  
    93           call_plugins(self.conf.plugins, 'addFailure', test, err, tb)  
      95         call_plugins(self.conf.plugins, 'addFailure', test, err, capt, tb)  
    93 95          
    94 96     def addSkip(self, test):  
  • trunk/nose/loader.py

    r15 r17  
    1 1 import logging  
    2 2 import os  
      3 import sys  
    3 4 import types  
    4 5 import unittest  
    5 6  
    6   from nose.selector import defaultSelector  
      7 from nose.case import *  
    6 7 from nose.config import Config  
    7 8 from nose.plugins import call_plugins  
      9 from nose.selector import defaultSelector  
    8 10 from nose.suite import LazySuite, TestClass, TestModule  
    9 11 from nose.util import split_test_name, try_run  
     
    12 14 log = logging.getLogger(__name__)  
    13 15  
    14   class FunctionTestCase(unittest.TestCase):  
    15       """TestCase wrapper for functional tests.  
    16    
    17       Don't use this class directly; it is used internally in nose to  
    18       create test cases for functional tests.  
    19        
    20       This class is very similar to unittest.FunctionTestCase, with a few  
    21       extensions:  
    22         * It descends from nose.TestCase, and so provides output  
    23           capture  
    24         * It allows setup and teardown functions to be defined as attributes  
    25           of the test function. A convenient way to set this up is via the  
    26           provided with_setup decorator:  
    27    
    28           def setup_func():  
    29               # ...  
    30    
    31           def teardown_func():  
    32               # ...  
    33            
    34           @with_setup(setup_func, teardown_func)         
    35           def test_something():  
    36               # ...  
    37    
    38       """  
    39       def __init__(self, testFunc, setUp=None, tearDown=None, description=None,  
    40                    fromDirectory=None):  
    41           super(FunctionTestCase, self).__init__()  
    42           self.testFunc = testFunc  
    43           self.setUpFunc = setUp  
    44           self.tearDownFunc = tearDown  
    45           self.description = description  
    46           self.fromDirectory = fromDirectory  
    47    
    48       def id(self):  
    49           name = self.testFunc.__name__  
    50           if self.fromDirectory is None:  
    51               return name  
    52           else:  
    53               return "%s: %s" % (self.fromDirectory, name)  
    54        
    55       def runTest(self):  
    56           self.testFunc()  
    57            
    58       def setUp(self):  
    59           """Run any setup function attached to the test function  
    60           """  
    61           if self.setUpFunc:  
    62               self.setUpFunc()  
    63           else:  
    64               names = ('setup', 'setUp', 'setUpFunc')  
    65               try_run(self.testFunc, names)  
    66    
    67       def tearDown(self):  
    68           """Run any teardown function attached to the test function  
    69           """  
    70           if self.tearDownFunc:  
    71               self.tearDownFunc()  
    72           else:  
    73               names = ('teardown', 'tearDown', 'tearDownFunc')  
    74               try_run(self.testFunc, names)  
    75            
    76       def __str__(self):  
    77           if hasattr(self.testFunc, 'compat_func_name'):  
    78               name = self.testFunc.compat_func_name  
    79           else:  
    80               name = self.testFunc.__name__  
    81           name = "%s.%s" % (self.testFunc.__module__, name)  
    82           if self.fromDirectory is None:  
    83               return name  
    84           else:  
    85               return "%s: %s" % (self.fromDirectory, name)  
    86       __repr__ = __str__  
    87        
    88       def shortDescription(self):  
    89           pass # FIXME  
    90    
    91            
    92   class MethodTestCase(unittest.TestCase):  
    93       """Test case that wraps one method in a test class.  
    94       """  
    95       def __init__(self, cls, method):  
    96           self.cls = cls  
    97           self.method = method  
    98           self.testInstance = self.cls()  
    99           self.testCase = getattr(self.testInstance, self.method)         
    100           super(MethodTestCase, self).__init__()  
    101            
    102       def __str__(self):  
    103           return self.id()  
    104            
    105       def id(self):  
    106           return "%s.%s.%s" % (self.cls.__module__,  
    107                                self.cls.__name__,  
    108                                self.method)  
    109    
    110       def setUp(self):  
    111           """Run any setup method declared in the test class to which this  
    112           method belongs  
    113           """  
    114           names = ('setup', 'setUp')  
    115           try_run(self.testInstance, names)  
    116    
    117       def runTest(self):  
    118           self.testCase()  
    119            
    120       def tearDown(self):  
    121           """Run any teardown method declared in the test class to which  
    122           this method belongs  
    123           """  
    124           if self.testInstance is not None:  
    125               names = ('teardown', 'tearDown')  
    126               try_run(self.testInstance, names)  
    127    
    128       def shortDescription(self):  
    129           # FIXME ... diff output if is TestCase subclass, for back compat  
    130           if self.testCase.__doc__ is not None:             
    131               return '(%s.%s) "%s"' % (self.cls.__module__,  
    132                                        self.cls.__name__,  
    133                                        self.testCase.__doc__)  
    134           return None  
    135    
    136 16      
    137 17 class TestLoader(unittest.TestLoader):  
     
    182 62         """Load tests from module at (optional) import path.  
    183 63         """  
    184           log.debug("load from module %s" % module)  
      64         log.debug("load from module %s (%s)", module, importPath)  
    184 64         tests = []  
    185 65         if self.selector.wantModuleTests(module):  
     
    262 142                                                        importPath=importPath)  
    263 143                     else:  
    264                           tests = self.loadTestsFromDir(path,  
    265                                                         package=package,  
    266                                                         importPath=importPath)  
      144                         # dirs inside of packages don't belong to the  
      145                         # package, so package and importPath are not passed  
      146                         tests = self.loadTestsFromDir(path)  
    267 147             else:  
    268 148                 # ignore non-file, non-path item  
     
    380 260                     continue  
    381 261                 # might be a generator  
    382                   # FIXME LazySuite w/ generate...  
      262                 # FIXME LazySuite w/ generate...?  
    382 262                 if self.isGenerator(test):  
    383 263                     func_tests.extend(self.generateTests(test))  
  • trunk/st/unit_tests/test_collector.py

    r14 r17  
    47 47                    'test module foo.bar in %s' % c.where,  
    48 48                    'test module foo.test_foo in %s' % c.where,  
      49                    'test module dir_test_file in %s/foo/tests' % c.where,  
    49 50                    'test module test in %s/test-dir' % c.where,  
    50 51                    'test module test in %s' % c.where,  
  • trunk/examples/html_plugin/htmlplug.py

    r15 r17  
    30 30         self.html.append('<span>DEPRECATED</span>')  
    31 31  
    32       def addError(self, test, err):  
      32     def addError(self, test, err, capt):  
    32 32         err = self.formatErr(err)  
    33 33         self.html.append('<span>ERROR</span>')  
    34 34         self.html.append('<pre>%s</pre>' % err)  
    35            
    36       def addFailure(self, test, err, tb_info):  
      35         if capt:  
      36             self.html.append('<pre>%s</pre>' % capt)  
      37     def addFailure(self, test, err, capt, tb_info):  
    37 38         err = self.formatErr(err)  
    38 39         self.html.append('<span>FAIL</span>')  
     
    41 42         if tb_info:  
    42 43             self.html.append('<pre>%s</pre>' % tb_info)  
      44         if capt:  
      45             self.html.append('<pre>%s</pre>' % capt)  
    43 46  
    44 47     def finalize(self, result):