Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[MRG] Make tests runnable with pytest without error #8246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 20, 2017

Conversation

lesteve
Copy link
Member

@lesteve lesteve commented Jan 30, 2017

Related to #7319. This is the minimal set of changes to make the tests runnable with pytest. All in all it amounts to:

  • splitting a test function in two functions. I made sure that this was still testing correctly the fix in c31ad7a.
  • moving check_ functions using closures to module-level

Errors were due to pytest quirks with (deprecated) yield support. AFAICT the underlying reason is that pytest first collects the tests (collecting the test function and the arguments) and then runs them. It is somewhat easy to modify the arguments at collection time which creates suprises during the test run.

See below for an example test highlighting the quirk:

class A(object):
    def __init__(self, a):
        self.a = a

args = [A(i) for i in [0]]


def check(x, y):
    print('\nin check:', 'x.a:', x.a, 'y.a:', y.a)
    assert x.a == y.a


def test():
    for arg in args:
        arg_copy = A(arg.a)

        print('\nin test: arg.a:', arg.a, 'arg_copy.a:', arg_copy.a)
        yield check, arg, arg_copy

        arg_copy.a = -100
        assert arg_copy.a == -100

Output:

❯ pytest -s test_pytest.py
======================================================== test session starts =========================================================
platform linux -- Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /tmp, inifile: 
plugins: cov-2.3.1
collecting 0 items
in test: arg.a: 0 arg_copy.a: 0
collected 1 items 

test_pytest.py 
in check: x.a: 0 y.a: -100
F

============================================================== FAILURES ==============================================================
______________________________________________________________ test[0] _______________________________________________________________

x = <test_pytest.A object at 0x7efcd0c6ab38>, y = <test_pytest.A object at 0x7efcd0716048>

    def check(x, y):
        print('\nin check:', 'x.a:', x.a, 'y.a:', y.a)
>       assert x.a == y.a
E       assert 0 == -100
E        +  where 0 = <test_pytest.A object at 0x7efcd0c6ab38>.a
E        +  and   -100 = <test_pytest.A object at 0x7efcd0716048>.a

test_pytest.py:10: AssertionError
======================================================= pytest-warning summary =======================================================
WC1 /tmp/test_pytest.py yield tests are deprecated, and scheduled to be removed in pytest 4.0
============================================ 1 failed, 1 pytest-warnings in 0.05 seconds =============================================

@lesteve
Copy link
Member Author

lesteve commented Feb 1, 2017

ping @karandesai-96 just in case you are interested to have some kind of explanation about the weird failure we were seeing with yield in joblib.

@kdexd
Copy link

kdexd commented Feb 1, 2017

Pytest >= 3.0.0 has dropped support of yield based tests. Basically we can look at yield statements in tests to be invocations of the test for different test cases. Pytest has a mechanism which registers the total number of tests (multiple invocations of same test included). Multiple invocations are registered through the @parametrize marker, or by looking whether the fixture required by test is parametrized (that is, whether it has params kwarg in @pytest.fixture decorator).

So yield based tests in their original form throw a pytest warning, but fiddling with them by passing fixtures or parametrize markers broke them. That's all I can say here. 😄

@lesteve lesteve mentioned this pull request Feb 1, 2017
@lesteve
Copy link
Member Author

lesteve commented Feb 2, 2017

Tests added. Ooops wrong PR ...

@lesteve
Copy link
Member Author

lesteve commented Feb 9, 2017

ping @jnothman @ogrisel.

@jnothman
Copy link
Member

jnothman commented Feb 9, 2017

@lesteve, I'm not yet familiar with py.tests or its quirks, so I feel under-qualified to give a thorough review. But I appreciate the risk of merge conflicts, so will do what I can.

@jnothman
Copy link
Member

jnothman commented Feb 9, 2017

Regarding the quirk you describe above, is one option to wrap the generators so that all yielded arguments are deepcopied during iteration?

@jnothman
Copy link
Member

jnothman commented Feb 9, 2017

I realise that won't fix the issue with closures.

@jnothman
Copy link
Member

jnothman commented Feb 9, 2017

Without a wrapper like that, it seems one needs to carefully check that all arguments are immutable or otherwise unmodified. I'd rather something with assurances like a deepcopy of all arguments..?

@jnothman
Copy link
Member

jnothman commented Feb 9, 2017

I think if we're going to support pytest we need CI to ensure it continues to work. Add a travis build that uses pytest??

@lesteve
Copy link
Member Author

lesteve commented Feb 9, 2017

I think if we're going to support pytest we need CI to ensure it continues to work. Add a travis build that uses pytest??

I was thinking about pytest as a "use at your own risks" kind of thing for now, hence the minimal PR. Given the limited set of changes I had to do to get the tests running without error with pytest, I am strongly encouraged to think that going forward the tests pass will pass with pytest if they pass with nose.

As soon as this PR is merged, I will use pytest to run the tests and I am willing to iron out any quirks, if any, that we find along the road.

@jnothman
Copy link
Member

I don't see much harm in a pytest CI run during the transition. @ogrisel?

@codecov
Copy link

codecov bot commented Feb 14, 2017

Codecov Report

Merging #8246 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #8246      +/-   ##
==========================================
+ Coverage   94.75%   94.75%   +<.01%     
==========================================
  Files         342      342              
  Lines       60801    60804       +3     
==========================================
+ Hits        57609    57612       +3     
  Misses       3192     3192
Impacted Files Coverage Δ
sklearn/neighbors/tests/test_kd_tree.py 97.45% <100%> (ø)
sklearn/neighbors/tests/test_kde.py 98.85% <100%> (ø)
sklearn/gaussian_process/tests/test_kernels.py 98.85% <100%> (+0.02%)
sklearn/neighbors/tests/test_ball_tree.py 98% <100%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80c1bf1...ba64c10. Read the comment docs.

@lesteve
Copy link
Member Author

lesteve commented Feb 14, 2017

I added a build on Travis that uses pytest.

Note that at the moment pytest does not run doctests from the rst in the doc folder. It seems like there is no easy way to do that and that pytest and nosetests are quite different on this topic so I would advise to tackle this when we drop nose.

@lesteve
Copy link
Member Author

lesteve commented Feb 16, 2017

@ogrisel feel free to take a look at this if you have a bit of time

Errors were due to pytest quirks with (deprecated) yield support.
and tweak pytest settings in setup.cfg
@codecov-io
Copy link

Codecov Report

Merging #8246 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #8246      +/-   ##
==========================================
+ Coverage   94.75%   94.75%   +<.01%     
==========================================
  Files         342      342              
  Lines       60801    60804       +3     
==========================================
+ Hits        57609    57612       +3     
  Misses       3192     3192
Impacted Files Coverage Δ
sklearn/neighbors/tests/test_ball_tree.py 98% <100%> (ø)
sklearn/neighbors/tests/test_kde.py 98.85% <100%> (ø)
sklearn/neighbors/tests/test_kd_tree.py 97.45% <100%> (ø)
sklearn/gaussian_process/tests/test_kernels.py 98.85% <100%> (+0.02%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80c1bf1...af94767. Read the comment docs.

@codecov-io
Copy link

codecov-io commented Feb 20, 2017

Codecov Report

Merging #8246 into master will increase coverage by <.01%.
The diff coverage is 100%.

@@            Coverage Diff             @@
##           master    #8246      +/-   ##
==========================================
+ Coverage   94.75%   94.75%   +<.01%     
==========================================
  Files         342      342              
  Lines       60801    60816      +15     
==========================================
+ Hits        57609    57624      +15     
  Misses       3192     3192
Impacted Files Coverage Δ
sklearn/neighbors/tests/test_kde.py 98.85% <100%> (ø)
sklearn/gaussian_process/tests/test_kernels.py 98.85% <100%> (+0.02%)
sklearn/neighbors/tests/test_ball_tree.py 98% <100%> (ø)
sklearn/neighbors/tests/test_kd_tree.py 97.45% <100%> (ø)
sklearn/linear_model/tests/test_randomized_l1.py 100% <ø> (ø)
sklearn/model_selection/tests/test_search.py 99.31% <ø> (ø)
sklearn/linear_model/randomized_l1.py 94.76% <ø> (+0.06%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 80c1bf1...af94767. Read the comment docs.

Copy link
Member

@ogrisel ogrisel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I think this a good first step and it's nice to have both nosetests and pytest work for the next release. After 0.19 we can refactor the test suite deeper to make it more py.test native (using parametrize instead of yields) and drop nosetests support in 0.20.

@ogrisel ogrisel merged commit 0ec6664 into scikit-learn:master Feb 20, 2017
@ogrisel
Copy link
Member

ogrisel commented Feb 20, 2017

Squash merged. The changes are small so it should be easy to revert shall it causes any problem.

@lesteve lesteve deleted the make-pytest-pass branch February 20, 2017 12:11
@kdexd
Copy link

kdexd commented Feb 20, 2017

This is a good move 😄

nosetests -s --with-coverage --with-timer --timer-top-n 20 sklearn
else
nosetests -s --with-timer --timer-top-n 20 sklearn
TEST_CMD="$TEST_CMD --with-coverage"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure you mean to repeat --with-coverage here and in setting TEST_CMD above

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I'll fix that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI #8444.

sergeyf pushed a commit to sergeyf/scikit-learn that referenced this pull request Feb 28, 2017
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
@Przemo10 Przemo10 mentioned this pull request Mar 17, 2017
Sundrique pushed a commit to Sundrique/scikit-learn that referenced this pull request Jun 14, 2017
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
NelleV pushed a commit to NelleV/scikit-learn that referenced this pull request Aug 11, 2017
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
paulha pushed a commit to paulha/scikit-learn that referenced this pull request Aug 19, 2017
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
maskani-moh pushed a commit to maskani-moh/scikit-learn that referenced this pull request Nov 15, 2017
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
lemonlaug pushed a commit to lemonlaug/scikit-learn that referenced this pull request Jan 6, 2021
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants