Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

testall.py 9.7KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. import getopt
  2. import os
  3. import re
  4. import sys
  5. import traceback
  6. import unittest
  7. try:
  8. this_file = __file__
  9. except NameError:
  10. this_file = sys.argv[0]
  11. win32com_src_dir = os.path.abspath(os.path.join(this_file, "../.."))
  12. import win32com
  13. # We'd prefer the win32com namespace to be the parent of __file__ - ie, our source-tree,
  14. # rather than the version installed - otherwise every .py change needs a full install to
  15. # test!
  16. # We can't patch win32comext as most of them have a .pyd in their root :(
  17. # This clearly ins't ideal or perfect :)
  18. win32com.__path__[0] = win32com_src_dir
  19. import pythoncom
  20. import win32com.client
  21. from win32com.test.util import (
  22. CapturingFunctionTestCase,
  23. CheckClean,
  24. RegisterPythonServer,
  25. ShellTestCase,
  26. TestCase,
  27. TestLoader,
  28. TestRunner,
  29. )
  30. verbosity = 1 # default unittest verbosity.
  31. def GenerateAndRunOldStyle():
  32. from . import GenTestScripts
  33. GenTestScripts.GenerateAll()
  34. try:
  35. pass #
  36. finally:
  37. GenTestScripts.CleanAll()
  38. def CleanGenerated():
  39. import shutil
  40. import win32com
  41. if os.path.isdir(win32com.__gen_path__):
  42. if verbosity > 1:
  43. print("Deleting files from %s" % (win32com.__gen_path__))
  44. shutil.rmtree(win32com.__gen_path__)
  45. import win32com.client.gencache
  46. win32com.client.gencache.__init__() # Reset
  47. def RemoveRefCountOutput(data):
  48. while 1:
  49. last_line_pos = data.rfind("\n")
  50. if not re.match("\[\d+ refs\]", data[last_line_pos + 1 :]):
  51. break
  52. if last_line_pos < 0:
  53. # All the output
  54. return ""
  55. data = data[:last_line_pos]
  56. return data
  57. def ExecuteSilentlyIfOK(cmd, testcase):
  58. f = os.popen(cmd)
  59. data = f.read().strip()
  60. rc = f.close()
  61. if rc:
  62. print(data)
  63. testcase.fail("Executing '%s' failed (%d)" % (cmd, rc))
  64. # for "_d" builds, strip the '[xxx refs]' line
  65. return RemoveRefCountOutput(data)
  66. class PyCOMTest(TestCase):
  67. no_leak_tests = True # done by the test itself
  68. def testit(self):
  69. # Check that the item is registered, so we get the correct
  70. # 'skipped' behaviour (and recorded as such) rather than either
  71. # error or silence due to non-registration.
  72. RegisterPythonServer(
  73. os.path.join(
  74. os.path.dirname(__file__), "..", "servers", "test_pycomtest.py"
  75. ),
  76. "Python.Test.PyCOMTest",
  77. )
  78. # Execute testPyComTest in its own process so it can play
  79. # with the Python thread state
  80. fname = os.path.join(os.path.dirname(this_file), "testPyComTest.py")
  81. cmd = '%s "%s" -q 2>&1' % (sys.executable, fname)
  82. data = ExecuteSilentlyIfOK(cmd, self)
  83. class PippoTest(TestCase):
  84. def testit(self):
  85. # Check we are registered before spawning the process.
  86. from win32com.test import pippo_server
  87. RegisterPythonServer(pippo_server.__file__, "Python.Test.Pippo")
  88. python = sys.executable
  89. fname = os.path.join(os.path.dirname(this_file), "testPippo.py")
  90. cmd = '%s "%s" 2>&1' % (python, fname)
  91. ExecuteSilentlyIfOK(cmd, self)
  92. # This is a list of "win32com.test.???" module names, optionally with a
  93. # function in that module if the module isn't unitest based...
  94. unittest_modules = [
  95. # Level 1 tests - fast and few dependencies - good for CI!
  96. """testIterators testvbscript_regexp testStorage
  97. testStreams testWMI policySemantics testShell testROT
  98. testxslt testCollections
  99. errorSemantics.test testArrays
  100. testClipboard
  101. testConversionErrors
  102. """.split(),
  103. # Level 2 tests - wants our demo COM objects registered.
  104. # (these are strange; on github CI they get further than expected when
  105. # our objects are not installed, so fail to quietly fail with "can't
  106. # register" like they do locally. So really just a nod to CI)
  107. """
  108. testAXScript testDictionary testServers testvb testMarshal
  109. """.split(),
  110. # Level 3 tests - Requires Office or other non-free stuff.
  111. """testMSOffice.TestAll testMSOfficeEvents.test testAccess.test
  112. testExplorer.TestAll testExchange.test
  113. """.split(),
  114. # Level 4 tests - we try and run `makepy` over every typelib installed!
  115. """testmakepy.TestAll
  116. """.split(),
  117. ]
  118. # A list of other unittest modules we use - these are fully qualified module
  119. # names and the module is assumed to be unittest based.
  120. unittest_other_modules = [
  121. # Level 1 tests.
  122. """win32com.directsound.test.ds_test
  123. """.split(),
  124. # Level 2 tests.
  125. [],
  126. # Level 3 tests.
  127. [],
  128. # Level 4 tests.
  129. [],
  130. ]
  131. output_checked_programs = [
  132. # Level 1 tests.
  133. [],
  134. # Level 2 tests.
  135. [
  136. ("cscript.exe /nologo //E:vbscript testInterp.vbs", "VBScript test worked OK"),
  137. (
  138. "cscript.exe /nologo //E:vbscript testDictionary.vbs",
  139. "VBScript has successfully tested Python.Dictionary",
  140. ),
  141. ],
  142. # Level 3 tests
  143. [],
  144. # Level 4 tests.
  145. [],
  146. ]
  147. custom_test_cases = [
  148. # Level 1 tests.
  149. [],
  150. # Level 2 tests.
  151. [
  152. PyCOMTest,
  153. PippoTest,
  154. ],
  155. # Level 3 tests
  156. [],
  157. # Level 4 tests.
  158. [],
  159. ]
  160. def get_test_mod_and_func(test_name, import_failures):
  161. if test_name.find(".") > 0:
  162. mod_name, func_name = test_name.split(".")
  163. else:
  164. mod_name = test_name
  165. func_name = None
  166. fq_mod_name = "win32com.test." + mod_name
  167. try:
  168. __import__(fq_mod_name)
  169. mod = sys.modules[fq_mod_name]
  170. except:
  171. import_failures.append((mod_name, sys.exc_info()[:2]))
  172. return None, None
  173. func = None if func_name is None else getattr(mod, func_name)
  174. return mod, func
  175. # Return a test suite all loaded with the tests we want to run
  176. def make_test_suite(test_level=1):
  177. suite = unittest.TestSuite()
  178. import_failures = []
  179. loader = TestLoader()
  180. for i in range(testLevel):
  181. for mod_name in unittest_modules[i]:
  182. mod, func = get_test_mod_and_func(mod_name, import_failures)
  183. if mod is None:
  184. raise Exception("no such module '{}'".format(mod_name))
  185. if func is not None:
  186. test = CapturingFunctionTestCase(func, description=mod_name)
  187. else:
  188. if hasattr(mod, "suite"):
  189. test = mod.suite()
  190. else:
  191. test = loader.loadTestsFromModule(mod)
  192. assert test.countTestCases() > 0, "No tests loaded from %r" % mod
  193. suite.addTest(test)
  194. for cmd, output in output_checked_programs[i]:
  195. suite.addTest(ShellTestCase(cmd, output))
  196. for test_class in custom_test_cases[i]:
  197. suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(test_class))
  198. # other "normal" unittest modules.
  199. for i in range(testLevel):
  200. for mod_name in unittest_other_modules[i]:
  201. try:
  202. __import__(mod_name)
  203. except:
  204. import_failures.append((mod_name, sys.exc_info()[:2]))
  205. continue
  206. mod = sys.modules[mod_name]
  207. if hasattr(mod, "suite"):
  208. test = mod.suite()
  209. else:
  210. test = loader.loadTestsFromModule(mod)
  211. assert test.countTestCases() > 0, "No tests loaded from %r" % mod
  212. suite.addTest(test)
  213. return suite, import_failures
  214. def usage(why):
  215. print(why)
  216. print()
  217. print("win32com test suite")
  218. print("usage: testall [-v] test_level")
  219. print(" where test_level is an integer 1-3. Level 1 tests are quick,")
  220. print(" level 2 tests invoke Word, IE etc, level 3 take ages!")
  221. sys.exit(1)
  222. if __name__ == "__main__":
  223. try:
  224. opts, args = getopt.getopt(sys.argv[1:], "v")
  225. except getopt.error as why:
  226. usage(why)
  227. for opt, val in opts:
  228. if opt == "-v":
  229. verbosity += 1
  230. testLevel = 2 # default to quick test with local objects
  231. test_names = []
  232. for arg in args:
  233. try:
  234. testLevel = int(arg)
  235. if testLevel < 0 or testLevel > 4:
  236. raise ValueError("Only levels 1-4 are supported")
  237. except ValueError:
  238. test_names.append(arg)
  239. if test_names:
  240. usage("Test names are not supported yet")
  241. CleanGenerated()
  242. suite, import_failures = make_test_suite(testLevel)
  243. if verbosity:
  244. if hasattr(sys, "gettotalrefcount"):
  245. print("This is a debug build - memory leak tests will also be run.")
  246. print("These tests may take *many* minutes to run - be patient!")
  247. print("(running from python.exe will avoid these leak tests)")
  248. print(
  249. "Executing level %d tests - %d test cases will be run"
  250. % (testLevel, suite.countTestCases())
  251. )
  252. if verbosity == 1 and suite.countTestCases() < 70:
  253. # A little row of markers so the dots show how close to finished
  254. print("|" * suite.countTestCases())
  255. testRunner = TestRunner(verbosity=verbosity)
  256. testResult = testRunner.run(suite)
  257. if import_failures:
  258. testResult.stream.writeln(
  259. "*** The following test modules could not be imported ***"
  260. )
  261. for mod_name, (exc_type, exc_val) in import_failures:
  262. desc = "\n".join(traceback.format_exception_only(exc_type, exc_val))
  263. testResult.stream.write("%s: %s" % (mod_name, desc))
  264. testResult.stream.writeln(
  265. "*** %d test(s) could not be run ***" % len(import_failures)
  266. )
  267. # re-print unit-test error here so it is noticed
  268. if not testResult.wasSuccessful():
  269. print("*" * 20, "- unittest tests FAILED")
  270. CheckClean()
  271. pythoncom.CoUninitialize()
  272. CleanGenerated()
  273. if not testResult.wasSuccessful():
  274. sys.exit(1)