python (3.11.7)

(root)/
lib/
python3.11/
unittest/
test/
test_program.py
       1  import io
       2  
       3  import os
       4  import sys
       5  import subprocess
       6  from test import support
       7  import unittest
       8  import unittest.test
       9  from unittest.test.test_result import BufferedWriter
      10  
      11  
      12  class ESC[4;38;5;81mTest_TestProgram(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      13  
      14      def test_discovery_from_dotted_path(self):
      15          loader = unittest.TestLoader()
      16  
      17          tests = [self]
      18          expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__))
      19  
      20          self.wasRun = False
      21          def _find_tests(start_dir, pattern):
      22              self.wasRun = True
      23              self.assertEqual(start_dir, expectedPath)
      24              return tests
      25          loader._find_tests = _find_tests
      26          suite = loader.discover('unittest.test')
      27          self.assertTrue(self.wasRun)
      28          self.assertEqual(suite._tests, tests)
      29  
      30      # Horrible white box test
      31      def testNoExit(self):
      32          result = object()
      33          test = object()
      34  
      35          class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
      36              def run(self, test):
      37                  self.test = test
      38                  return result
      39  
      40          runner = FakeRunner()
      41  
      42          oldParseArgs = unittest.TestProgram.parseArgs
      43          def restoreParseArgs():
      44              unittest.TestProgram.parseArgs = oldParseArgs
      45          unittest.TestProgram.parseArgs = lambda *args: None
      46          self.addCleanup(restoreParseArgs)
      47  
      48          def removeTest():
      49              del unittest.TestProgram.test
      50          unittest.TestProgram.test = test
      51          self.addCleanup(removeTest)
      52  
      53          program = unittest.TestProgram(testRunner=runner, exit=False, verbosity=2)
      54  
      55          self.assertEqual(program.result, result)
      56          self.assertEqual(runner.test, test)
      57          self.assertEqual(program.verbosity, 2)
      58  
      59      class ESC[4;38;5;81mFooBar(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      60          def testPass(self):
      61              pass
      62          def testFail(self):
      63              raise AssertionError
      64          def testError(self):
      65              1/0
      66          @unittest.skip('skipping')
      67          def testSkipped(self):
      68              raise AssertionError
      69          @unittest.expectedFailure
      70          def testExpectedFailure(self):
      71              raise AssertionError
      72          @unittest.expectedFailure
      73          def testUnexpectedSuccess(self):
      74              pass
      75  
      76      class ESC[4;38;5;81mFooBarLoader(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestLoader):
      77          """Test loader that returns a suite containing FooBar."""
      78          def loadTestsFromModule(self, module):
      79              return self.suiteClass(
      80                  [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
      81  
      82          def loadTestsFromNames(self, names, module):
      83              return self.suiteClass(
      84                  [self.loadTestsFromTestCase(Test_TestProgram.FooBar)])
      85  
      86      def test_defaultTest_with_string(self):
      87          class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
      88              def run(self, test):
      89                  self.test = test
      90                  return True
      91  
      92          old_argv = sys.argv
      93          sys.argv = ['faketest']
      94          runner = FakeRunner()
      95          program = unittest.TestProgram(testRunner=runner, exit=False,
      96                                         defaultTest='unittest.test',
      97                                         testLoader=self.FooBarLoader())
      98          sys.argv = old_argv
      99          self.assertEqual(('unittest.test',), program.testNames)
     100  
     101      def test_defaultTest_with_iterable(self):
     102          class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
     103              def run(self, test):
     104                  self.test = test
     105                  return True
     106  
     107          old_argv = sys.argv
     108          sys.argv = ['faketest']
     109          runner = FakeRunner()
     110          program = unittest.TestProgram(
     111              testRunner=runner, exit=False,
     112              defaultTest=['unittest.test', 'unittest.test2'],
     113              testLoader=self.FooBarLoader())
     114          sys.argv = old_argv
     115          self.assertEqual(['unittest.test', 'unittest.test2'],
     116                            program.testNames)
     117  
     118      def test_NonExit(self):
     119          stream = BufferedWriter()
     120          program = unittest.main(exit=False,
     121                                  argv=["foobar"],
     122                                  testRunner=unittest.TextTestRunner(stream=stream),
     123                                  testLoader=self.FooBarLoader())
     124          self.assertTrue(hasattr(program, 'result'))
     125          out = stream.getvalue()
     126          self.assertIn('\nFAIL: testFail ', out)
     127          self.assertIn('\nERROR: testError ', out)
     128          self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
     129          expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
     130                      'expected failures=1, unexpected successes=1)\n')
     131          self.assertTrue(out.endswith(expected))
     132  
     133      def test_Exit(self):
     134          stream = BufferedWriter()
     135          self.assertRaises(
     136              SystemExit,
     137              unittest.main,
     138              argv=["foobar"],
     139              testRunner=unittest.TextTestRunner(stream=stream),
     140              exit=True,
     141              testLoader=self.FooBarLoader())
     142          out = stream.getvalue()
     143          self.assertIn('\nFAIL: testFail ', out)
     144          self.assertIn('\nERROR: testError ', out)
     145          self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
     146          expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
     147                      'expected failures=1, unexpected successes=1)\n')
     148          self.assertTrue(out.endswith(expected))
     149  
     150      def test_ExitAsDefault(self):
     151          stream = BufferedWriter()
     152          self.assertRaises(
     153              SystemExit,
     154              unittest.main,
     155              argv=["foobar"],
     156              testRunner=unittest.TextTestRunner(stream=stream),
     157              testLoader=self.FooBarLoader())
     158          out = stream.getvalue()
     159          self.assertIn('\nFAIL: testFail ', out)
     160          self.assertIn('\nERROR: testError ', out)
     161          self.assertIn('\nUNEXPECTED SUCCESS: testUnexpectedSuccess ', out)
     162          expected = ('\n\nFAILED (failures=1, errors=1, skipped=1, '
     163                      'expected failures=1, unexpected successes=1)\n')
     164          self.assertTrue(out.endswith(expected))
     165  
     166  
     167  class ESC[4;38;5;81mInitialisableProgram(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestProgram):
     168      exit = False
     169      result = None
     170      verbosity = 1
     171      defaultTest = None
     172      tb_locals = False
     173      testRunner = None
     174      testLoader = unittest.defaultTestLoader
     175      module = '__main__'
     176      progName = 'test'
     177      test = 'test'
     178      def __init__(self, *args):
     179          pass
     180  
     181  RESULT = object()
     182  
     183  class ESC[4;38;5;81mFakeRunner(ESC[4;38;5;149mobject):
     184      initArgs = None
     185      test = None
     186      raiseError = 0
     187  
     188      def __init__(self, **kwargs):
     189          FakeRunner.initArgs = kwargs
     190          if FakeRunner.raiseError:
     191              FakeRunner.raiseError -= 1
     192              raise TypeError
     193  
     194      def run(self, test):
     195          FakeRunner.test = test
     196          return RESULT
     197  
     198  
     199  @support.requires_subprocess()
     200  class ESC[4;38;5;81mTestCommandLineArgs(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     201  
     202      def setUp(self):
     203          self.program = InitialisableProgram()
     204          self.program.createTests = lambda: None
     205          FakeRunner.initArgs = None
     206          FakeRunner.test = None
     207          FakeRunner.raiseError = 0
     208  
     209      def testVerbosity(self):
     210          program = self.program
     211  
     212          for opt in '-q', '--quiet':
     213              program.verbosity = 1
     214              program.parseArgs([None, opt])
     215              self.assertEqual(program.verbosity, 0)
     216  
     217          for opt in '-v', '--verbose':
     218              program.verbosity = 1
     219              program.parseArgs([None, opt])
     220              self.assertEqual(program.verbosity, 2)
     221  
     222      def testBufferCatchFailfast(self):
     223          program = self.program
     224          for arg, attr in (('buffer', 'buffer'), ('failfast', 'failfast'),
     225                        ('catch', 'catchbreak')):
     226  
     227              setattr(program, attr, None)
     228              program.parseArgs([None])
     229              self.assertIs(getattr(program, attr), False)
     230  
     231              false = []
     232              setattr(program, attr, false)
     233              program.parseArgs([None])
     234              self.assertIs(getattr(program, attr), false)
     235  
     236              true = [42]
     237              setattr(program, attr, true)
     238              program.parseArgs([None])
     239              self.assertIs(getattr(program, attr), true)
     240  
     241              short_opt = '-%s' % arg[0]
     242              long_opt = '--%s' % arg
     243              for opt in short_opt, long_opt:
     244                  setattr(program, attr, None)
     245                  program.parseArgs([None, opt])
     246                  self.assertIs(getattr(program, attr), True)
     247  
     248                  setattr(program, attr, False)
     249                  with support.captured_stderr() as stderr, \
     250                      self.assertRaises(SystemExit) as cm:
     251                      program.parseArgs([None, opt])
     252                  self.assertEqual(cm.exception.args, (2,))
     253  
     254                  setattr(program, attr, True)
     255                  with support.captured_stderr() as stderr, \
     256                      self.assertRaises(SystemExit) as cm:
     257                      program.parseArgs([None, opt])
     258                  self.assertEqual(cm.exception.args, (2,))
     259  
     260      def testWarning(self):
     261          """Test the warnings argument"""
     262          # see #10535
     263          class ESC[4;38;5;81mFakeTP(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestProgram):
     264              def parseArgs(self, *args, **kw): pass
     265              def runTests(self, *args, **kw): pass
     266          warnoptions = sys.warnoptions[:]
     267          try:
     268              sys.warnoptions[:] = []
     269              # no warn options, no arg -> default
     270              self.assertEqual(FakeTP().warnings, 'default')
     271              # no warn options, w/ arg -> arg value
     272              self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
     273              sys.warnoptions[:] = ['somevalue']
     274              # warn options, no arg -> None
     275              # warn options, w/ arg -> arg value
     276              self.assertEqual(FakeTP().warnings, None)
     277              self.assertEqual(FakeTP(warnings='ignore').warnings, 'ignore')
     278          finally:
     279              sys.warnoptions[:] = warnoptions
     280  
     281      def testRunTestsRunnerClass(self):
     282          program = self.program
     283  
     284          program.testRunner = FakeRunner
     285          program.verbosity = 'verbosity'
     286          program.failfast = 'failfast'
     287          program.buffer = 'buffer'
     288          program.warnings = 'warnings'
     289  
     290          program.runTests()
     291  
     292          self.assertEqual(FakeRunner.initArgs, {'verbosity': 'verbosity',
     293                                                  'failfast': 'failfast',
     294                                                  'buffer': 'buffer',
     295                                                  'tb_locals': False,
     296                                                  'warnings': 'warnings'})
     297          self.assertEqual(FakeRunner.test, 'test')
     298          self.assertIs(program.result, RESULT)
     299  
     300      def testRunTestsRunnerInstance(self):
     301          program = self.program
     302  
     303          program.testRunner = FakeRunner()
     304          FakeRunner.initArgs = None
     305  
     306          program.runTests()
     307  
     308          # A new FakeRunner should not have been instantiated
     309          self.assertIsNone(FakeRunner.initArgs)
     310  
     311          self.assertEqual(FakeRunner.test, 'test')
     312          self.assertIs(program.result, RESULT)
     313  
     314      def test_locals(self):
     315          program = self.program
     316  
     317          program.testRunner = FakeRunner
     318          program.parseArgs([None, '--locals'])
     319          self.assertEqual(True, program.tb_locals)
     320          program.runTests()
     321          self.assertEqual(FakeRunner.initArgs, {'buffer': False,
     322                                                 'failfast': False,
     323                                                 'tb_locals': True,
     324                                                 'verbosity': 1,
     325                                                 'warnings': None})
     326  
     327      def testRunTestsOldRunnerClass(self):
     328          program = self.program
     329  
     330          # Two TypeErrors are needed to fall all the way back to old-style
     331          # runners - one to fail tb_locals, one to fail buffer etc.
     332          FakeRunner.raiseError = 2
     333          program.testRunner = FakeRunner
     334          program.verbosity = 'verbosity'
     335          program.failfast = 'failfast'
     336          program.buffer = 'buffer'
     337          program.test = 'test'
     338  
     339          program.runTests()
     340  
     341          # If initialising raises a type error it should be retried
     342          # without the new keyword arguments
     343          self.assertEqual(FakeRunner.initArgs, {})
     344          self.assertEqual(FakeRunner.test, 'test')
     345          self.assertIs(program.result, RESULT)
     346  
     347      def testCatchBreakInstallsHandler(self):
     348          module = sys.modules['unittest.main']
     349          original = module.installHandler
     350          def restore():
     351              module.installHandler = original
     352          self.addCleanup(restore)
     353  
     354          self.installed = False
     355          def fakeInstallHandler():
     356              self.installed = True
     357          module.installHandler = fakeInstallHandler
     358  
     359          program = self.program
     360          program.catchbreak = True
     361  
     362          program.testRunner = FakeRunner
     363  
     364          program.runTests()
     365          self.assertTrue(self.installed)
     366  
     367      def _patch_isfile(self, names, exists=True):
     368          def isfile(path):
     369              return path in names
     370          original = os.path.isfile
     371          os.path.isfile = isfile
     372          def restore():
     373              os.path.isfile = original
     374          self.addCleanup(restore)
     375  
     376  
     377      def testParseArgsFileNames(self):
     378          # running tests with filenames instead of module names
     379          program = self.program
     380          argv = ['progname', 'foo.py', 'bar.Py', 'baz.PY', 'wing.txt']
     381          self._patch_isfile(argv)
     382  
     383          program.createTests = lambda: None
     384          program.parseArgs(argv)
     385  
     386          # note that 'wing.txt' is not a Python file so the name should
     387          # *not* be converted to a module name
     388          expected = ['foo', 'bar', 'baz', 'wing.txt']
     389          self.assertEqual(program.testNames, expected)
     390  
     391  
     392      def testParseArgsFilePaths(self):
     393          program = self.program
     394          argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
     395          self._patch_isfile(argv)
     396  
     397          program.createTests = lambda: None
     398          program.parseArgs(argv)
     399  
     400          expected = ['foo.bar.baz', 'green.red']
     401          self.assertEqual(program.testNames, expected)
     402  
     403  
     404      def testParseArgsNonExistentFiles(self):
     405          program = self.program
     406          argv = ['progname', 'foo/bar/baz.py', 'green\\red.py']
     407          self._patch_isfile([])
     408  
     409          program.createTests = lambda: None
     410          program.parseArgs(argv)
     411  
     412          self.assertEqual(program.testNames, argv[1:])
     413  
     414      def testParseArgsAbsolutePathsThatCanBeConverted(self):
     415          cur_dir = os.getcwd()
     416          program = self.program
     417          def _join(name):
     418              return os.path.join(cur_dir, name)
     419          argv = ['progname', _join('foo/bar/baz.py'), _join('green\\red.py')]
     420          self._patch_isfile(argv)
     421  
     422          program.createTests = lambda: None
     423          program.parseArgs(argv)
     424  
     425          expected = ['foo.bar.baz', 'green.red']
     426          self.assertEqual(program.testNames, expected)
     427  
     428      def testParseArgsAbsolutePathsThatCannotBeConverted(self):
     429          program = self.program
     430          # even on Windows '/...' is considered absolute by os.path.abspath
     431          argv = ['progname', '/foo/bar/baz.py', '/green/red.py']
     432          self._patch_isfile(argv)
     433  
     434          program.createTests = lambda: None
     435          program.parseArgs(argv)
     436  
     437          self.assertEqual(program.testNames, argv[1:])
     438  
     439          # it may be better to use platform specific functions to normalise paths
     440          # rather than accepting '.PY' and '\' as file separator on Linux / Mac
     441          # it would also be better to check that a filename is a valid module
     442          # identifier (we have a regex for this in loader.py)
     443          # for invalid filenames should we raise a useful error rather than
     444          # leaving the current error message (import of filename fails) in place?
     445  
     446      def testParseArgsSelectedTestNames(self):
     447          program = self.program
     448          argv = ['progname', '-k', 'foo', '-k', 'bar', '-k', '*pat*']
     449  
     450          program.createTests = lambda: None
     451          program.parseArgs(argv)
     452  
     453          self.assertEqual(program.testNamePatterns, ['*foo*', '*bar*', '*pat*'])
     454  
     455      def testSelectedTestNamesFunctionalTest(self):
     456          def run_unittest(args):
     457              # Use -E to ignore PYTHONSAFEPATH env var
     458              cmd = [sys.executable, '-E', '-m', 'unittest'] + args
     459              p = subprocess.Popen(cmd,
     460                  stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__))
     461              with p:
     462                  _, stderr = p.communicate()
     463              return stderr.decode()
     464  
     465          t = '_test_warnings'
     466          self.assertIn('Ran 7 tests', run_unittest([t]))
     467          self.assertIn('Ran 7 tests', run_unittest(['-k', 'TestWarnings', t]))
     468          self.assertIn('Ran 7 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings']))
     469          self.assertIn('Ran 2 tests', run_unittest(['-k', 'f', t]))
     470          self.assertIn('Ran 7 tests', run_unittest(['-k', 't', t]))
     471          self.assertIn('Ran 3 tests', run_unittest(['-k', '*t', t]))
     472          self.assertIn('Ran 7 tests', run_unittest(['-k', '*test_warnings.*Warning*', t]))
     473          self.assertIn('Ran 1 test', run_unittest(['-k', '*test_warnings.*warning*', t]))
     474  
     475  
     476  if __name__ == '__main__':
     477      unittest.main()