:orphan:

===================================
PROPOSAL: Parametrize with fixtures
===================================

.. warning::

    This document outlines a proposal around using fixtures as input
    of parametrized tests or fixtures.

Problem
-------

As a user I have functional tests that I would like to run against various
scenarios.

In this particular example we want to generate a new project based on a
cookiecutter template. We want to test default values but also data that
emulates user input.

- use default values

- emulate user input

  - specify 'author'

  - specify 'project_slug'

  - specify 'author' and 'project_slug'

This is how a functional test could look like:

.. code-block:: python

    import pytest


    @pytest.fixture
    def default_context():
        return {"extra_context": {}}


    @pytest.fixture(
        params=[
            {"author": "alice"},
            {"project_slug": "helloworld"},
            {"author": "bob", "project_slug": "foobar"},
        ]
    )
    def extra_context(request):
        return {"extra_context": request.param}


    @pytest.fixture(params=["default", "extra"])
    def context(request):
        if request.param == "default":
            return request.getfuncargvalue("default_context")
        else:
            return request.getfuncargvalue("extra_context")


    def test_generate_project(cookies, context):
        """Call the cookiecutter API to generate a new project from a
        template.
        """
        result = cookies.bake(extra_context=context)

        assert result.exit_code == 0
        assert result.exception is None
        assert result.project.isdir()


Issues
------

* By using ``request.getfuncargvalue()`` we rely on actual fixture function
  execution to know what fixtures are involved, due to it's dynamic nature
* More importantly, ``request.getfuncargvalue()`` cannot be combined with
  parametrized fixtures, such as ``extra_context``
* This is very inconvenient if you wish to extend an existing test suite by
  certain parameters for fixtures that are already used by tests

pytest version 3.0 reports an error if you try to run above code::

    Failed: The requested fixture has no parameter defined for the current
    test.

    Requested fixture 'extra_context'


Proposed solution
-----------------

A new function that can be used in modules can be used to dynamically define
fixtures from existing ones.

.. code-block:: python

    pytest.define_combined_fixture(
        name="context", fixtures=["default_context", "extra_context"]
    )

The new fixture ``context`` inherits the scope from the used fixtures and yield
the following values.

- ``{}``

- ``{'author': 'alice'}``

- ``{'project_slug': 'helloworld'}``

- ``{'author': 'bob', 'project_slug': 'foobar'}``

Alternative approach
--------------------

A new helper function named ``fixture_request`` would tell pytest to yield
all parameters marked as a fixture.

.. note::

    The `pytest-lazy-fixture <https://pypi.org/project/pytest-lazy-fixture/>`_ plugin implements a very
    similar solution to the proposal below, make sure to check it out.

.. code-block:: python

    @pytest.fixture(
        params=[
            pytest.fixture_request("default_context"),
            pytest.fixture_request("extra_context"),
        ]
    )
    def context(request):
        """Returns all values for ``default_context``, one-by-one before it
        does the same for ``extra_context``.

        request.param:
            - {}
            - {'author': 'alice'}
            - {'project_slug': 'helloworld'}
            - {'author': 'bob', 'project_slug': 'foobar'}
        """
        return request.param

The same helper can be used in combination with ``pytest.mark.parametrize``.

.. code-block:: python


    @pytest.mark.parametrize(
        "context, expected_response_code",
        [
            (pytest.fixture_request("default_context"), 0),
            (pytest.fixture_request("extra_context"), 0),
        ],
    )
    def test_generate_project(cookies, context, exit_code):
        """Call the cookiecutter API to generate a new project from a
        template.
        """
        result = cookies.bake(extra_context=context)

        assert result.exit_code == exit_code
