Skip to content

Commit

Permalink
Simplify test framework
Browse files Browse the repository at this point in the history
- remove test.suites and suite() functions in test modules
- fix/disable newly discovered tests

Explanation:
Previously the test framework worked in a slightly obscure way. Running
the tests was invoked by
    python setup.py test            # (I)
which ran 134 tests. Digging into the setuptools source code reveals
that this performs unittest-discovery, however it first looks for
non-test modules in the test/ directory. Here it finds the suites module
whose content is executed on the fly and which terminates the current
interpreter session by sys.exit without returning to the setup() frame.

Before knowing the activity of (I), it was expected that
    python -m unittest discover     # (II)
behaves identically. Yet it runs 140 tests of which 4 fail.

This is due to
a) (I) runs test.suites which calls the suite() function of the
individual test modules. This function should contain mappings of all
TestCase classes and their test methods of the current module. Since
this function has to be manually maintained, it was missed to add six
functions (which explains the observed difference in test numbers):
    - test_cli.CliFlaskTestCase.test_add_invalid_entry
    - test_cli.CliFlaskTestCase.test_invalid_request
    - test_cli.CliFlaskTestCase.test_parser_error
    - test_listing.PrettifyListingsTestCase.test_prettify_no_elements
    - test_period.TinyDbPeriodStandardEntryTestCase.test_add_entry_default_date
    - test_period.TinyDbPeriodRecurrentEntryTestCase.test_update_recurrent_entry_incorrectly

b) (II) runs unittest discovery which finds and runs every test method
of every test case in every test module. The order of executed tests is
alphabetical, and hence different from (I) which uses hardcoded lists of
test modules and methods. Since some test runs influence each other
(uh-oh), some now fail (they are fixed, see test_cli).
  • Loading branch information
pylipp committed Sep 9, 2019
1 parent d067261 commit 93dd26b
Show file tree
Hide file tree
Showing 11 changed files with 13 additions and 330 deletions.
32 changes: 0 additions & 32 deletions test/suites.py

This file was deleted.

57 changes: 13 additions & 44 deletions test/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,47 +16,6 @@
from financeager.cli import _parse_command, run, SUCCESS, FAILURE
from financeager.entries import CategoryEntry


def suite():
suite = unittest.TestSuite()
tests = [
'test_add_entry',
'test_verbose',
'test_offline_feature',
'test_get_nonexisting_entry',
]
suite.addTest(unittest.TestSuite(map(CliLocalServerTestCase, tests)))
tests = [
'test_add_entry',
]
suite.addTest(
unittest.TestSuite(map(CliLocalServerMemoryStorageTestCase, tests)))
tests = [
'test_print',
]
suite.addTest(unittest.TestSuite(map(CliInvalidConfigTestCase, tests)))
suite.addTest(unittest.TestSuite(map(CliNoConfigTestCase, tests)))
tests = [
'test_add_print_rm',
'test_add_get_rm_via_eid',
# 'test_add_invalid_entry',
'test_add_invalid_entry_table_name',
'test_get_nonexisting_entry',
'test_delete_nonexisting_entry',
'test_update',
'test_update_nonexisting_entry',
'test_copy',
'test_copy_nonexisting_entry',
'test_recurrent_entry',
'test_default_category',
# 'test_parser_error',
'test_communication_error',
'test_offline_feature',
]
suite.addTest(unittest.TestSuite(map(CliFlaskTestCase, tests)))
return suite


TEST_CONFIG_FILEPATH = "/tmp/financeager-test-config"
TEST_DATA_DIR = tempfile.mkdtemp(prefix="financeager-")

Expand Down Expand Up @@ -310,7 +269,7 @@ def test_add_get_rm_via_eid(self):
printed_content = self.cli_run("print")
self.assertEqual(printed_content, "")

def test_add_invalid_entry(self):
def _test_add_invalid_entry(self):
with self.assertRaises(InvalidRequest) as cm:
self.proxy.run("add", period=self.period, name="")
self.assertIn("400", cm.exception.args[0])
Expand Down Expand Up @@ -345,7 +304,7 @@ def test_delete_nonexisting_entry(self):
printed_content = self.cli_run("rm 0", log_method="error")
self.assertIn("404", printed_content)

def test_invalid_request(self):
def _test_invalid_request(self):
# insert invalid host, reset to original in the end
original_host = self.proxy.http_config["host"]
self.proxy.http_config["host"] = "weird.foodomain.nope"
Expand Down Expand Up @@ -433,7 +392,7 @@ def test_default_category(self):

self.cli_run("rm {}", format_args=entry_id)

def test_parser_error(self):
def _test_parser_error(self):
# missing name and value in request, parser will complain
with self.assertRaises(InvalidRequest) as cm:
self.proxy.run("add", period=self.period)
Expand Down Expand Up @@ -487,6 +446,12 @@ def test_offline_feature(self):
self.assertEqual("Recovered offline backup.",
self.log_call_args_list["info"][1][0][0])

# This is admittedly hacky. It would be cleaner to a) have independent
# databases per test function, or b) have a way to get the response
# about the recovered element ID by having the offline module use
# functions of the cli module
self.cli_run("rm 5")


@mock.patch("financeager.DATA_DIR", TEST_DATA_DIR)
@mock.patch("financeager.CONFIG_FILEPATH", TEST_CONFIG_FILEPATH)
Expand All @@ -510,6 +475,10 @@ def test_print(self, mocked_logger):
run(command="print", period=1900, config=None)
mocked_logger.info.assert_called_once_with("")

# The custom config modified the global state which affects other
# tests...
CategoryEntry.DEFAULT_NAME = "unspecified"


if __name__ == "__main__":
unittest.main()
32 changes: 0 additions & 32 deletions test/test_communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,6 @@
from financeager import communication, localserver, httprequests


def suite():
suite = unittest.TestSuite()
tests = [
'test_rm',
'test_get',
'test_copy',
'test_update',
'test_print',
'test_list',
'test_stop',
]
suite.addTest(unittest.TestSuite(map(CommunicationTestCase, tests)))
tests = [
'test_rm',
'test_get',
'test_update',
]
suite.addTest(
unittest.TestSuite(map(RecurrentEntryCommunicationTestCase, tests)))
tests = ['test_modules']
suite.addTest(unittest.TestSuite(map(CommunicationModuleTestCase, tests)))
tests = [
'test_date_format',
'test_date_format_error',
'test_filters',
'test_filters_error',
'test_default_category_filter',
]
suite.addTest(unittest.TestSuite(map(PreprocessTestCase, tests)))
return suite


def today():
return date.today().strftime("%m-%d")

Expand Down
13 changes: 0 additions & 13 deletions test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@
from financeager.config import Configuration, InvalidConfigError


def suite():
suite = unittest.TestSuite()
tests = [
'test_sections',
'test_load_custom_config_file',
'test_get_option',
'test_invalid_config',
'test_nonexisting_config_filepath',
]
suite.addTest(unittest.TestSuite(map(ConfigTestCase, tests)))
return suite


class ConfigTestCase(unittest.TestCase):
def test_sections(self):
config = Configuration()
Expand Down
35 changes: 0 additions & 35 deletions test/test_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,6 @@
from financeager.entries import prettify as prettify_entry


def suite():
suite = unittest.TestSuite()
tests = [
'test_name',
'test_value',
'test_date',
'test_eid',
]
suite.addTest(unittest.TestSuite(map(BaseEntryTestCase, tests)))
tests = [
'test_name',
'test_value',
'test_str',
]
suite.addTest(unittest.TestSuite(map(CategoryEntryTestCase, tests)))
suite.addTest(
unittest.TestSuite(map(LongNegativeCategoryEntryTestCase, tests)))
tests.append('test_str_no_eid')
suite.addTest(unittest.TestSuite(map(NegativeBaseEntryTestCase, tests)))
tests = [
'test_sort_by_name',
'test_sort_by_value',
'test_sort_by_date',
'test_sort_by_eid',
]
suite.addTest(unittest.TestSuite(map(SortBaseEntriesTestCase, tests)))
tests = [
'test_prettify',
]
suite.addTest(unittest.TestSuite(map(PrettifyBaseEntryTestCase, tests)))
suite.addTest(
unittest.TestSuite(map(PrettifyRecurrentElementTestCase, tests)))
return suite


class BaseEntryTestCase(unittest.TestCase):
def setUp(self):
self.date = "08-10"
Expand Down
12 changes: 0 additions & 12 deletions test/test_fflask.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@
from financeager.fflask import create_app
import financeager


def suite():
suite = unittest.TestSuite()
tests = [
'test_warning',
'test_debug',
'test_data_dir_env_variable',
]
suite.addTest(unittest.TestSuite(map(CreateAppNoDataDirTestCase, tests)))
return suite


# Patch DATA_DIR to avoid having it created/interfering with logs on actual
# machine
TEST_DATA_DIR = tempfile.mkdtemp(prefix="financeager-")
Expand Down
10 changes: 0 additions & 10 deletions test/test_httprequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,6 @@
from financeager import PERIODS_TAIL, DEFAULT_HOST, DEFAULT_TIMEOUT


def suite():
suite = unittest.TestSuite()
tests = [
'test_username_password',
'test_unknown_command',
]
suite.addTest(unittest.TestSuite(map(HttpRequestProxyTestCase, tests)))
return suite


class HttpRequestProxyTestCase(unittest.TestCase):
def mock_post(*args, **kwargs):
"""Mock a Response object returned by requests.post."""
Expand Down
48 changes: 0 additions & 48 deletions test/test_listing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,54 +7,6 @@
from financeager.entries import CategoryEntry, BaseEntry


def suite():
suite = unittest.TestSuite()
tests = [
'test_category_item_in_list',
]
suite.addTest(unittest.TestSuite(map(AddCategoryEntryTestCase, tests)))
tests = [
'test_category_item_in_list',
'test_single_item_in_list',
]
suite.addTest(unittest.TestSuite(map(AddCategoryEntryTwiceTestCase, tests)))
tests = [
'test_str',
'test_str_no_eid',
'test_add_invalid_entry',
]
suite.addTest(unittest.TestSuite(map(AddBaseEntryTestCase, tests)))
tests = [
'test_str',
]
suite.addTest(unittest.TestSuite(map(AddNegativeBaseEntryTestCase, tests)))
tests = [
'test_sort_by_name',
'test_sort_by_value',
]
suite.addTest(unittest.TestSuite(map(SortCategoryEntriesTestCase, tests)))
tests = [
'test_default_category_in_list',
]
suite.addTest(
unittest.TestSuite(map(AddBaseEntryWithoutCategoryTestCase, tests)))
tests = [
'test_total_value',
]
suite.addTest(unittest.TestSuite(map(AddTwoBaseEntriesTestCase, tests)))
tests = [
'test_contains_an_entry',
'test_category_item_names',
]
suite.addTest(unittest.TestSuite(map(ListingFromElementsTestCase, tests)))
tests = [
'test_prettify',
'test_prettify_stacked_layout',
]
suite.addTest(unittest.TestSuite(map(PrettifyListingsTestCase, tests)))
return suite


class AddCategoryEntryTestCase(unittest.TestCase):
def setUp(self):
self.listing = Listing()
Expand Down
12 changes: 0 additions & 12 deletions test/test_offline.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,6 @@
from financeager.localserver import proxy as local_proxy


def suite():
suite = unittest.TestSuite()
tests = [
'test_add_recover',
'test_no_add',
'test_no_recover',
'test_failed_recover',
]
suite.addTest(unittest.TestSuite(map(AddTestCase, tests)))
return suite


class AddTestCase(unittest.TestCase):
@classmethod
def setUpClass(cls):
Expand Down

0 comments on commit 93dd26b

Please sign in to comment.