Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestMigration setUpClass #96

Closed
wants to merge 6 commits into from
Closed

TestMigration setUpClass #96

wants to merge 6 commits into from

Conversation

eagmon
Copy link
Contributor

@eagmon eagmon commented Oct 26, 2021

Create TestMigration setUpClass method suggested by @1fish2 in #91. This allows us to load sim_data only once for all the migration tests, and saves pytest a lot of time.

@eagmon eagmon changed the title Test migration TestMigration setUpClass Oct 26, 2021
Copy link
Contributor

@1fish2 1fish2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. Can this use the normal pytest runner?

The test framework has features to make testing easier including discovering the test cases so you needn't build a collection of them, an annotation to skip a specific test, CLI args to run all or specific tests or named tests or start with the tests that failed last time, and setUp/tearDown methods.

class TestMigration:
    sim_data = None

    @classmethod
    def setUpClass(cls):
        self.sim_data = LoadSimData(sim_data_path=SIM_DATA_PATH, seed=0)

    @classmethod
    def tearDownClass(cls):
        self.sim_data = None  # not really needed

    def test_metabolism_migration():
        config = self.sim_data.get_metabolism_config()
        ...

    # ...

If for some reason you need test functions instead of test classes, I think setUpModule() handles setup work for a source file's test functions.

One can create modular pytest fixtures so test methods can easily ask for inputs, ways to run a test on a collection of inputs, capture python warnings, and more. There are also pre-provided fixtures that do things like capture stdout and stderr, parameterize test cases, cache values across pytest runs, make a tempdir, temporarily monkey-patch something.

I haven't yet used fixtures but I think using them for data injection looks like this:

import pytest

_sim_data = None

@pytest.fixture
def sim_data():
    if _sim_data is None:
        _sim_data = LoadSimData(sim_data_path=SIM_DATA_PATH, seed=0)
    return _sim_data

def test_metabolism_migration(sim_data):
    config = sim_data.get_metabolism_config()
    ...

def test_something_else(sim_data):
    ...

and the fixture could be in one module and used in all the others. That'd only load sim_data once. If need be, the fixture could do a deepcopy() of the sim_data each time. That'd be a lot faster than reloading a pickle file, while insulating the tests from any other tests that mutate sim_data.

@1fish2
Copy link
Contributor

1fish2 commented Oct 26, 2021

I forgot the self arg for def test_metabolism_migration(self).

It looks like we can use Python style names setup_class(cls) and teardown_class(cls) in place of the Java-style names setUpClass(cls) in Python's built-in unittest library. With unittest, I think a test class has to subclass unittest.TestCase, and that might be needed to use setUpClass(cls) et al. Unittest does ordinary OOP. pytest does lots of reflection to save boilerplate.

@eagmon eagmon closed this Dec 9, 2021
@eagmon eagmon deleted the test-migration branch March 31, 2022 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants