diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 2a8b0f62..5eb20214 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -83,10 +83,36 @@ jobs: - name: Run pytest run: pytest -sv tests + tests-minimal-install: + + runs-on: ubuntu-latest + timeout-minutes: 30 + + strategy: + matrix: + python-version: ['3.9'] + + steps: + - uses: actions/checkout@v2 + + - name: Install Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: pyproject.toml + + - name: Install Python package without any extras + run: pip install -e .[tests] + + - name: Run pytest + run: pytest -sv tests -m minimal_install + + publish: name: Publish to PyPI - needs: [pre-commit, tests] + needs: [pre-commit, tests, tests-minimal-install] runs-on: ubuntu-latest steps: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1a274db..e829c587 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -62,3 +62,28 @@ jobs: env: AIIDA_WARN_v3: true run: pytest -sv tests + + tests-minimal-install: + + runs-on: ubuntu-latest + timeout-minutes: 30 + + strategy: + matrix: + python-version: ['3.9'] + + steps: + - uses: actions/checkout@v2 + + - name: Install Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: pip + cache-dependency-path: pyproject.toml + + - name: Install Python package without any extras + run: pip install -e .[tests] + + - name: Run pytest + run: pytest -sv tests -m minimal_install diff --git a/pyproject.toml b/pyproject.toml index d649255a..0292591a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -164,6 +164,9 @@ filterwarnings = [ 'ignore:Creating AiiDA configuration folder.*:UserWarning', 'ignore:Object of type .* not in session, .* operation along .* will not proceed:sqlalchemy.exc.SAWarning' ] +markers = [ + 'minimal_install: mark test as relevant for minimal install.' +] testpaths = [ 'tests' ] diff --git a/tests/cli/test_root.py b/tests/cli/test_root.py index cd194bb2..619e173c 100644 --- a/tests/cli/test_root.py +++ b/tests/cli/test_root.py @@ -32,6 +32,7 @@ def recurse_commands(command: click.Command, parents: list[str] | None = None): @pytest.mark.parametrize('command', recurse_commands(cmd_root)) @pytest.mark.parametrize('help_option', ('--help', '-h')) +@pytest.mark.minimal_install def test_commands_help_option(command, help_option): """Test the help options for all subcommands of the CLI. diff --git a/tests/test_minimal_install.py b/tests/test_minimal_install.py new file mode 100644 index 00000000..9ca3ec22 --- /dev/null +++ b/tests/test_minimal_install.py @@ -0,0 +1,20 @@ +"""Tests for a minimal install of the package without any extra dependencies. + +The unit tests in this module should be run against a minimal install of the package without any extra dependencies +installed. This guarantees that most of the code can be imported without any plugin packages being installed. +""" +import pytest + + +@pytest.mark.minimal_install +def test_imports(): + """The following modules should be importable without any plugin packages installed.""" + import aiida_common_workflows.cli + import aiida_common_workflows.common + import aiida_common_workflows.generators + import aiida_common_workflows.plugins + import aiida_common_workflows.protocol + import aiida_common_workflows.utils + import aiida_common_workflows.workflows + import aiida_common_workflows.workflows.dissociation + import aiida_common_workflows.workflows.eos # noqa: F401 diff --git a/tests/workflows/relax/test_abinit.py b/tests/workflows/relax/test_abinit.py index f1fb154a..132c7911 100644 --- a/tests/workflows/relax/test_abinit.py +++ b/tests/workflows/relax/test_abinit.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.abinit` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.abinit') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.abinit').get_input_generator() @pytest.fixture @@ -22,52 +23,52 @@ def default_builder_inputs(generate_code, generate_structure): @pytest.mark.usefixtures('pseudo_dojo_jthxml_family') -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('pseudo_dojo_jthxml_family') @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) @pytest.mark.usefixtures('pseudo_dojo_jthxml_family') -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('pseudo_dojo_jthxml_family') -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('pseudo_dojo_jthxml_family') @pytest.mark.filterwarnings('ignore: input magnetization per site was None') -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_bigdft.py b/tests/workflows/relax/test_bigdft.py index de0f9b50..1363ef95 100644 --- a/tests/workflows/relax/test_bigdft.py +++ b/tests/workflows/relax/test_bigdft.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.bigdft` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.bigdft') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.bigdft').get_input_generator() @pytest.fixture @@ -21,47 +22,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_castep.py b/tests/workflows/relax/test_castep.py index bf0f1c39..00e36ad2 100644 --- a/tests/workflows/relax/test_castep.py +++ b/tests/workflows/relax/test_castep.py @@ -1,28 +1,17 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.castep` module.""" - import copy import pytest from aiida import engine, plugins from aiida.orm import StructureData from aiida.plugins import WorkflowFactory -from aiida_castep.data.otfg import OTFGGroup -from aiida_common_workflows.workflows.relax.castep.generator import ( - CastepCommonRelaxInputGenerator, - ElectronicType, - RelaxType, - SpinType, - ensure_otfg_family, - generate_inputs, - generate_inputs_base, - generate_inputs_calculation, - generate_inputs_relax, -) -from aiida_common_workflows.workflows.relax.castep.workchain import CastepCommonRelaxWorkChain +from aiida_common_workflows.common import ElectronicType, RelaxType, SpinType from ase.build.bulk import bulk -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.castep') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.castep').get_input_generator() @pytest.fixture @@ -50,6 +39,8 @@ def castep_code(generate_code): @pytest.fixture def with_otfg(with_database): """Ensure has OTFG""" + from aiida_common_workflows.workflows.relax.castep.generator import ensure_otfg_family + ensure_otfg_family('C19') @@ -64,54 +55,57 @@ def default_builder_inputs(generate_code, generate_structure, castep_code): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) def test_calc_generator(nacl, castep_code, with_otfg): """Test the functionality of the calculation generator""" + from aiida_castep.data.otfg import OTFGGroup + from aiida_common_workflows.workflows.relax.castep.generator import generate_inputs_calculation + protcol = { 'kpoints_spacing': 0.05, 'calc': {'parameters': {'task': 'geometryoptimisation', 'basis_precision': 'medium'}}, @@ -128,6 +122,9 @@ def test_calc_generator(nacl, castep_code, with_otfg): def test_base_generator(castep_code, nacl, with_otfg): """Test for generating the Base namespace""" + from aiida_castep.data.otfg import OTFGGroup + from aiida_common_workflows.workflows.relax.castep.generator import generate_inputs_base + protcol = { 'kpoints_spacing': 0.05, 'max_iterations': 5, @@ -145,12 +142,12 @@ def test_base_generator(castep_code, nacl, with_otfg): assert generated['calc']['metadata']['label'] == 'test' -def test_relax_generator(castep_code, nacl, with_otfg): +def test_relax_generator(generator, castep_code, nacl, with_otfg): """Test for generating the relax namespace""" - CastepCommonRelaxWorkChain = WorkflowFactory('castep.relax') # noqa: N806 - protocol = CastepCommonRelaxInputGenerator(process_class=CastepCommonRelaxWorkChain).get_protocol('moderate')[ - 'relax' - ] + from aiida_castep.data.otfg import OTFGGroup + from aiida_common_workflows.workflows.relax.castep.generator import generate_inputs_relax + + protocol = generator.get_protocol('moderate')['relax'] override = { 'base': { 'metadata': {'label': 'test'}, @@ -170,11 +167,14 @@ def test_relax_generator(castep_code, nacl, with_otfg): assert generated['base']['metadata']['label'] == 'test' -def test_generate_inputs(castep_code, nacl, si): +def test_generate_inputs(generator, castep_code, nacl, si): """ Test for the generator """ - protocol = CastepCommonRelaxInputGenerator(process_class=CastepCommonRelaxWorkChain).get_protocol('moderate') + from aiida_common_workflows.workflows.relax.castep.generator import generate_inputs + from aiida_common_workflows.workflows.relax.castep.workchain import CastepCommonRelaxWorkChain + + protocol = generator(process_class=CastepCommonRelaxWorkChain).get_protocol('moderate') override = {'base': {'metadata': {'label': 'test'}, 'calc': {}}} output = generate_inputs(WorkflowFactory('castep.relax'), copy.deepcopy(protocol), castep_code, si, override) @@ -186,28 +186,31 @@ def test_generate_inputs(castep_code, nacl, si): assert 'structure' in output['calc'] -def test_input_generator(castep_code, nacl, si): +def test_input_generator(generator, castep_code, nacl, si): """Test for the input generator""" - gen = CastepCommonRelaxInputGenerator(process_class=CastepCommonRelaxWorkChain) engines = {'relax': {'code': castep_code, 'options': {}}} - builder = gen.get_builder(structure=si, engines=engines, protocol='moderate') + builder = generator.get_builder(structure=si, engines=engines, protocol='moderate') param = builder.calc.parameters.get_dict() assert param['cut_off_energy'] == 326 assert builder.base.kpoints_spacing == pytest.approx(0.023873, abs=1e-6) - builder = gen.get_builder(structure=si, engines=engines, protocol='moderate', relax_type=RelaxType.POSITIONS) + builder = generator.get_builder(structure=si, engines=engines, protocol='moderate', relax_type=RelaxType.POSITIONS) assert 'fix_all_cell' in builder.calc.parameters.get_dict() - builder = gen.get_builder(structure=si, engines=engines, protocol='moderate', relax_type=RelaxType.POSITIONS_SHAPE) + builder = generator.get_builder( + structure=si, engines=engines, protocol='moderate', relax_type=RelaxType.POSITIONS_SHAPE + ) assert 'fix_vol' in builder.calc.parameters.get_dict() - builder = gen.get_builder(structure=si, engines=engines, protocol='moderate', spin_type=SpinType.COLLINEAR) + builder = generator.get_builder(structure=si, engines=engines, protocol='moderate', spin_type=SpinType.COLLINEAR) assert 'SPINS' in builder.calc.settings.get_dict() - builder = gen.get_builder(structure=si, engines=engines, protocol='moderate', spin_type=SpinType.NON_COLLINEAR) + builder = generator.get_builder( + structure=si, engines=engines, protocol='moderate', spin_type=SpinType.NON_COLLINEAR + ) assert builder.calc.settings['SPINS'][0] == [1.0, 1.0, 1.0] - builder = gen.get_builder( + builder = generator.get_builder( structure=si, engines=engines, protocol='moderate', electronic_type=ElectronicType.INSULATOR ) assert builder.calc.settings is None @@ -218,6 +221,8 @@ def test_otfg_upload(with_otfg): """ Test uploading customized OTFG family """ + from aiida_castep.data.otfg import OTFGGroup + from aiida_common_workflows.workflows.relax.castep.generator import ensure_otfg_family # Initial upload ensure_otfg_family('C19V2') diff --git a/tests/workflows/relax/test_cp2k.py b/tests/workflows/relax/test_cp2k.py index 40de2478..18fa8468 100644 --- a/tests/workflows/relax/test_cp2k.py +++ b/tests/workflows/relax/test_cp2k.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.cp2k` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.cp2k') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.cp2k').get_input_generator() @pytest.fixture @@ -21,47 +22,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_fleur.py b/tests/workflows/relax/test_fleur.py index cd72d625..49a3508c 100644 --- a/tests/workflows/relax/test_fleur.py +++ b/tests/workflows/relax/test_fleur.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.fleur` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.fleur') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.fleur').get_input_generator() @pytest.fixture @@ -25,47 +26,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_gaussian.py b/tests/workflows/relax/test_gaussian.py index 67ced3a0..7dd8572c 100644 --- a/tests/workflows/relax/test_gaussian.py +++ b/tests/workflows/relax/test_gaussian.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.gaussian` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.gaussian') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.gaussian').get_input_generator() @pytest.fixture @@ -21,47 +22,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_nwchem.py b/tests/workflows/relax/test_nwchem.py index 710c8a36..1f99b386 100644 --- a/tests/workflows/relax/test_nwchem.py +++ b/tests/workflows/relax/test_nwchem.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.nwchem` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.nwchem') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.nwchem').get_input_generator() @pytest.fixture @@ -21,47 +22,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_orca.py b/tests/workflows/relax/test_orca.py index 18167b7f..59d77793 100644 --- a/tests/workflows/relax/test_orca.py +++ b/tests/workflows/relax/test_orca.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.orca` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.orca') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.orca').get_input_generator() @pytest.fixture @@ -22,51 +23,51 @@ def default_builder_inputs(generate_code, generate_structure): @pytest.mark.filterwarnings('ignore: PBC detected ') -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.filterwarnings('ignore: PBC detected ') @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) @pytest.mark.filterwarnings('ignore: PBC detected ') -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.filterwarnings('ignore: PBC detected ') -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.filterwarnings('ignore: PBC detected ') -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_quantum_espresso.py b/tests/workflows/relax/test_quantum_espresso.py index d9a95e6f..bf862086 100644 --- a/tests/workflows/relax/test_quantum_espresso.py +++ b/tests/workflows/relax/test_quantum_espresso.py @@ -1,12 +1,12 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.quantum_espresso` module.""" - import pytest from aiida import engine, plugins from aiida_common_workflows.workflows.relax.generator import ElectronicType, RelaxType, SpinType -from qe_tools import CONSTANTS -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.quantum_espresso') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.quantum_espresso').get_input_generator() @pytest.fixture @@ -24,72 +24,71 @@ def default_builder_inputs(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('sssp') @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) @pytest.mark.usefixtures('sssp') -def test_options(default_builder_inputs): +def test_options(generator, default_builder_inputs): """Test that the ``options`` of the ``engines`` argument are added to all namespaces.""" inputs = default_builder_inputs - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) assert builder.base.pw.metadata.options.resources == inputs['engines']['relax']['options']['resources'] assert builder.base_final_scf.pw.metadata.options.resources == inputs['engines']['relax']['options']['resources'] @pytest.mark.usefixtures('sssp') -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('sssp') -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('sssp') -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('sssp') -def test_relax_type(generate_code, generate_structure): +def test_relax_type(generator, generate_code, generate_structure): """Test the ``relax_type`` keyword argument.""" code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si',)) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} builder = generator.get_builder(structure=structure, engines=engines, relax_type=RelaxType.NONE) @@ -124,11 +123,10 @@ def test_relax_type(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_spin_type(generate_code, generate_structure): +def test_spin_type(generator, generate_code, generate_structure): """Test the ``spin_type`` keyword argument.""" code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si',)) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} builder = generator.get_builder(structure=structure, engines=engines, spin_type=SpinType.NONE) @@ -140,11 +138,10 @@ def test_spin_type(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_electronic_type(generate_code, generate_structure): +def test_electronic_type(generator, generate_code, generate_structure): """Test the ``electronic_type`` keyword argument.""" code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si',)) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} builder = generator.get_builder(structure=structure, engines=engines, electronic_type=ElectronicType.METAL) @@ -158,11 +155,12 @@ def test_electronic_type(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_threshold_forces(generate_code, generate_structure): +def test_threshold_forces(generator, generate_code, generate_structure): """Test the ``threshold_forces`` keyword argument.""" + from qe_tools import CONSTANTS + code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si',)) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} threshold_forces = 0.1 @@ -172,11 +170,12 @@ def test_threshold_forces(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_threshold_stress(generate_code, generate_structure): +def test_threshold_stress(generator, generate_code, generate_structure): """Test the ``threshold_stress`` keyword argument.""" + from qe_tools import CONSTANTS + code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si',)) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} threshold_stress = 0.1 @@ -186,11 +185,10 @@ def test_threshold_stress(generate_code, generate_structure): @pytest.mark.usefixtures('sssp') -def test_magnetization_per_site(generate_code, generate_structure): +def test_magnetization_per_site(generator, generate_code, generate_structure): """Test the ``magnetization_per_site`` keyword argument.""" code = generate_code('quantumespresso.pw') structure = generate_structure(symbols=('Si', 'Ge')) - generator = WORKCHAIN.get_input_generator() engines = {'relax': {'code': code, 'options': {}}} magnetization_per_site = [0.0, 0.1, 0.2] diff --git a/tests/workflows/relax/test_siesta.py b/tests/workflows/relax/test_siesta.py index 9959c4f7..a9501343 100644 --- a/tests/workflows/relax/test_siesta.py +++ b/tests/workflows/relax/test_siesta.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.siesta` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.siesta') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.siesta').get_input_generator() @pytest.fixture @@ -22,51 +23,51 @@ def default_builder_inputs(generate_code, generate_structure): @pytest.mark.usefixtures('psml_family') -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('psml_family') @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) @pytest.mark.usefixtures('psml_family') -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('psml_family') -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.usefixtures('psml_family') -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) diff --git a/tests/workflows/relax/test_vasp.py b/tests/workflows/relax/test_vasp.py index 59ca8799..b5eca1ca 100644 --- a/tests/workflows/relax/test_vasp.py +++ b/tests/workflows/relax/test_vasp.py @@ -1,10 +1,11 @@ """Tests for the :mod:`aiida_common_workflows.workflows.relax.vasp` module.""" - import pytest from aiida import engine, plugins -WORKCHAIN = plugins.WorkflowFactory('common_workflows.relax.vasp') -GENERATOR = WORKCHAIN.get_input_generator() + +@pytest.fixture +def generator(): + return plugins.WorkflowFactory('common_workflows.relax.vasp').get_input_generator() @pytest.fixture @@ -21,47 +22,47 @@ def default_builder_inputs(generate_code, generate_structure): } -def test_get_builder(default_builder_inputs): +def test_get_builder(generator, default_builder_inputs): """Test the ``get_builder`` with default arguments.""" - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) assert isinstance(builder, engine.ProcessBuilder) @pytest.mark.skip('Running this test will fail with an `UnroutableError` in `kiwipy`.') -def test_submit(default_builder_inputs): +def test_submit(generator, default_builder_inputs): """Test submitting the builder returned by ``get_builder`` called with default arguments. This will actually create the ``WorkChain`` instance, so if it doesn't raise, that means the input spec was valid. """ - builder = GENERATOR.get_builder(**default_builder_inputs) + builder = generator.get_builder(**default_builder_inputs) engine.submit(builder) -def test_supported_electronic_types(default_builder_inputs): +def test_supported_electronic_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``electronic_types``.""" inputs = default_builder_inputs - for electronic_type in GENERATOR.spec().inputs['electronic_type'].choices: + for electronic_type in generator.spec().inputs['electronic_type'].choices: inputs['electronic_type'] = electronic_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_relax_types(default_builder_inputs): +def test_supported_relax_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``relax_types``.""" inputs = default_builder_inputs - for relax_type in GENERATOR.spec().inputs['relax_type'].choices: + for relax_type in generator.spec().inputs['relax_type'].choices: inputs['relax_type'] = relax_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder) -def test_supported_spin_types(default_builder_inputs): +def test_supported_spin_types(generator, default_builder_inputs): """Test calling ``get_builder`` for the supported ``spin_types``.""" inputs = default_builder_inputs - for spin_type in GENERATOR.spec().inputs['spin_type'].choices: + for spin_type in generator.spec().inputs['spin_type'].choices: inputs['spin_type'] = spin_type - builder = GENERATOR.get_builder(**inputs) + builder = generator.get_builder(**inputs) assert isinstance(builder, engine.ProcessBuilder)