Fix problems with different test ordering
diff --git a/certbot/tests/cli_test.py b/certbot/tests/cli_test.py
index 32aada811c2..b0eb965426b 100644
--- a/certbot/tests/cli_test.py
+++ b/certbot/tests/cli_test.py
@@ -1,12 +1,11 @@
 """Tests for certbot.cli."""
 import argparse
-import functools
 import unittest
 import os
 import tempfile
 
-import six
 import mock
+import six
 from six.moves import reload_module  # pylint: disable=import-error
 
 from certbot import cli
@@ -14,9 +13,8 @@
 from certbot import errors
 from certbot.plugins import disco
 
-def reset_set_by_cli():
-    '''Reset the state of the `set_by_cli` function'''
-    cli.set_by_cli.detector = None
+PLUGINS = disco.PluginsRegistry.find_all()
+
 
 class TestReadFile(unittest.TestCase):
     '''Test cli.read_file'''
@@ -43,13 +41,13 @@ class ParseTest(unittest.TestCase):
 
     _multiprocess_can_split_ = True
 
-    @classmethod
-    def setUpClass(cls):
-        cls.plugins = disco.PluginsRegistry.find_all()
-        cls.parse = functools.partial(cli.prepare_and_parse_args, cls.plugins)
-
     def setUp(self):
-        reset_set_by_cli()
+        reload_module(cli)
+
+    @staticmethod
+    def parse(*args, **kwargs):
+        """Get result of cli.prepare_and_parse_args."""
+        return cli.prepare_and_parse_args(PLUGINS, *args, **kwargs)
 
     def _help_output(self, args):
         "Run a command, and return the ouput string for scrutiny"
@@ -88,7 +86,7 @@ def test_help(self):
         self.assertTrue("{0}" not in out)
 
         out = self._help_output(['-h', 'nginx'])
-        if "nginx" in self.plugins:
+        if "nginx" in PLUGINS:
             # may be false while building distributions without plugins
             self.assertTrue("--nginx-ctl" in out)
         self.assertTrue("--webroot-path" not in out)
@@ -96,7 +94,7 @@ def test_help(self):
 
         out = self._help_output(['-h'])
         self.assertTrue("letsencrypt-auto" not in out)  # test cli.cli_command
-        if "nginx" in self.plugins:
+        if "nginx" in PLUGINS:
             self.assertTrue("Use the Nginx plugin" in out)
         else:
             self.assertTrue("(the certbot nginx plugin is not" in out)
diff --git a/certbot/tests/hook_test.py b/certbot/tests/hook_test.py
index 87c86ad5cba..0fbb91492a3 100644
--- a/certbot/tests/hook_test.py
+++ b/certbot/tests/hook_test.py
@@ -5,16 +5,14 @@
 import unittest
 
 import mock
+from six.moves import reload_module  # pylint: disable=import-error
 
 from certbot import errors
 from certbot import hooks
 
 class HookTest(unittest.TestCase):
     def setUp(self):
-        pass
-
-    def tearDown(self):
-        pass
+        reload_module(hooks)
 
     @mock.patch('certbot.hooks._prog')
     def test_validate_hooks(self, mock_prog):
@@ -47,7 +45,6 @@ def _test_a_hook(self, config, hook_function, calls_expected, **kwargs):
             return mock_logger.warning
 
     def test_pre_hook(self):
-        hooks.pre_hook.already = set()
         config = mock.MagicMock(pre_hook="true")
         self._test_a_hook(config, hooks.pre_hook, 1)
         self._test_a_hook(config, hooks.pre_hook, 0)
diff --git a/certbot/tests/main_test.py b/certbot/tests/main_test.py
index 01ec2f0611d..087a3615dcf 100644
--- a/certbot/tests/main_test.py
+++ b/certbot/tests/main_test.py
@@ -12,6 +12,7 @@
 import pytz
 
 import six
+from six.moves import reload_module  # pylint: disable=import-error
 
 from acme import jose
 
@@ -434,10 +435,9 @@ def setUp(self):
                               '--logs-dir', self.logs_dir, '--text']
 
     def tearDown(self):
-        shutil.rmtree(self.tmp_dir)
         # Reset globals in cli
-        # pylint: disable=protected-access
-        cli._parser = cli.set_by_cli.detector = None
+        reload_module(cli)
+        shutil.rmtree(self.tmp_dir)
 
     def _call(self, args, stdout=None):
         "Run the cli with output streams and actual client mocked out"
@@ -874,8 +874,9 @@ def test_renew_no_hook_validation(self):
         test_util.make_lineage(self, 'sample-renewal.conf')
         args = ["renew", "--dry-run", "--post-hook=no-such-command",
                 "--disable-hook-validation"]
-        self._test_renewal_common(True, [], args=args, should_renew=True,
-                                  error_expected=False)
+        with mock.patch("certbot.hooks.post_hook"):
+            self._test_renewal_common(True, [], args=args, should_renew=True,
+                                      error_expected=False)
 
     @mock.patch("certbot.cli.set_by_cli")
     def test_ancient_webroot_renewal_conf(self, mock_set_by_cli):

I went through our unit tests and looked at all non-constant global/static variables that I'm aware of. The ones I looked at are in `certbot/cli.py` and `certbot/hooks.py`. These variables are now properly cleaned up during tests so they don't affect other tests.