Skip to content

Commit

Permalink
Remove message keyword argument in pytest.raises and pytest.warns (#602)
Browse files Browse the repository at this point in the history
* Remove message kwarg in pytest.raises and pytest.warns

In pytest.raises, the message argument has been used to provide a test
failure message, but it has gotten confused with the match argument
which is used to check the message from the exception to be tested so
it is being deprecated.  I changed the usage to:

    with pytest.fails(SomeException):
        should_raise_exception()
	pytest.fails("should_raise_exception() did not raise anything")

Also, we had pytest.warns(..., message="...") at one point, though it
appears pytest.warns does not do anything with the message kwarg to
begin with.  That had to be changed into a grumpier try except block.

* Improve a failure message when using pytest.warns

* Fix bug when using pytest.warns in parsing.py

* Fix bug when testing missing warnings
  • Loading branch information
namurphy committed Feb 2, 2019
1 parent 2f941f1 commit a709aa7
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 54 deletions.
17 changes: 9 additions & 8 deletions plasmapy/atomic/tests/test_atomic.py
Expand Up @@ -632,13 +632,14 @@ def test_half_life_u_220():

isotope_without_half_life_data = "No-248"

with pytest.raises(MissingAtomicDataError, message=(
with pytest.raises(MissingAtomicDataError):
half_life(isotope_without_half_life_data)
pytest.fail(
f"This test assumes that {isotope_without_half_life_data} does "
f"not have half-life data. If half-life data is added for this "
f"isotope, then a different isotope that does not have half-life "
f"data should be chosen for this test.")):

half_life(isotope_without_half_life_data)
f"data should be chosen for this test."
)


def test_known_common_stable_isotopes_cases():
Expand Down Expand Up @@ -692,9 +693,9 @@ def test_known_common_stable_isotopes_error(func):
"""Test that `known_isotopes`, `common_isotopes`, and
`stable_isotopes` raise an `~plasmapy.utils.InvalidElementError` for
neutrons."""
with pytest.raises(InvalidElementError, message=(
f"{func} is not raising a ElementError for neutrons.")):
with pytest.raises(InvalidElementError):
func('n')
pytest.fail(f"{func} is not raising a ElementError for neutrons.")


def test_isotopic_abundance():
Expand All @@ -708,9 +709,9 @@ def test_isotopic_abundance():
with pytest.warns(AtomicWarning):
isotopic_abundance('Og', 294)

with pytest.raises(InvalidIsotopeError, message="No exception raised for "
"neutrons"):
with pytest.raises(InvalidIsotopeError):
isotopic_abundance('neutron')
pytest.fail("No exception raised for neutrons.")

with pytest.raises(InvalidParticleError):
isotopic_abundance('Og-2')
Expand Down
4 changes: 2 additions & 2 deletions plasmapy/atomic/tests/test_ionization_state.py
Expand Up @@ -532,11 +532,11 @@ def test_n_e(self):
"number_densities was set.")

def test_that_negative_density_raises_error(self):
with pytest.raises(AtomicError, message="cannot be negative"):
with pytest.raises(AtomicError, match="cannot be negative"):
self.instance.number_densities = u.Quantity([-0.1, 0.2], unit=u.m**-3)

def test_incorrect_number_of_charge_states_error(self):
with pytest.raises(AtomicError, message="Incorrect number of charge states"):
with pytest.raises(AtomicError, match="Incorrect number of charge states"):
self.instance.number_densities = u.Quantity([0.1, 0.2, 0.3], unit=u.m**-3)

def test_incorrect_units_error(self):
Expand Down
6 changes: 4 additions & 2 deletions plasmapy/atomic/tests/test_ionization_states.py
Expand Up @@ -476,8 +476,9 @@ def test_attribute_exceptions(self, attribute, invalid_value, expected_exception
command = f"self.instance.{attribute} = {invalid_value}"
errmsg = f"No {expected_exception} was raised for command\n\n: {command}"

with pytest.raises(expected_exception, message=errmsg):
with pytest.raises(expected_exception):
exec(command)
pytest.fail(errmsg)

def test_setting_ionic_fractions_for_single_element(self):
"""
Expand Down Expand Up @@ -512,8 +513,9 @@ def test_setting_invalid_ionfracs(self, key, invalid_fracs, expected_exception):
errmsg = (
f"No {expected_exception} is raised when trying to assign "
f"{invalid_fracs} to {key} in an IonizationStates instance.")
with pytest.raises(expected_exception, message=errmsg):
with pytest.raises(expected_exception):
self.instance[key] = invalid_fracs
pytest.fail(errmsg)

def test_setting_incomplete_abundances(self):
new_abundances = {'H': 1, 'He': 0.1, 'Fe': 1e-5, 'Au': 1e-8} # missing lithium
Expand Down
26 changes: 16 additions & 10 deletions plasmapy/atomic/tests/test_parsing.py
Expand Up @@ -254,21 +254,22 @@ def test_parse_InvalidParticleErrors(arg, kwargs):
r"""Tests that _parse_and_check_atomic_input raises an
InvalidParticleError when the input does not correspond
to a real particle."""
with pytest.raises(InvalidParticleError, message=(
"An InvalidParticleError was expected to be raised by "
f"{_call_string(arg, kwargs)}, but no exception was raised.")):
with pytest.raises(InvalidParticleError):
_parse_and_check_atomic_input(arg, **kwargs)

pytest.fail(
"An InvalidParticleError was expected to be raised by "
f"{_call_string(arg, kwargs)}, but no exception was raised.")

@pytest.mark.parametrize('arg', ParticleZoo.everything - {'p+'})
def test_parse_InvalidElementErrors(arg):
r"""Tests that _parse_and_check_atomic_input raises an
InvalidElementError when the input corresponds to a valid
particle but not a valid element, isotope, or ion."""
with pytest.raises(InvalidElementError, message=(
"An InvalidElementError was expected to be raised by "
f"{_call_string(arg)}, but no exception was raised.")):
with pytest.raises(InvalidElementError):
_parse_and_check_atomic_input(arg)
pytest.fail(
"An InvalidElementError was expected to be raised by "
f"{_call_string(arg)}, but no exception was raised.")


# (arg, kwargs, num_warnings)
Expand All @@ -285,10 +286,15 @@ def test_parse_InvalidElementErrors(arg):
def test_parse_AtomicWarnings(arg, kwargs, num_warnings):
r"""Tests that _parse_and_check_atomic_input issues an AtomicWarning
under the required conditions. """
with pytest.warns(AtomicWarning, message=(
f"No AtomicWarning was issued by {_call_string(arg, kwargs)} but "
f"the expected number of warnings was {num_warnings}")) as record:

with pytest.warns(AtomicWarning) as record:
_parse_and_check_atomic_input(arg, **kwargs)
if not record:
pytest.fail(
f"No AtomicWarning was issued by "
f"{_call_string(arg, kwargs)} but the expected number "
f"of warnings was {num_warnings}")

assert len(record) == num_warnings, (
f"The number of AtomicWarnings issued by {_call_string(arg, kwargs)} "
f"was {len(record)}, which differs from the expected number "
Expand Down
19 changes: 10 additions & 9 deletions plasmapy/atomic/tests/test_particle_class.py
Expand Up @@ -529,12 +529,12 @@ def test_Particle_errors(arg, kwargs, attribute, exception):
Test that the appropriate exceptions are raised during the creation
and use of a `~plasmapy.atomic.Particle` object.
"""
with pytest.raises(exception, message=(
with pytest.raises(exception):
exec(f'Particle(arg, **kwargs){attribute}')
pytest.fail(
f"The following command: "
f"\n\n {call_string(Particle, arg, kwargs)}{attribute}\n\n"
f"did not raise a {exception.__name__} as expected")):
exec(f'Particle(arg, **kwargs){attribute}')

f"did not raise a {exception.__name__} as expected")

# arg, kwargs, attribute, exception
test_Particle_warning_table = [
Expand All @@ -551,12 +551,13 @@ def test_Particle_warnings(arg, kwargs, attribute, warning):
Test that the appropriate warnings are issued during the creation
and use of a `~plasmapy.atomic.Particle` object.
"""
with pytest.warns(warning, message=(
f"The following command: "
f"\n\n >>> {call_string(Particle, arg, kwargs)}{attribute}\n\n"
f"did not issue a {warning.__name__} as expected")):
with pytest.warns(warning) as record:
exec(f'Particle(arg, **kwargs){attribute}')

if not record:
pytest.fail(
f"The following command: "
f"\n\n >>> {call_string(Particle, arg, kwargs)}{attribute}\n\n"
f"did not issue a {warning.__name__} as expected")

def test_Particle_cmp():
"""Test ``__eq__`` and ``__ne__`` in the Particle class."""
Expand Down
51 changes: 30 additions & 21 deletions plasmapy/atomic/tests/test_particle_input.py
Expand Up @@ -100,9 +100,9 @@ def test_particle_input_errors(func, kwargs, expected_error):
Test that functions decorated with particle_input raise the
expected errors.
"""
with pytest.raises(expected_error, message=(
f"{func} did not raise {expected_error} with kwargs = {kwargs}")):
with pytest.raises(expected_error):
func(**kwargs)
pytest.fail(f"{func} did not raise {expected_error} with kwargs = {kwargs}")


class Test_particle_input:
Expand Down Expand Up @@ -439,20 +439,23 @@ def func_none_shall_not_pass_with_tuple(particles: (Particle, Particle)) -> \
def func_none_shall_not_pass_with_list(particles: [Particle]) -> [Particle]:
return particles

with pytest.raises(TypeError, message=(
"The none_shall_pass keyword in the particle_input decorator is "
"set to False, but is not raising a TypeError.")):
with pytest.raises(TypeError):
func_none_shall_not_pass(None)
pytest.fail(
"The none_shall_pass keyword in the particle_input "
"decorator is set to False, but is not raising a TypeError.")

with pytest.raises(TypeError, message=(
"The none_shall_pass keyword in the particle_input decorator is "
"set to False, but is not raising a TypeError.")):
with pytest.raises(TypeError):
func_none_shall_not_pass_with_tuple(('He', None))
pytest.fail(
"The none_shall_pass keyword in the particle_input "
"decorator is set to False, but is not raising a TypeError.")

with pytest.raises(TypeError, message=(
"The none_shall_pass keyword in the particle_input decorator is "
"set to False, but is not raising a TypeError.")):
with pytest.raises(TypeError):
func_none_shall_not_pass(('He', None))
pytest.fail(
"The none_shall_pass keyword in the particle_input "
"decorator is set to False, but is not raising a TypeError.")


def test_optional_particle_annotation_argname():
Expand Down Expand Up @@ -500,15 +503,20 @@ def func_not_optional_particle_with_tuple(particles: (Particle, Optional[Particl
def func_not_optional_particle_with_list(particles: [Particle]) -> [Particle]:
return particles

with pytest.raises(TypeError, message=(
"The particle keyword in the particle_input decorator received a "
"None instead of a Particle, but is not raising a TypeError.")):
with pytest.raises(TypeError):
func_not_optional_particle_with_tuple((None, 'He'))
pytest.fail(
"The particle keyword in the particle_input decorator "
"received None instead of a Particle, but is not raising a "
"TypeError.")

with pytest.raises(TypeError):

with pytest.raises(TypeError, message=(
"The particle keyword in the particle_input decorator received a "
"None instead of a Particle, but is not raising a TypeError.")):
func_not_optional_particle_with_list(('He', None))
pytest.fail(
"The particle keyword in the particle_input decorator "
"received None instead of a Particle, but is not raising a "
"TypeError.")


# TODO: The following tests might be able to be cleaned up and/or
Expand Down Expand Up @@ -575,11 +583,12 @@ def test_not_element(particle):
`~plasmapy.atomic.Particle` is named 'element', but the annotated
argument ends up not being an element, isotope, or ion.
"""
with pytest.raises(InvalidElementError, message=(
"@particle_input is not raising an InvalidElementError for "
f"{repr(particle)} even though the annotated argument is named "
"'element'.")):
with pytest.raises(InvalidElementError):
function_with_element_argument(particle)
pytest.fail(
"@particle_input is not raising an InvalidElementError for "
f"{repr(particle)} even though the annotated argument is "
f"named 'element'.")


@pytest.mark.parametrize('isotope', is_isotope)
Expand Down
4 changes: 2 additions & 2 deletions plasmapy/utils/checks.py
Expand Up @@ -50,7 +50,7 @@ def check_quantity(**validations: Dict[str, bool]):
astropy.units.core.UnitConversionError: The argument x to func should be a Quantity with the following units: m
>>> import pytest # to show the UnitsWarning
>>> with pytest.warns(u.UnitsWarning, message="Assuming units of m."):
>>> with pytest.warns(u.UnitsWarning, match="Assuming units of m."):
... func(1)
<Quantity 1. m>
Expand Down Expand Up @@ -106,7 +106,7 @@ def check_quantity(**validations: Dict[str, bool]):
Notes
-----
This functionality may end up becoming deprecated due to
This functionality may end up becoming deprecated due to
noncompliance with the `IEEE 754 standard
<https://en.wikipedia.org/wiki/IEEE_754#Exception_handling>`_
and in favor of `~astropy.units.quantity_input`.
Expand Down

0 comments on commit a709aa7

Please sign in to comment.