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