syrusakbary / snapshottest

Snapshot Testing utils for Python 📸
MIT License
530 stars 103 forks source link

Fix pytest parametrize for multiline strings #86

Closed johnnymetz closed 5 years ago

johnnymetz commented 5 years ago

When using pytest.parametrize with multiline strings, the new line string literal \n causes the test name to change on each test run, which causes unexpected behavior.

Here's an example given the following script script.py:

import pytest

def return_one(s):
    return 1

@pytest.mark.parametrize(
    "s",
    [
        "singleline",
        """
        some
        multiline
        string
        """,
    ],
)
def test_return_one(snapshot, s):
    result = return_one(s)
    snapshot.assert_match(result)

When running pytest script.py I get 2 snapshots written which look like this:

snapshots['test_return_one[singleline] 1'] = 1

snapshots['test_return_one[\n        some\n        multiline\n        string\n        ] 1'] = 1

When running pytest script.py I get 1 snapshots written and 1 snapshots deprecated which returns an invalid python file (notice the malformed second test):

snapshots['test_return_one[singleline] 1'] = 1

snapshots['test_return_one[
                some
                multiline
                string
                ] 1'] = 1

snapshots['test_return_one[\n        some\n        multiline\n        string\n        ] 1'] = 1

This fix will return the following snapshots on each test run:

snapshots['test_return_one[singleline] 1'] = 1

snapshots['test_return_one[ some multiline string ] 1'] = 1

Using pytest parametrize for multiline strings is specifically important when using snapshottest with graphene. There should be countless other use cases besides that.