New issue 440: parametrized fixture output captured inconsistently
https://bitbucket.org/hpk42/pytest/issue/440/parametrized-fixture-output-captured

Jurko Gospodnetić:

When using parametrized module scoped fixtures, their finalization output gets 
captured inconsistently. It does not get captured for a test run with the 
initial parametrization, but tests run using a non-initial parametrization 
capture output from the previous parametrization's finalization instead.

The following test demonstrates the issue. You can run is as a part of the 
internal pytest test suite:

```
import fnmatch

def test_module_fixture_finalizer_output_capture(testdir):
    """
    Parametrized module scoped fixture output should be captured consistently
    and separately for each test using that fixture.

    If the fixture code produces output, that output should be consistently
    captured for every test using any of that fixture's parametrizations -
    either it should or it should not be captured for every such test, but it
    must not be captured only for some of them.

    Also, if a fixture produces output for a specific fixture parametrization,
    that output must not be captured for tests using a different fixture
    parametrization.

    Demonstrates a defect in pytest 2.5.0 where module scoped parametrized
    fixtures do not get their finalization output captured for their initial
    parametrization, but each test run using a non-initial parametrization
    captures finalization output from the previous parametrization.

    """
    testdir.makepyfile(r"""\
import pytest

@pytest.fixture(scope="module", params=["A", "B", "C"])
def ola(request):
    print("<KISS> %s - in the fixture" % (request.param,))
    class frufru:
        def __init__(self, param):
            self.param = param
        def __call__(self):
            print("<KISS> %s - in the finalizer" % (self.param,))
    request.addfinalizer(frufru(request.param))
    return request.param

def test_me(ola):
    print("<KISS> %s - in the test" % (ola,))
    pytest.fail()
""")

    expected_params = "ABC"

    result = testdir.runpytest("--tb=short", "-q")
    output = result.stdout.get_lines_after("*=== FAILURES ===*")

    # Collect reported captured output lines for each test.
    in_output_block = False
    test_outputs = []
    for line in output:
        if in_output_block:
            if line.startswith("<KISS> "):
                test_outputs[-1].append(line[7:])
                # Check expected output line formatting.
                assert line[7] in expected_params
                assert line[8:].startswith(" - ")
            else:
                in_output_block = False
        elif fnmatch.fnmatch(line, "*--- Captured stdout ---*"):
            in_output_block = True
            test_outputs.append([])
        else:
            # Sanity check - no lines except reported output lines should match
            # our expected output line formatting.
            assert not line.startswith("<KISS>")

    # We ran a single test for each fixture parametrization.
    assert len(test_outputs) == len(expected_params)

    content_0 = None
    for test_param_index, single_test_output in enumerate(test_outputs):
        # All lines belonging to a single test should report using the same
        # fixture parameter.
        param = single_test_output[0][0]
        for line_index, line in enumerate(single_test_output):
            assert line[0] == param

        # All tests should output the same content except for the param value.
        content = [line[1:] for line in single_test_output]
        if content_0 is None:
            content_0 = content
        else:
            assert content == content_0
```

The test could be made shorter and use more precise assertions but I did not 
want for it to assert the exact logged output, but only that the output be 
consistent for tests run using all the different parametrizations.

Hope this helps.

Best regards,
  Jurko Gospodnetić



_______________________________________________
pytest-commit mailing list
pytest-commit@python.org
https://mail.python.org/mailman/listinfo/pytest-commit

Reply via email to