Issue *24750: Switch all scrollbars in IDLE to ttk versions.
Where needed, add minimal tests to cover changes.
diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py
index c66b3df..38f8601 100644
--- a/Lib/idlelib/autocomplete_w.py
+++ b/Lib/idlelib/autocomplete_w.py
@@ -2,6 +2,7 @@
 An auto-completion window for IDLE, used by the autocomplete extension
 """
 from tkinter import *
+from tkinter.ttk import Scrollbar
 from idlelib.multicall import MC_SHIFT
 from idlelib.autocomplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES
 
diff --git a/Lib/idlelib/config_key.py b/Lib/idlelib/config_key.py
index e6438bf..2602293 100644
--- a/Lib/idlelib/config_key.py
+++ b/Lib/idlelib/config_key.py
@@ -2,31 +2,35 @@
 Dialog for building Tkinter accelerator key bindings
 """
 from tkinter import *
+from tkinter.ttk import Scrollbar
 import tkinter.messagebox as tkMessageBox
 import string
 import sys
 
 class GetKeysDialog(Toplevel):
-    def __init__(self,parent,title,action,currentKeySequences,_htest=False):
+    def __init__(self, parent, title, action, currentKeySequences,
+                 _htest=False, _utest=False):
         """
         action - string, the name of the virtual event these keys will be
                  mapped to
         currentKeys - list, a list of all key sequence lists currently mapped
                  to virtual events, for overlap checking
+        _utest - bool, do not wait when running unittest
         _htest - bool, change box location when running htest
         """
         Toplevel.__init__(self, parent)
+        self.withdraw() #hide while setting geometry
         self.configure(borderwidth=5)
-        self.resizable(height=FALSE,width=FALSE)
+        self.resizable(height=FALSE, width=FALSE)
         self.title(title)
         self.transient(parent)
         self.grab_set()
         self.protocol("WM_DELETE_WINDOW", self.Cancel)
         self.parent = parent
         self.action=action
-        self.currentKeySequences=currentKeySequences
-        self.result=''
-        self.keyString=StringVar(self)
+        self.currentKeySequences = currentKeySequences
+        self.result = ''
+        self.keyString = StringVar(self)
         self.keyString.set('')
         self.SetModifiersForPlatform() # set self.modifiers, self.modifier_label
         self.modifier_vars = []
@@ -37,7 +41,6 @@
         self.advanced = False
         self.CreateWidgets()
         self.LoadFinalKeyList()
-        self.withdraw() #hide while setting geometry
         self.update_idletasks()
         self.geometry(
                 "+%d+%d" % (
@@ -47,8 +50,9 @@
                     ((parent.winfo_height()/2 - self.winfo_reqheight()/2)
                     if not _htest else 150)
                 ) )  #centre dialog over parent (or below htest box)
-        self.deiconify() #geometry set, unhide
-        self.wait_window()
+        if not _utest:
+            self.deiconify() #geometry set, unhide
+            self.wait_window()
 
     def CreateWidgets(self):
         frameMain = Frame(self,borderwidth=2,relief=SUNKEN)
@@ -261,6 +265,7 @@
             keysOK = True
         return keysOK
 
+
 if __name__ == '__main__':
     from idlelib.idle_test.htest import run
     run(GetKeysDialog)
diff --git a/Lib/idlelib/configdialog.py b/Lib/idlelib/configdialog.py
index b58806e..1d7b417 100644
--- a/Lib/idlelib/configdialog.py
+++ b/Lib/idlelib/configdialog.py
@@ -10,6 +10,7 @@
 
 """
 from tkinter import *
+from tkinter.ttk import Scrollbar
 import tkinter.messagebox as tkMessageBox
 import tkinter.colorchooser as tkColorChooser
 import tkinter.font as tkFont
diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py
index 9af626c..ea393b1 100644
--- a/Lib/idlelib/debugger.py
+++ b/Lib/idlelib/debugger.py
@@ -1,6 +1,7 @@
 import os
 import bdb
 from tkinter import *
+from tkinter.ttk import Scrollbar
 from idlelib.windows import ListedToplevel
 from idlelib.scrolledlist import ScrolledList
 from idlelib import macosx
diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py
index d04fc08..7f910e7 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -7,6 +7,7 @@
 import string
 import sys
 from tkinter import *
+from tkinter.ttk import Scrollbar
 import tkinter.simpledialog as tkSimpleDialog
 import tkinter.messagebox as tkMessageBox
 import traceback
diff --git a/Lib/idlelib/help.py b/Lib/idlelib/help.py
index 0093015..d18d1ca 100644
--- a/Lib/idlelib/help.py
+++ b/Lib/idlelib/help.py
@@ -26,14 +26,11 @@
 """
 from html.parser import HTMLParser
 from os.path import abspath, dirname, isfile, join
-from tkinter import Toplevel, Frame, Text, Scrollbar, Menu, Menubutton
+from tkinter import Toplevel, Frame, Text, Menu
+from tkinter.ttk import Menubutton, Scrollbar
 from tkinter import font as tkfont
 from idlelib.config import idleConf
 
-use_ttk = False # until available to import
-if use_ttk:
-    from tkinter.ttk import Menubutton
-
 ## About IDLE ##
 
 
@@ -196,15 +193,18 @@
     "Display html text, scrollbar, and toc."
     def __init__(self, parent, filename):
         Frame.__init__(self, parent)
-        text = HelpText(self, filename)
+        # keep references to widgets for test access.
+        self.text = text = HelpText(self, filename)
         self['background'] = text['background']
-        scroll = Scrollbar(self, command=text.yview)
+        self.toc = toc = self.toc_menu(text)
+        self.scroll = scroll = Scrollbar(self, command=text.yview)
         text['yscrollcommand'] = scroll.set
+
         self.rowconfigure(0, weight=1)
         self.columnconfigure(1, weight=1)  # text
-        self.toc_menu(text).grid(column=0, row=0, sticky='nw')
-        text.grid(column=1, row=0, sticky='nsew')
-        scroll.grid(column=2, row=0, sticky='ns')
+        toc.grid(row=0, column=0, sticky='nw')
+        text.grid(row=0, column=1, sticky='nsew')
+        scroll.grid(row=0, column=2, sticky='ns')
 
     def toc_menu(self, text):
         "Create table of contents as drop-down menu."
@@ -265,7 +265,7 @@
     if not isfile(filename):
         # try copy_strip, present message
         return
-    HelpWindow(parent, filename, 'IDLE Help')
+    return HelpWindow(parent, filename, 'IDLE Help')
 
 if __name__ == '__main__':
     from idlelib.idle_test.htest import run
diff --git a/Lib/idlelib/idle_test/htest.py b/Lib/idlelib/idle_test/htest.py
index 686ccc5..5fd33a6 100644
--- a/Lib/idlelib/idle_test/htest.py
+++ b/Lib/idlelib/idle_test/htest.py
@@ -68,6 +68,7 @@
 from importlib import import_module
 from idlelib.macosx import _init_tk_type
 import tkinter as tk
+from tkinter.ttk import Scrollbar
 
 AboutDialog_spec = {
     'file': 'help_about',
@@ -344,7 +345,7 @@
     frameLabel.pack()
     text = tk.Text(frameLabel, wrap='word')
     text.configure(bg=root.cget('bg'), relief='flat', height=4, width=70)
-    scrollbar = tk.Scrollbar(frameLabel, command=text.yview)
+    scrollbar = Scrollbar(frameLabel, command=text.yview)
     text.config(yscrollcommand=scrollbar.set)
     scrollbar.pack(side='right', fill='y', expand=False)
     text.pack(side='left', fill='both', expand=True)
diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py
index 496a41d..a14c6db 100644
--- a/Lib/idlelib/idle_test/test_autocomplete.py
+++ b/Lib/idlelib/idle_test/test_autocomplete.py
@@ -1,10 +1,14 @@
+''' Test autocomplete and autocomple_w
+
+Coverage of autocomple: 56%
+'''
 import unittest
 from test.support import requires
 from tkinter import Tk, Text
 
 import idlelib.autocomplete as ac
 import idlelib.autocomplete_w as acw
-import idlelib.macosx as mac
+from idlelib import macosx
 from idlelib.idle_test.mock_idle import Func
 from idlelib.idle_test.mock_tk import Event
 
@@ -27,7 +31,7 @@
     def setUpClass(cls):
         requires('gui')
         cls.root = Tk()
-        mac.setupApp(cls.root, None)
+        macosx.setupApp(cls.root, None)
         cls.text = Text(cls.root)
         cls.editor = DummyEditwin(cls.root, cls.text)
 
diff --git a/Lib/idlelib/idle_test/test_config_key.py b/Lib/idlelib/idle_test/test_config_key.py
new file mode 100644
index 0000000..8109829
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_config_key.py
@@ -0,0 +1,31 @@
+''' Test idlelib.config_key.
+
+Coverage: 56%
+'''
+from idlelib import config_key
+from test.support import requires
+requires('gui')
+import unittest
+from tkinter import Tk, Text
+
+
+class GetKeysTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        del cls.root
+
+
+    def test_init(self):
+        dia = config_key.GetKeysDialog(
+            self.root, 'test', '<<Test>>', ['<Key-F12>'], _utest=True)
+        dia.Cancel()
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_debugger.py b/Lib/idlelib/idle_test/test_debugger.py
new file mode 100644
index 0000000..bcba9a4
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_debugger.py
@@ -0,0 +1,29 @@
+''' Test idlelib.debugger.
+
+Coverage: 19%
+'''
+from idlelib import debugger
+from test.support import requires
+requires('gui')
+import unittest
+from tkinter import Tk
+
+
+class NameSpaceTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+        cls.root.withdraw()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        del cls.root
+
+    def test_init(self):
+        debugger.NamespaceViewer(self.root, 'Test')
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_help.py b/Lib/idlelib/idle_test/test_help.py
new file mode 100644
index 0000000..cdded2a
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_help.py
@@ -0,0 +1,34 @@
+'''Test idlelib.help.
+
+Coverage: 87%
+'''
+from idlelib import help
+from test.support import requires
+requires('gui')
+from os.path import abspath, dirname, join
+from tkinter import Tk
+import unittest
+
+class HelpFrameTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        "By itself, this tests that file parsed without exception."
+        cls.root = root = Tk()
+        root.withdraw()
+        helpfile = join(abspath(dirname(dirname(__file__))), 'help.html')
+        cls.frame = help.HelpFrame(root, helpfile)
+
+    @classmethod
+    def tearDownClass(cls):
+        del cls.frame
+        cls.root.update_idletasks()
+        cls.root.destroy()
+        del cls.root
+
+    def test_line1(self):
+        text = self.frame.text
+        self.assertEqual(text.get('1.0', '1.end'), ' IDLE ')
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_scrolledlist.py b/Lib/idlelib/idle_test/test_scrolledlist.py
new file mode 100644
index 0000000..56aabfe
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_scrolledlist.py
@@ -0,0 +1,29 @@
+''' Test idlelib.scrolledlist.
+
+Coverage: 39%
+'''
+from idlelib import scrolledlist
+from test.support import requires
+requires('gui')
+import unittest
+from tkinter import Tk
+
+
+class ScrolledListTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        del cls.root
+
+
+    def test_init(self):
+        scrolledlist.ScrolledList(self.root)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/idle_test/test_textview.py b/Lib/idlelib/idle_test/test_textview.py
index 4c70ebb..764a1a5 100644
--- a/Lib/idlelib/idle_test/test_textview.py
+++ b/Lib/idlelib/idle_test/test_textview.py
@@ -7,13 +7,13 @@
 
 The coverage is essentially 100%.
 '''
+from idlelib import textview as tv
 from test.support import requires
 requires('gui')
 
 import unittest
 import os
 from tkinter import Tk
-from idlelib import textview as tv
 from idlelib.idle_test.mock_idle import Func
 from idlelib.idle_test.mock_tk import Mbox
 
diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py
new file mode 100644
index 0000000..09ba964
--- /dev/null
+++ b/Lib/idlelib/idle_test/test_tree.py
@@ -0,0 +1,36 @@
+''' Test idlelib.tree.
+
+Coverage: 56%
+'''
+from idlelib import tree
+from test.support import requires
+requires('gui')
+import os
+import unittest
+from tkinter import Tk
+
+
+class TreeTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.root = Tk()
+        cls.root.withdraw()
+
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        del cls.root
+
+    def test_init(self):
+        # Start with code slightly adapted from htest.
+        sc = tree.ScrolledCanvas(
+            self.root, bg="white", highlightthickness=0, takefocus=1)
+        sc.frame.pack(expand=1, fill="both", side='left')
+        item = tree.FileTreeItem(tree.ICONDIR)
+        node = tree.TreeNode(sc.canvas, None, item)
+        node.expand()
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/Lib/idlelib/scrolledlist.py b/Lib/idlelib/scrolledlist.py
index 80df0f8..d0b6610 100644
--- a/Lib/idlelib/scrolledlist.py
+++ b/Lib/idlelib/scrolledlist.py
@@ -1,5 +1,6 @@
 from tkinter import *
 from idlelib import macosx
+from tkinter.ttk import Scrollbar
 
 class ScrolledList:
 
@@ -124,22 +125,20 @@
         pass
 
 
-def _scrolled_list(parent):
-    root = Tk()
-    root.title("Test ScrolledList")
+def _scrolled_list(parent):  # htest #
+    top = Toplevel(parent)
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
+    top.geometry("+%d+%d"%(x+200, y + 175))
     class MyScrolledList(ScrolledList):
         def fill_menu(self): self.menu.add_command(label="right click")
         def on_select(self, index): print("select", self.get(index))
         def on_double(self, index): print("double", self.get(index))
 
-    scrolled_list = MyScrolledList(root)
+    scrolled_list = MyScrolledList(top)
     for i in range(30):
         scrolled_list.append("Item %02d" % i)
 
-    root.mainloop()
-
 if __name__ == '__main__':
+    # At the moment, test_scrolledlist merely creates instance, like htest.
     from idlelib.idle_test.htest import run
     run(_scrolled_list)
diff --git a/Lib/idlelib/textview.py b/Lib/idlelib/textview.py
index 01b2d8f..9dc8357 100644
--- a/Lib/idlelib/textview.py
+++ b/Lib/idlelib/textview.py
@@ -3,6 +3,7 @@
 """
 
 from tkinter import *
+from tkinter.ttk import Scrollbar
 import tkinter.messagebox as tkMessageBox
 
 class TextViewer(Toplevel):
@@ -50,7 +51,7 @@
         self.buttonOk = Button(frameButtons, text='Close',
                                command=self.Ok, takefocus=FALSE)
         self.scrollbarView = Scrollbar(frameText, orient=VERTICAL,
-                                       takefocus=FALSE, highlightthickness=0)
+                                       takefocus=FALSE)
         self.textView = Text(frameText, wrap=WORD, highlightthickness=0,
                              fg=self.fg, bg=self.bg)
         self.scrollbarView.config(command=self.textView.yview)
diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py
index 08cc637..cb7f9ae 100644
--- a/Lib/idlelib/tree.py
+++ b/Lib/idlelib/tree.py
@@ -16,7 +16,7 @@
 
 import os
 from tkinter import *
-
+from tkinter.ttk import Scrollbar
 from idlelib import zoomheight
 from idlelib.config import idleConf
 
@@ -449,18 +449,17 @@
         return "break"
 
 
-def _tree_widget(parent):
-    root = Tk()
-    root.title("Test TreeWidget")
+def _tree_widget(parent):  # htest #
+    top = Toplevel(parent)
     width, height, x, y = list(map(int, re.split('[x+]', parent.geometry())))
-    root.geometry("+%d+%d"%(x, y + 150))
-    sc = ScrolledCanvas(root, bg="white", highlightthickness=0, takefocus=1)
+    top.geometry("+%d+%d"%(x+50, y+175))
+    sc = ScrolledCanvas(top, bg="white", highlightthickness=0, takefocus=1)
     sc.frame.pack(expand=1, fill="both", side=LEFT)
-    item = FileTreeItem(os.getcwd())
+    item = FileTreeItem(ICONDIR)
     node = TreeNode(sc.canvas, None, item)
     node.expand()
-    root.mainloop()
 
 if __name__ == '__main__':
+    # test_tree is currently a copy of this
     from idlelib.idle_test.htest import run
     run(_tree_widget)