blob: 041814d0ea8a0318d2f2d36903b67241362ba58f [file] [log] [blame]
Guilherme Polocda93aa2009-01-28 13:09:03 +00001"""
2Use this module to get and run all tk tests.
3
4Tkinter tests should live in a package inside the directory where this file
5lives, like test_tkinter.
6Extensions also should live in packages following the same rule as above.
7"""
8
9import os
10import sys
11import unittest
Guilherme Polob98cb432009-02-02 20:28:59 +000012import importlib
Ned Deily46268c42011-07-03 21:52:35 -070013import subprocess
Guilherme Polocda93aa2009-01-28 13:09:03 +000014import test.test_support
15
16this_dir_path = os.path.abspath(os.path.dirname(__file__))
17
Ned Deily46268c42011-07-03 21:52:35 -070018_tk_available = None
19
20def check_tk_availability():
21 """Check that Tk is installed and available."""
22 global _tk_available
23
24 if _tk_available is not None:
25 return
26
27 if sys.platform == 'darwin':
28 # The Aqua Tk implementations on OS X can abort the process if
29 # being called in an environment where a window server connection
30 # cannot be made, for instance when invoked by a buildbot or ssh
31 # process not running under the same user id as the current console
32 # user. Instead, try to initialize Tk under a subprocess.
33 p = subprocess.Popen(
34 [sys.executable, '-c', 'import Tkinter; Tkinter.Button()'],
35 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
36 stderr = test.test_support.strip_python_stderr(p.communicate()[1])
37 if stderr or p.returncode:
38 raise unittest.SkipTest("tk cannot be initialized: %s" % stderr)
39 else:
40 try:
41 Tkinter.Button()
42 except tkinter.TclError as msg:
43 # assuming tk is not available
44 raise unittest.SkipTest("tk not available: %s" % msg)
45
46 _tk_available = True
47 return
48
Guilherme Polocda93aa2009-01-28 13:09:03 +000049def is_package(path):
50 for name in os.listdir(path):
51 if name in ('__init__.py', '__init__.pyc', '__init.pyo'):
52 return True
53 return False
54
Guilherme Polo6785cf02009-01-28 19:23:28 +000055def get_tests_modules(basepath=this_dir_path, gui=True, packages=None):
Guilherme Polocda93aa2009-01-28 13:09:03 +000056 """This will import and yield modules whose names start with test_
Guilherme Polo6785cf02009-01-28 19:23:28 +000057 and are inside packages found in the path starting at basepath.
58
59 If packages is specified it should contain package names that want
60 their tests colleted.
61 """
Guilherme Polocda93aa2009-01-28 13:09:03 +000062 py_ext = '.py'
63
64 for dirpath, dirnames, filenames in os.walk(basepath):
65 for dirname in list(dirnames):
66 if dirname[0] == '.':
67 dirnames.remove(dirname)
68
69 if is_package(dirpath) and filenames:
70 pkg_name = dirpath[len(basepath) + len(os.sep):].replace('/', '.')
Guilherme Polo6785cf02009-01-28 19:23:28 +000071 if packages and pkg_name not in packages:
72 continue
73
Guilherme Polocda93aa2009-01-28 13:09:03 +000074 filenames = filter(
75 lambda x: x.startswith('test_') and x.endswith(py_ext),
76 filenames)
77
78 for name in filenames:
79 try:
Guilherme Polob98cb432009-02-02 20:28:59 +000080 yield importlib.import_module(
81 ".%s" % name[:-len(py_ext)], pkg_name)
Guilherme Polocda93aa2009-01-28 13:09:03 +000082 except test.test_support.ResourceDenied:
83 if gui:
84 raise
85
Guilherme Polo6785cf02009-01-28 19:23:28 +000086def get_tests(text=True, gui=True, packages=None):
Guilherme Polocda93aa2009-01-28 13:09:03 +000087 """Yield all the tests in the modules found by get_tests_modules.
88
89 If nogui is True, only tests that do not require a GUI will be
90 returned."""
91 attrs = []
92 if text:
93 attrs.append('tests_nogui')
94 if gui:
95 attrs.append('tests_gui')
Guilherme Polo6785cf02009-01-28 19:23:28 +000096 for module in get_tests_modules(gui=gui, packages=packages):
Guilherme Polocda93aa2009-01-28 13:09:03 +000097 for attr in attrs:
98 for test in getattr(module, attr, ()):
99 yield test
100
101if __name__ == "__main__":
102 test.test_support.use_resources = ['gui']
103 test.test_support.run_unittest(*get_tests())