From 77af4ce04065da55ea235b61c3efd0a933581fef Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Sun, 13 Apr 2014 13:57:22 -0700 Subject: [PATCH] more test isolation (#670) Doing test-specific cleanup in tearDown before general sandbox deletion helps avoiding contamination of global state between tests when cleanup fails. Current Windows status: Ran 1106 tests in 72.373s FAILED (SKIP=10, errors=13, failures=15) Closer! --- test/test_convert.py | 4 ++-- test/test_ui.py | 30 ++++++++++++++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/test/test_convert.py b/test/test_convert.py index e53ba2391e..4af539923b 100644 --- a/test/test_convert.py +++ b/test/test_convert.py @@ -35,8 +35,8 @@ def setUp(self): } def tearDown(self): - self.teardown_beets() self.unload_plugins() + self.teardown_beets() def test_import_converted(self): self.importer.run() @@ -72,8 +72,8 @@ def setUp(self): self.config['convert']['paths']['default'] = u'converted' def tearDown(self): - self.teardown_beets() self.unload_plugins() + self.teardown_beets() def test_convert(self): with control_stdin('y'): diff --git a/test/test_ui.py b/test/test_ui.py index 6a3b3f78f4..34d7104b40 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -140,6 +140,7 @@ def test_remove_items_with_delete(self): self.assertEqual(len(list(items)), 0) self.assertFalse(os.path.exists(self.i.path)) + class ModifyTest(_common.TestCase): def setUp(self): super(ModifyTest, self).setUp() @@ -237,6 +238,7 @@ def test_delete_initial_key_tag(self): mediafile = MediaFile(item.path) self.assertIsNone(mediafile.initial_key) + class MoveTest(_common.TestCase): def setUp(self): super(MoveTest, self).setUp() @@ -303,6 +305,7 @@ def test_move_album_custom_dir(self): self.assertExists(self.i.path) self.assertNotExists(self.itempath) + class UpdateTest(_common.TestCase): def setUp(self): super(UpdateTest, self).setUp() @@ -319,7 +322,7 @@ def setUp(self): self.album = self.lib.add_album([self.i]) # Album art. - artfile = os.path.join(_common.RSRC, 'testart.jpg') + artfile = os.path.join(self.temp_dir, 'testart.jpg') _common.touch(artfile) self.album.set_art(artfile) self.album.store() @@ -405,6 +408,7 @@ def test_mtime_match_skips_update(self): item = self.lib.items().get() self.assertEqual(item.title, 'full') + class PrintTest(_common.TestCase): def setUp(self): super(PrintTest, self).setUp() @@ -443,6 +447,7 @@ def test_print_with_invalid_locale(self): else: del os.environ['LC_CTYPE'] + class AutotagTest(_common.TestCase): def setUp(self): super(AutotagTest, self).setUp() @@ -468,6 +473,7 @@ def test_choose_match_with_no_candidates_asis(self): self.io.addinput('u') self._no_candidates_test(importer.action.ASIS) + class ImportTest(_common.TestCase): def test_quiet_timid_disallowed(self): config['import']['quiet'] = True @@ -475,6 +481,7 @@ def test_quiet_timid_disallowed(self): self.assertRaises(ui.UserError, commands.import_files, None, [], None) + class InputTest(_common.TestCase): def setUp(self): super(InputTest, self).setUp() @@ -487,6 +494,7 @@ def test_manual_search_gets_unicode(self): self.assertEqual(artist, u'\xc2me') self.assertEqual(album, u'\xc2me') + class ConfigTest(_common.TestCase): def setUp(self): super(ConfigTest, self).setUp() @@ -507,19 +515,21 @@ def setUp(self): self._reset_config() def tearDown(self): - super(ConfigTest, self).tearDown() commands.default_commands.pop() if 'BEETSDIR' in os.environ: del os.environ['BEETSDIR'] if os.getcwd != self._orig_cwd: os.chdir(self._orig_cwd) + super(ConfigTest, self).tearDown() def _make_test_cmd(self): test_cmd = ui.Subcommand('test', help='test') + def run(lib, options, args): test_cmd.lib = lib test_cmd.options = options test_cmd.args = args + test_cmd.func = run return test_cmd @@ -533,7 +543,6 @@ def _reset_config(self): def write_config_file(self): return open(self.user_config_path, 'w') - def test_paths_section_respected(self): with self.write_config_file() as config: config.write('paths: {x: y}') @@ -865,6 +874,7 @@ def test_item_data_change_title_missing_with_unicode_filename(self): self.assertTrue(u'caf\xe9.mp3 -> the title' in msg or u'caf.mp3 ->' in msg) + class PathFormatTest(_common.TestCase): def test_custom_paths_prepend(self): default_formats = ui.get_path_formats() @@ -876,6 +886,7 @@ def test_custom_paths_prepend(self): self.assertEqual(tmpl.original, 'bar') self.assertEqual(pf[1:], default_formats) + class PluginTest(_common.TestCase): def test_plugin_command_from_pluginpath(self): config['pluginpath'] = [os.path.join(_common.RSRC, 'beetsplug')] @@ -884,19 +895,25 @@ def test_plugin_command_from_pluginpath(self): class CompletionTest(_common.TestCase): - def test_completion(self): # Load plugin commands config['pluginpath'] = [os.path.join(_common.RSRC, 'beetsplug')] config['plugins'] = ['test'] - test_script = os.path.join(os.path.dirname(__file__), - 'test_completion.sh') + test_script = os.path.join( + os.path.dirname(__file__), 'test_completion.sh' + ) bash_completion = os.path.abspath(os.environ.get( 'BASH_COMPLETION_SCRIPT', '/etc/bash_completion')) # Tests run in bash shell = os.environ.get('BEETS_TEST_SHELL', '/bin/bash --norc') + try: + with open(os.devnull, 'wb') as devnull: + subprocess.check_call(shell.split() + ['--version'], + stdout=devnull) + except OSError: + self.skipTest('bash not available') tester = subprocess.Popen(shell.split(' '), stdin=subprocess.PIPE, stdout=subprocess.PIPE) @@ -925,6 +942,7 @@ def test_completion(self): print(out) self.fail('test/test_completion.sh did not execute properly') + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)