From b4e737c2435739199aaaa39790d520cea86fe6cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alban=20F=C3=A9ron?= Date: Sat, 20 Nov 2021 21:01:00 +0100 Subject: [PATCH] Use test discovery rather than explicit suites --- .github/workflows/tests.yaml | 6 ++--- README.md | 12 ++++++---- setup.py | 5 +---- tests/__init__.py | 36 +++++------------------------- tests/api/__init__.py | 36 ------------------------------ tests/api/test_response_helper.py | 10 --------- tests/base/__init__.py | 24 -------------------- tests/base/test_watcher.py | 9 -------- tests/frontend/__init__.py | 18 --------------- tests/managers/__init__.py | 14 ------------ tests/net/__init__.py | 28 +++++++++++++++++++++++ tests/{base => net}/test_lastfm.py | 2 +- tests/{api => net}/test_lyrics.py | 2 +- tests/with_net.py | 20 ----------------- 14 files changed, 48 insertions(+), 174 deletions(-) create mode 100644 tests/net/__init__.py rename tests/{base => net}/test_lastfm.py (90%) rename tests/{api => net}/test_lyrics.py (98%) delete mode 100644 tests/with_net.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 9689137..0868352 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,7 +16,7 @@ jobs: - 3.7 - 3.8 - 3.9 - - "3.10" + #- "3.10" fail-fast: false steps: - name: Checkout @@ -31,8 +31,8 @@ jobs: pip install -r ci-requirements.txt - name: Run tests run: | - coverage run setup.py test - coverage run -a setup.py test --test-suite tests.with_net + coverage run -m unittest + coverage run -a -m unittest tests.net.suite - name: Upload coverage uses: codecov/codecov-action@v1.0.15 if: ${{ !cancelled() }} diff --git a/README.md b/README.md index a0e7e60..9666659 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Current supported features are: * user or random playlists * cover art * starred tracks/albums and ratings -* [Last.FM][lastfm] scrobbling +* [Last.fm][lastfm] scrobbling * Jukebox mode Supysonic currently targets the version 1.10.2 of the Subsonic API. For more @@ -65,9 +65,13 @@ in-browser debugging among other things. To start said server: $ export FLASK_ENV=development $ flask run -And there's also the tests: +And there's also the tests (which require `lxml` to run): - $ python setup.py test - $ python setup.py test --test-suite tests.with_net + $ pip install lxml + $ python -m unittest + $ python -m unittest tests.net.suite + +The last command runs a few tests that make HTTP requests to remote third-party +services (namely Last.fm and ChartLyrics). [flask]: https://flask.palletsprojects.com/ diff --git a/setup.py b/setup.py index c043717..e51e2d7 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,4 @@ from setuptools import setup if __name__ == "__main__": - setup( - test_suite="tests.suite", - tests_require=["lxml"], - ) + setup() diff --git a/tests/__init__.py b/tests/__init__.py index 3ea7952..aedbb98 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -6,35 +6,11 @@ # # Distributed under terms of the GNU AGPLv3 license. -import unittest - -from . import base -from . import managers -from . import api -from . import frontend - -from .issue85 import Issue85TestCase -from .issue101 import Issue101TestCase -from .issue129 import Issue129TestCase -from .issue133 import Issue133TestCase -from .issue139 import Issue139TestCase -from .issue148 import Issue148TestCase -from .issue221 import Issue221TestCase +import os.path -def suite(): - suite = unittest.TestSuite() - - suite.addTest(base.suite()) - suite.addTest(managers.suite()) - suite.addTest(api.suite()) - suite.addTest(frontend.suite()) - suite.addTest(unittest.makeSuite(Issue85TestCase)) - suite.addTest(unittest.makeSuite(Issue101TestCase)) - suite.addTest(unittest.makeSuite(Issue129TestCase)) - suite.addTest(unittest.makeSuite(Issue133TestCase)) - suite.addTest(unittest.makeSuite(Issue139TestCase)) - suite.addTest(unittest.makeSuite(Issue148TestCase)) - suite.addTest(unittest.makeSuite(Issue221TestCase)) - - return suite +def load_tests(loader, tests, pattern): + this_dir = os.path.dirname(__file__) + tests.addTests(loader.discover(start_dir=this_dir, pattern="test*.py")) + tests.addTests(loader.discover(start_dir=this_dir, pattern="issue*.py")) + return tests diff --git a/tests/api/__init__.py b/tests/api/__init__.py index b67211d..227addb 100644 --- a/tests/api/__init__.py +++ b/tests/api/__init__.py @@ -4,39 +4,3 @@ # Copyright (C) 2017 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. - -import unittest - -from .test_response_helper import suite as rh_suite -from .test_api_setup import ApiSetupTestCase -from .test_system import SystemTestCase -from .test_user import UserTestCase -from .test_chat import ChatTestCase -from .test_search import SearchTestCase -from .test_playlist import PlaylistTestCase -from .test_browse import BrowseTestCase -from .test_album_songs import AlbumSongsTestCase -from .test_annotation import AnnotationTestCase -from .test_media import MediaTestCase -from .test_transcoding import TranscodingTestCase -from .test_radio import RadioStationTestCase - - -def suite(): - suite = unittest.TestSuite() - - suite.addTest(rh_suite()) - suite.addTest(unittest.makeSuite(ApiSetupTestCase)) - suite.addTest(unittest.makeSuite(SystemTestCase)) - suite.addTest(unittest.makeSuite(UserTestCase)) - suite.addTest(unittest.makeSuite(ChatTestCase)) - suite.addTest(unittest.makeSuite(SearchTestCase)) - suite.addTest(unittest.makeSuite(PlaylistTestCase)) - suite.addTest(unittest.makeSuite(BrowseTestCase)) - suite.addTest(unittest.makeSuite(AlbumSongsTestCase)) - suite.addTest(unittest.makeSuite(AnnotationTestCase)) - suite.addTest(unittest.makeSuite(MediaTestCase)) - suite.addTest(unittest.makeSuite(TranscodingTestCase)) - suite.addTest(unittest.makeSuite(RadioStationTestCase)) - - return suite diff --git a/tests/api/test_response_helper.py b/tests/api/test_response_helper.py index 78b0b54..695b480 100644 --- a/tests/api/test_response_helper.py +++ b/tests/api/test_response_helper.py @@ -194,15 +194,5 @@ class ResponseHelperXMLTestCase(TestBase, UnwrapperMixin.create_from(XMLFormatte self.assertEqual(lists[2].text, "final string") -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(ResponseHelperJsonTestCase)) - suite.addTest(unittest.makeSuite(ResponseHelperJsonpTestCase)) - suite.addTest(unittest.makeSuite(ResponseHelperXMLTestCase)) - - return suite - - if __name__ == "__main__": unittest.main() diff --git a/tests/base/__init__.py b/tests/base/__init__.py index 3633340..227addb 100644 --- a/tests/base/__init__.py +++ b/tests/base/__init__.py @@ -4,27 +4,3 @@ # Copyright (C) 2017 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. - -import unittest - -from .test_cli import CLITestCase -from .test_cache import CacheTestCase -from .test_config import ConfigTestCase -from .test_db import DbTestCase -from .test_scanner import ScannerTestCase -from .test_secret import SecretTestCase -from .test_watcher import suite as watcher_suite - - -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(CacheTestCase)) - suite.addTest(unittest.makeSuite(ConfigTestCase)) - suite.addTest(unittest.makeSuite(DbTestCase)) - suite.addTest(unittest.makeSuite(ScannerTestCase)) - suite.addTest(watcher_suite()) - suite.addTest(unittest.makeSuite(CLITestCase)) - suite.addTest(unittest.makeSuite(SecretTestCase)) - - return suite diff --git a/tests/base/test_watcher.py b/tests/base/test_watcher.py index 7720d5f..afbe728 100644 --- a/tests/base/test_watcher.py +++ b/tests/base/test_watcher.py @@ -344,14 +344,5 @@ class CoverWatcherTestCase(WatcherTestCase): self._sleep() -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(AudioWatcherTestCase)) - suite.addTest(unittest.makeSuite(CoverWatcherTestCase)) - - return suite - - if __name__ == "__main__": unittest.main() diff --git a/tests/frontend/__init__.py b/tests/frontend/__init__.py index 24bb0bb..227addb 100644 --- a/tests/frontend/__init__.py +++ b/tests/frontend/__init__.py @@ -4,21 +4,3 @@ # Copyright (C) 2017 Alban 'spl0k' Féron # # Distributed under terms of the GNU AGPLv3 license. - -import unittest - -from .test_login import LoginTestCase -from .test_folder import FolderTestCase -from .test_playlist import PlaylistTestCase -from .test_user import UserTestCase - - -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(LoginTestCase)) - suite.addTest(unittest.makeSuite(FolderTestCase)) - suite.addTest(unittest.makeSuite(PlaylistTestCase)) - suite.addTest(unittest.makeSuite(UserTestCase)) - - return suite diff --git a/tests/managers/__init__.py b/tests/managers/__init__.py index efe761b..4c9aa06 100644 --- a/tests/managers/__init__.py +++ b/tests/managers/__init__.py @@ -5,17 +5,3 @@ # 2017 Óscar García Amor # # Distributed under terms of the GNU AGPLv3 license. - -import unittest - -from .test_manager_folder import FolderManagerTestCase -from .test_manager_user import UserManagerTestCase - - -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(FolderManagerTestCase)) - suite.addTest(unittest.makeSuite(UserManagerTestCase)) - - return suite diff --git a/tests/net/__init__.py b/tests/net/__init__.py new file mode 100644 index 0000000..dbfd0d0 --- /dev/null +++ b/tests/net/__init__.py @@ -0,0 +1,28 @@ +# This file is part of Supysonic. +# Supysonic is a Python implementation of the Subsonic server API. +# +# Copyright (C) 2021 Alban 'spl0k' Féron +# +# Distributed under terms of the GNU AGPLv3 license. + +import importlib +import os +import os.path +import unittest + +from unittest.suite import TestSuite + + +def load_tests(loader, tests, pattern): + # Skip these tests from discovery + return tests + + +suite = TestSuite() +for e in os.scandir(os.path.dirname(__file__)): + if not e.name.startswith("test") or not e.name.endswith(".py"): + continue + + module = importlib.import_module("tests.net." + e.name[:-3]) + tests = unittest.defaultTestLoader.loadTestsFromModule(module) + suite.addTests(tests) diff --git a/tests/base/test_lastfm.py b/tests/net/test_lastfm.py similarity index 90% rename from tests/base/test_lastfm.py rename to tests/net/test_lastfm.py index dfa72b8..72c6355 100644 --- a/tests/base/test_lastfm.py +++ b/tests/net/test_lastfm.py @@ -12,7 +12,7 @@ from supysonic.lastfm import LastFm class LastFmTestCase(unittest.TestCase): - """ Designed only to have coverage on the most important method """ + """Designed only to have coverage on the most important method""" def test_request(self): logging.getLogger("supysonic.lastfm").addHandler(logging.NullHandler()) diff --git a/tests/api/test_lyrics.py b/tests/net/test_lyrics.py similarity index 98% rename from tests/api/test_lyrics.py rename to tests/net/test_lyrics.py index c1cfea0..158fddf 100644 --- a/tests/api/test_lyrics.py +++ b/tests/net/test_lyrics.py @@ -14,7 +14,7 @@ from pony.orm import db_session from supysonic.db import Folder, Artist, Album, Track -from .apitestbase import ApiTestBase +from ..api.apitestbase import ApiTestBase class LyricsTestCase(ApiTestBase): diff --git a/tests/with_net.py b/tests/with_net.py deleted file mode 100644 index 64a268c..0000000 --- a/tests/with_net.py +++ /dev/null @@ -1,20 +0,0 @@ -# This file is part of Supysonic. -# Supysonic is a Python implementation of the Subsonic server API. -# -# Copyright (C) 2019 Alban 'spl0k' Féron -# -# Distributed under terms of the GNU AGPLv3 license. - -import unittest - -from .api.test_lyrics import LyricsTestCase -from .base.test_lastfm import LastFmTestCase - - -def suite(): - suite = unittest.TestSuite() - - suite.addTest(unittest.makeSuite(LastFmTestCase)) - suite.addTest(unittest.makeSuite(LyricsTestCase)) - - return suite