Customize instance fixture


Customize instance fixture

This will let us pass overrides for each test.

The instance fixture still provides our default instance:

def test_instance(instance):
    assert isinstance(instance.run_launcher, EcsRunLauncher)

But tests can also use the lower level instance_cm fixture to
customize the Dagster Instance (while still reaping the benefit of
ignoring the minutia of the stub_aws and metadata test setup):

def test_instance(instance_cm):
    with instance_cm({"container_name": "foo"}) as instance:
        assert isinstance(instance.run_launcher, EcsRunLauncher)
        assert instance.container_name == "foo"

The reason instance_cm returns a contextmanager rather than yielding
the instance directly is because when you yield a function that yields,
it returns a generator and not the thing being yielded. So callers would
need to call next(instance) to actually get their instance. Rough.

Another approach I looked at was using pytest parameterization:

def instance_config():
    return {}

def instance(stub_aws, metadata, instance_config):
    overrides = {
        "run_launcher": {
            "module": "dagster_aws.ecs",
            "class": "EcsRunLauncher",
            "config": {**(instance_config or {})},

    with instance_for_test(overrides) as instance:
        yield instance

def test_instance(instance):
    # If you don't parametrize, it uses the default `instance_config`.
    assert isinstance(instance.run_launcher, EcsRunLauncher)

@pytest.mark.parametrize("instance_config", [{"container_name": "foo"})
def test_instance_parametrized(instance):
    assert isinstance(instance.run_launcher, EcsRunLauncher)
    assert instance.container_name == "foo"

While perhaps better adhering to pytest idioms, it's an inelegent
solution for two reasons:

  1. You can't easily parametrize the same fixture multiple times. So a test that needs multiple instances - each with their own config - is diffult to achieve.
  2. There's not an easy way for the parameter itself to source from a fixture (like if instead of {"container_name": "foo"}, we wanted {"container_name": foo_fixture}. This means we cede control of the fixture setup/teardown chain because we can't make our instance fixture depend on another fixture.

Test Plan: unit

Reviewers: dgibson, johann, alangenfeld

Reviewed By: dgibson

Differential Revision: https://dagster.phacility.com/D8637


jordansandersAuthored on Jun 30 2021, 4:13 PM
Differential Revision
D8637: Customize instance fixture
R1:95cbb3674d39: Stub AWS before instance construction