Skip to content

Commit

Permalink
Handle addcall deprecation
Browse files Browse the repository at this point in the history
Since `ptytest` v3.3.0+, `metafunc.addcall` is deprecated and is slated
to be removed in v4.0. [See changelog][1]

The recommendation is to use `metafunc.parametrize`. The twist is that
parametrization requires the value to either be taken as an argument by
the function or as a fixture. So a dynamic fixture is created and added
to each test function to avoid needing to change the test function
signatures.

Verified the change works for both v3.3.1 and v3.2.4.

Minimum repro case:

```python
""" test_file.py """

def test_asd():
    pass
```

Run: `pytest --flake-finder test_file.py`

<details>
<summary>Test output</summary>

```
================================================== test session starts
===================================================
platform linux -- Python 3.6.3, pytest-3.3.1, py-1.5.2, pluggy-0.6.0
rootdir: /home/sam/tmp, inifile:
plugins: xdist-1.20.1, forked-0.2, flakefinder-0.1.0
collected 50 items

test_file.py ..................................................
[100%]

==================================================== warnings summary
====================================================
None
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.
  Metafunc.addcall is deprecated and scheduled to be removed in pytest
4.0.
  Please use Metafunc.parametrize instead.

-- Docs: http://doc.pytest.org/en/latest/warnings.html
========================================= 50 passed, 50 warnings in 0.04
seconds =========================================

```
</details>

[1]: https://docs.pytest.org/en/latest/changelog.html#id38
  • Loading branch information
Sam Park committed Jan 10, 2018
1 parent bdfb704 commit f50a7aa
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 4 deletions.
12 changes: 10 additions & 2 deletions pytest_flakefinder.py
Expand Up @@ -50,8 +50,16 @@ def __init__(self, config):
def pytest_generate_tests(self, metafunc):
"""For all true pytest tests use metafunc to add all the duplicates."""
# This is safer because otherwise test with fixtures might not be setup correctly.
for _ in range(self.flake_runs):
metafunc.addcall()
# Parameterization requires the test function to accept the permutation as
# either an argument or depend on it as a fixture. Use fixture so the test
# function signature is not changed. Suffix with timestamp to reduce odds of
# collision with other fixture names.
fixture_name = 'flakefinder-{}'.format(time.time())
metafunc.fixturenames.append(fixture_name)
metafunc.parametrize(
argnames=fixture_name,
argvalues=list(range(self.flake_runs)),
)
metafunc.function._pytest_duplicated = True

@pytest.mark.tryfirst
Expand Down
5 changes: 3 additions & 2 deletions tests/test_flakefinder.py
Expand Up @@ -35,7 +35,7 @@ def test():

# Check output.
result.stdout.fnmatch_lines(
# Wildcard at end because latest pytest pluralizes 'item'
# Wildcard at end because different Python+pytest combos pluralize 'item'
['collecting ... collected %d item*' % runs] +
# fnmatch doesn't like `[` characters so I use `?`.
['*::test?%d? PASSED*' % i for i in range(runs)]
Expand Down Expand Up @@ -66,6 +66,7 @@ def test(self):
# Check output.
result.stdout.fnmatch_lines(
# NB: unitest TestCases don't increment the collected items.
# Wildcard at end because different Python+pytest combos pluralize 'item'
['collecting ... collected 1 item*'] +
['*::TestAwesome::test PASSED*' for _ in range(runs)]
)
Expand Down Expand Up @@ -162,7 +163,7 @@ def test(self):
['*::test?%d? PASSED*' % i for i in range(min(runs, passing_runs))] +
['*::test?%d? SKIPPED*' % i for i in range(passing_runs, runs)] +
# Test for the test, make sure the time isn't modified when coming out.
['* 10 passed, 40 skipped* in ?.?? seconds *']
['* 10 passed, 40 skipped in ?.?? seconds *']
)
assert result.ret == 0

Expand Down

0 comments on commit f50a7aa

Please sign in to comment.