diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index cacd06db873d03..242de222524817 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -33,9 +33,9 @@ insert the import and main lines before the htest lines. if __name__ == "__main__": from unittest import main - main('idlelib.idle_test.test_abc', verbosity=2, exit=False) + main('idlelib.idle_test.test_abc', verbosity=2) -The ', exit=False' is only needed if an htest follows. +Add ', exit=False' to the main call if and only if an htest follows. diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py index 778e5c3d84e496..0bd0378fbfa07a 100644 --- a/Lib/idlelib/idle_test/htest.py +++ b/Lib/idlelib/idle_test/htest.py @@ -1,48 +1,51 @@ """Run human tests of Idle's window, dialog, and popup widgets. -run(*tests) Create a master Tk() htest window. Within that, run each -callable in tests after finding the matching test spec in this file. If -tests is empty, run an htest for each spec dict in this file after -finding the matching callable in the module named in the spec. Close -the master window to end testing. - -In a tested module, let X be a global name bound to a callable (class or -function) whose .__name__ attribute is also X (the usual situation). The -first parameter of X must be 'parent' or 'master'. When called, the -first argument will be the root window. X must create a child -Toplevel(parent/master) (or subclass thereof). The Toplevel may be a -test widget or dialog, in which case the callable is the corresponding -class. Or the Toplevel may contain the widget to be tested or set up a -context in which a test widget is invoked. In this latter case, the -callable is a wrapper function that sets up the Toplevel and other -objects. Wrapper function names, such as _editor_window', should start -with '_' and be lowercase. - +The main function, `run(*tests)`, is defined at the end of this file. +Argument `tests` is a possibly empty tuple of callables defined in some +idlelib.abc module (or possibly modules). Its steps: +1. Create a master Tk() htest window. Within that window ... +2a. If tuple `tests` is not empty, run was likely called from one + module. Run each callable in `tests` after finding the matching + callable_spec test spec in this file. +2b. If tests is empty, run was likely called from this file. + Run an htest for each spec dict in this file after finding the + matching callable in the module named in the spec. +3. Close the master window to end testing. + +In a tested module, let X be a global name bound to a callable (class +or function) whose .__name__ attribute (its `class` or `def` definition +name) is also X. X must expect exactly 1 positional argument, a +parent toplevel window. Run passes the htest window. X must create a +child Toplevel(parent/master). The callable may be either a runtime +object or a wrapper function written just for the test. In the latter +case, its name should start with '_' and be lowercase (such as '_ttt'). End the module with - +``` if __name__ == '__main__': - + from unittest import main + main("idlelib.idle_test.test_xyz", verbosity=2, exit=False) + from idlelib.idle_test.htest import run - run(callable) # There could be multiple comma-separated callables. + run(callable) +``` +Replace 'xyz' as appropriate and 'callable' with the callable name or +comma-separated names (multiple names is rare). 'exit=False' is needed +for the htest to run. To have wrapper functions ignored by coverage reports, tag the def -header like so: "def _wrapper(parent): # htest #". Use the same tag -for htest lines in widget code. Make sure that the 'if __name__' line -matches the above. Then have make sure that .coveragerc includes the -following: - +header like so: "def _wrapper(root): # htest #". Use the same tag +for htest-only lines in the main code. To ignore the 'if __name__' +statement, match the example above. Add the below to coveragerc. +``` [report] exclude_lines = .*# htest # if __name__ == .__main__.: - -(The "." instead of "'" is intentional and necessary.) - +``` To run any X, this file must contain a matching instance of the following template, with X.__name__ prepended to '_spec'. -When all tests are run, the prefix is use to get X. callable_spec = { 'file': '', @@ -51,11 +54,10 @@ } file (no .py): run() imports file.py. -kwds: augmented with {'parent':root} and passed to X as **kwds. +kwds: run() augments with {'parent':root} and passes to X as **kwds. title: an example kwd; some widgets need this, delete line if not. msg: master window hints about testing the widget. - TODO test these modules and classes: autocomplete_w.AutoCompleteWindow debugger.Debugger diff --git a/Lib/idlelib/idle_test/test_delegator.py b/Lib/idlelib/idle_test/test_delegator.py index 922416297a42e0..c4273deee7ffbd 100644 --- a/Lib/idlelib/idle_test/test_delegator.py +++ b/Lib/idlelib/idle_test/test_delegator.py @@ -41,4 +41,4 @@ def test_mydel(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_format.py b/Lib/idlelib/idle_test/test_format.py index e5e903688597aa..6550e9765f290d 100644 --- a/Lib/idlelib/idle_test/test_format.py +++ b/Lib/idlelib/idle_test/test_format.py @@ -665,4 +665,4 @@ def test_rstrip_end(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_history.py b/Lib/idlelib/idle_test/test_history.py index 67539651444751..e1031579c3d821 100644 --- a/Lib/idlelib/idle_test/test_history.py +++ b/Lib/idlelib/idle_test/test_history.py @@ -169,4 +169,4 @@ def test_history_prev_next(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_pathbrowser.py b/Lib/idlelib/idle_test/test_pathbrowser.py index 13d8b9e1ba9572..a198978d5c1ef7 100644 --- a/Lib/idlelib/idle_test/test_pathbrowser.py +++ b/Lib/idlelib/idle_test/test_pathbrowser.py @@ -83,4 +83,4 @@ def test_PathBrowserTreeItem(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_query.py b/Lib/idlelib/idle_test/test_query.py index a6ef858a8c954a..58c173723a5ada 100644 --- a/Lib/idlelib/idle_test/test_query.py +++ b/Lib/idlelib/idle_test/test_query.py @@ -448,4 +448,4 @@ def test_click_args(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_search.py b/Lib/idlelib/idle_test/test_search.py index de703c195cd229..2b0a9d483bfc0f 100644 --- a/Lib/idlelib/idle_test/test_search.py +++ b/Lib/idlelib/idle_test/test_search.py @@ -77,4 +77,4 @@ def test_find_selection(self): text.delete('2.0', 'end') if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_searchbase.py b/Lib/idlelib/idle_test/test_searchbase.py index 8c9c410ebaf47c..1780cab6527dd9 100644 --- a/Lib/idlelib/idle_test/test_searchbase.py +++ b/Lib/idlelib/idle_test/test_searchbase.py @@ -157,4 +157,4 @@ def test_create_command_buttons(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=2) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_text.py b/Lib/idlelib/idle_test/test_text.py index 43a9ba02c3d3c9..8ee1c9f2d76813 100644 --- a/Lib/idlelib/idle_test/test_text.py +++ b/Lib/idlelib/idle_test/test_text.py @@ -233,4 +233,4 @@ def setUp(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2) diff --git a/Lib/idlelib/idle_test/test_undo.py b/Lib/idlelib/idle_test/test_undo.py index beb5b582039f88..0488a2c9809b48 100644 --- a/Lib/idlelib/idle_test/test_undo.py +++ b/Lib/idlelib/idle_test/test_undo.py @@ -132,4 +132,4 @@ def test_addcmd(self): if __name__ == '__main__': - unittest.main(verbosity=2, exit=False) + unittest.main(verbosity=2)