Skip to content

[MRG]Fix pytest message that silently passes no matter if it should #12001

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 2 commits into from
Sep 4, 2018

Conversation

wdevazelhes
Copy link
Contributor

What does this implement/fix? Explain your changes.

I found that there were two tests using with pytest.raises(SomeError, message='some message'), which does not check that the error raised is equal to 'some message', but returns 'some message' in case the statement inside the with fails. This can make the tests pass even if they should fail because the error message was the wrong one.

ParameterGrid(input)
assert str(raised_error.value) == error_message
Copy link
Contributor Author

Choose a reason for hiding this comment

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

here we want to test the exact message, and the message contains characters that can be parsed in regexp (like (), so I thought this was the way to go

Copy link
Member

Choose a reason for hiding this comment

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

Maybe use match here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't use it to avoid putting backslashes in front of parenthesis, and to be more restrictive (exact match vs partial match), but I guess indeed it is simpler with match, and match seems more used in the rest of scikit-learn

@@ -182,7 +182,7 @@ def test_check_array_force_all_finiteinvalid(value, force_all_finite,
match_msg, retype):
X = retype(np.arange(4).reshape(2, 2).astype(np.float))
X[0, 0] = value
with pytest.raises(ValueError, message=match_msg):
with pytest.raises(ValueError, match=match_msg):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here we only test that part of the message matches

@@ -172,7 +172,7 @@ def test_check_array_force_all_finite_valid(value, force_all_finite, retype):
(np.inf, 'allow-nan', 'Input contains infinity'),
(np.nan, True, 'Input contains NaN, infinity'),
(np.nan, 'allow-inf', 'force_all_finite should be a bool or "allow-nan"'),
(np.nan, 1, 'force_all_finite should be a bool or "allow-nan"')]
(np.nan, 1, 'Input contains NaN, infinity')]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here changing the test with match instead of message revealed that it was in fact failing so here is the fix

@rth
Copy link
Member

rth commented Sep 4, 2018

Which version of pytest are you using? pytest.raises(SomeError, message='some message') is indeed ignored on older pytest versions, but it should work with reasonably recent ones.

Once we figure out the minimum pytest version, we should add it to the docs...

@wdevazelhes
Copy link
Contributor Author

I use pytest 3.7.4

@wdevazelhes
Copy link
Contributor Author

After looking into the docs, I think that the message argument is not ignored in my version of pytest, but it is just that what it does is to raise a "custom error message" if the statement in the with fails (and this statement only checks the type of the error)
It does not check that the raised error message matches the expected error message, hence the test silently passing

But I also saw that indeed as you said this argument (and I think the match argument too) were introduced in recent versions of pytest and ignored before, so I can look at the version of introduction and do a PR to include it in the docs indeed

@rth
Copy link
Member

rth commented Sep 4, 2018

Yes, I was confusing message and match arguments. In this PR, it definitely makes sense to replace message with match, as this is a bug.

@wdevazelhes
Copy link
Contributor Author

Regarding the silent ignore of arguments in previous versions, according to this changelog, pytest.warns(match=) was introduced in v 3.3.0, pytest.raises(match=) in v 3.1.0, and pytest.raises(message=) in v 3.0.0 (I didn't see pytest.warns(message=))
so should I add pytest>=v3.3.0 here and/or here and/or here ?
In a separate PR ?

Copy link
Member

@rth rth left a comment

Choose a reason for hiding this comment

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

Minor comment below, otherwise LGTM, thanks!

should I add pytest>=v3.3.0 here and/or here and/or here ?
In a separate PR ?

+1 for a separate PR

ParameterGrid(input)
assert str(raised_error.value) == error_message
Copy link
Member

Choose a reason for hiding this comment

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

Maybe use match here?

@wdevazelhes
Copy link
Contributor Author

should I add pytest>=v3.3.0 here and/or here and/or here ?
In a separate PR ?

+1 for a separate PR

I just created the PR here: #12002

@jnothman jnothman merged commit a041821 into scikit-learn:master Sep 4, 2018
@jnothman
Copy link
Member

jnothman commented Sep 4, 2018

Thanks @wdevazelhes. Will keep a look out for these in the future.

@wdevazelhes wdevazelhes deleted the fix/fix_pytest_message branch September 5, 2018 07:00
jnothman pushed a commit to jnothman/scikit-learn that referenced this pull request Sep 6, 2018
…12001)

Previously these assertions would pass without matching.
jnothman pushed a commit to jnothman/scikit-learn that referenced this pull request Sep 17, 2018
…12001)

Previously these assertions would pass without matching.
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.

3 participants