Repository: PlasmaPy/PlasmaPy

Issue:
Numpy isnan bug in plasmapy.formulary.parameters.gyroradius()
I recently experienced an error during an ion gyroradius calculation: `ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`. The problem seems to stem from the line:

`if not np.isnan(T_i):`
 
in

`plasmapy.formulary.parameters.gyroradius()`

It looks like you're expecting `T_i` to be a scalar but in my case it was an array. 

To reproduce, you can run `plasmapy.formulary.parameters.gyroradius(B, 'p', T_i=T_i)` with a `T_i` that's an array.


Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) Report
> Merging [#1430](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (8eb9242) into [main](https://codecov.io/gh/PlasmaPy/PlasmaPy/commit/5681a0f86fa8c7536328160745d72d9980aac7ce?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) (5681a0f) will **decrease** coverage by `0.62%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430/graphs/tree.svg?width=650&height=150&src=pr&token=LzZ5mnXVad&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)

```diff
@@            Coverage Diff             @@
##             main    #1430      +/-   ##
==========================================
- Coverage   97.11%   96.48%   -0.63%     
==========================================
  Files          77       78       +1     
  Lines        7406     7787     +381     
==========================================
+ Hits         7192     7513     +321     
- Misses        214      274      +60     
```


| [Impacted Files](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy) | Coverage Δ | |
|---|---|---|
| [plasmapy/formulary/parameters.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy#diff-cGxhc21hcHkvZm9ybXVsYXJ5L3BhcmFtZXRlcnMucHk=) | `99.15% <100.00%> (-0.03%)` | :arrow_down: |
| [plasmapy/analysis/nullpoint.py](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy#diff-cGxhc21hcHkvYW5hbHlzaXMvbnVsbHBvaW50LnB5) | `84.49% <0.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy). Last update [5681a0f...8eb9242](https://codecov.io/gh/PlasmaPy/PlasmaPy/pull/1430?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=PlasmaPy).


Patch:
diff --git a/changelog/1430.bugfix.rst b/changelog/1430.bugfix.rst
new file mode 100644
index 00000000..4faac207
--- /dev/null
+++ b/changelog/1430.bugfix.rst
@@ -0,0 +1,5 @@
+For `~plasmapy.formulary.parameters.gyroradius`, updated the default
+keyword arguments and conditional for issuing the
+`~plasmapy.utils.exceptions.PlasmaPyFutureWarning`.  This addresses the
+incorrect behavior where a `ValueError` is raised if an array is passed
+to the deprecated keyword ``T_i``.
diff --git a/changelog/1430.trivial.rst b/changelog/1430.trivial.rst
new file mode 100644
index 00000000..adcffb36
--- /dev/null
+++ b/changelog/1430.trivial.rst
@@ -0,0 +1,2 @@
+Consolidated and parametrized tests associated with
+`~plasmapy.formulary.parameters.gyroradius`.
diff --git a/plasmapy/formulary/parameters.py b/plasmapy/formulary/parameters.py
index ad848081..7090de0a 100644
--- a/plasmapy/formulary/parameters.py
+++ b/plasmapy/formulary/parameters.py
@@ -1299,8 +1299,16 @@ def gyrofrequency(B: u.T, particle: Particle, signed=False, Z=None) -> u.rad / u
 
 @validate_quantities(
     Vperp={"can_be_nan": True},
-    T_i={"can_be_nan": True, "equivalencies": u.temperature_energy()},
-    T={"can_be_nan": True, "equivalencies": u.temperature_energy()},
+    T_i={
+        "can_be_nan": True,
+        "equivalencies": u.temperature_energy(),
+        "none_shall_pass": True,
+    },
+    T={
+        "can_be_nan": True,
+        "equivalencies": u.temperature_energy(),
+        "none_shall_pass": True,
+    },
     validations_on_return={"equivalencies": u.dimensionless_angles()},
 )
 def gyroradius(
@@ -1308,8 +1316,8 @@ def gyroradius(
     particle: Particle,
     *,
     Vperp: u.m / u.s = np.nan * u.m / u.s,
-    T_i: u.K = np.nan * u.K,
-    T: u.K = np.nan * u.K,
+    T_i: u.K = None,
+    T: u.K = None,
 ) -> u.m:
     r"""Return the particle gyroradius.
 
@@ -1406,13 +1414,21 @@ def gyroradius(
     """
 
     # Backwards Compatibility and Deprecation check for keyword T_i
-    if not np.isnan(T_i):
+    if T_i is not None:
         warnings.warn(
             "Keyword T_i is deprecated, use T instead.",
             PlasmaPyFutureWarning,
         )
-        if np.isnan(T):
+        if T is None:
             T = T_i
+        else:
+            raise ValueError(
+                "Keywords T_i and T are both given.  T_i is deprecated, "
+                "please use T only."
+            )
+
+    if T is None:
+        T = np.nan * u.K
 
     isfinite_T = np.isfinite(T)
     isfinite_Vperp = np.isfinite(Vperp)
diff --git a/setup.cfg b/setup.cfg
index 3a44da17..21928f62 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -76,6 +76,7 @@ tests =
   pytest >= 5.1
   hypothesis
   pytest-regressions
+  pytest-xdist
 docs =
   # ought to mirror requirements/docs.txt
   %(extras)s


Test patch:
diff --git a/plasmapy/formulary/tests/test_parameters.py b/plasmapy/formulary/tests/test_parameters.py
index 8e94ec9a..a1f5d738 100644
--- a/plasmapy/formulary/tests/test_parameters.py
+++ b/plasmapy/formulary/tests/test_parameters.py
@@ -2,6 +2,7 @@
 
 import numpy as np
 import pytest
+import warnings
 
 from astropy import units as u
 from astropy.constants import m_e, m_p
@@ -644,169 +645,235 @@ def test_gyrofrequency():
     assert_can_handle_nparray(gyrofrequency, kwargs={"signed": False})
 
 
-def test_gyroradius():
-    r"""Test the gyroradius function in parameters.py."""
+class TestGyroradius:
+    """Tests for `plasmapy.formulary.parameters.gyroradius`."""
 
-    assert gyroradius(B, "e-", T=T_e).unit.is_equivalent(u.m)
-
-    assert gyroradius(B, "e-", Vperp=25 * u.m / u.s).unit.is_equivalent(u.m)
-
-    # test for possiblity to allow nan for input values
-    assert np.isnan(gyroradius(np.nan * u.T, particle="e-", T=1 * u.K))
-    assert np.isnan(gyroradius(1 * u.T, particle="e-", T=np.nan * u.K))
-    assert np.isnan(gyroradius(1 * u.T, particle="e-", Vperp=np.nan * u.m / u.s))
-
-    Vperp = 1e6 * u.m / u.s
-    Bmag = 1 * u.T
-    omega_ce = gyrofrequency(Bmag, "e-")
-    analytical_result = (Vperp / omega_ce).to(
-        u.m, equivalencies=u.dimensionless_angles()
+    @pytest.mark.parametrize(
+        "args, kwargs, _error",
+        [
+            ((u.T, "e-"), {}, TypeError),
+            ((5 * u.A, "e-"), {"Vperp": 8 * u.m / u.s}, u.UnitTypeError),
+            ((5 * u.T, "e-"), {"Vperp": 8 * u.m}, u.UnitTypeError),
+            (
+                (np.array([5, 6]) * u.T, "e-"),
+                {"Vperp": np.array([5, 6, 7]) * u.m / u.s},
+                ValueError,
+            ),
+            ((3.14159 * u.T, "e-"), {"T": -1 * u.K}, ValueError),
+            ((1.1 * u.T, "e-"), {"Vperp": 1 * u.m / u.s, "T": 1.2 * u.K}, ValueError),
+            ((1.1 * u.T, "e-"), {"Vperp": 1.1 * u.m, "T": 1.2 * u.K}, u.UnitTypeError),
+            ((u.T,), {"particle": "p", "Vperp": 8 * u.m / u.s}, TypeError),
+            ((B,), {"particle": "p", "T": -1 * u.K}, ValueError),
+            (
+                (1.1 * u.T,),
+                {"particle": "p", "Vperp": 1 * u.m / u.s, "T": 1.2 * u.K},
+                ValueError,
+            ),
+            (
+                (1.1 * u.T,),
+                {"particle": "p", "Vperp": 1.1 * u.m, "T": 1.2 * u.K},
+                u.UnitTypeError,
+            ),
+            (
+                (1.1 * u.T,),
+                {"particle": "p", "Vperp": 1.2 * u.m, "T": 1.1 * u.K},
+                u.UnitTypeError,
+            ),
+            ((B_arr, "e-"), {"Vperp": V, "T": T_arr}, ValueError),
+            ((B_arr, "e-"), {"Vperp": V_arr, "T": T_i}, ValueError),
+            ((B_arr, "e-"), {"Vperp": V, "T": T_nanarr}, ValueError),
+            ((B_arr, "e-"), {"Vperp": V_nanarr, "T": T_i}, ValueError),
+            ((0.4 * u.T, "e-"), {"T": 5 * u.eV, "T_i": 7 * u.eV}, ValueError),
+        ],
     )
-    assert gyroradius(Bmag, "e-", Vperp=Vperp) == analytical_result
-
-    with pytest.raises(TypeError):
-        with pytest.warns(u.UnitsWarning):
-            gyroradius(u.T, "e-")
-
-    with pytest.raises(u.UnitTypeError):
-        gyroradius(5 * u.A, "e-", Vperp=8 * u.m / u.s)
-
-    with pytest.raises(u.UnitTypeError):
-        gyroradius(5 * u.T, "e-", Vperp=8 * u.m)
-
-    with pytest.raises(ValueError):
-        gyroradius(np.array([5, 6]) * u.T, "e-", Vperp=np.array([5, 6, 7]) * u.m / u.s)
-
-    assert np.isnan(gyroradius(np.nan * u.T, "e-", Vperp=1 * u.m / u.s))
-
-    with pytest.raises(ValueError):
-        gyroradius(3.14159 * u.T, "e-", T=-1 * u.K)
-
-    with pytest.warns(u.UnitsWarning):
-        assert gyroradius(1.0, "e-", Vperp=1.0) == gyroradius(
-            1.0 * u.T, "e-", Vperp=1.0 * u.m / u.s
-        )
-
-    with pytest.warns(u.UnitsWarning):
-        assert gyroradius(1.1, "e-", T=1.2) == gyroradius(1.1 * u.T, "e-", T=1.2 * u.K)
-
-    with pytest.raises(ValueError):
-        gyroradius(1.1 * u.T, "e-", Vperp=1 * u.m / u.s, T=1.2 * u.K)
-
-    with pytest.raises(u.UnitTypeError):
-        gyroradius(1.1 * u.T, "e-", Vperp=1.1 * u.m, T=1.2 * u.K)
-
-    # Check for Deprecation warning when using T_i instead of T
-    with pytest.warns(PlasmaPyFutureWarning):
-        gyroradius(1.1 * u.T, "e-", T_i=1.2 * u.K)
+    def test_raises(self, args, kwargs, _error):
+        """Test scenarios that raise an exception."""
 
-    assert gyroradius(B, particle="p", T=T_i).unit.is_equivalent(u.m)
+        with warnings.catch_warnings(), pytest.raises(_error):
+            # we don't care about warnings for these tests
+            warnings.simplefilter("ignore")
 
-    assert gyroradius(B, particle="p", Vperp=25 * u.m / u.s).unit.is_equivalent(u.m)
+            gyroradius(*args, **kwargs)
 
-    # Case when Z=1 is assumed
-    assert np.isclose(
-        gyroradius(B, particle="p", T=T_i),
-        gyroradius(B, particle="H+", T=T_i),
-        atol=1e-6 * u.m,
+    @pytest.mark.parametrize(
+        "args, kwargs, nan_mask",
+        [
+            ((np.nan * u.T,), {"particle": "e-", "T": 1 * u.K}, None),
+            ((np.nan * u.T,), {"particle": "e-", "Vperp": 1 * u.m / u.s}, None),
+            ((1 * u.T,), {"particle": "e-", "T": np.nan * u.K}, None),
+            ((1 * u.T,), {"particle": "e-", "Vperp": np.nan * u.m / u.s}, None),
+            (
+                ([1, 2, np.nan] * u.T,),
+                {"particle": "e-", "T": 1 * u.K},
+                [False, False, True],
+            ),
+            (
+                ([1, 2, np.nan] * u.T,),
+                {"particle": "e-", "T": [np.nan, 1, 2] * u.K},
+                [True, False, True],
+            ),
+            (
+                ([1, np.nan, 2] * u.T,),
+                {"particle": "e-", "Vperp": [np.nan, 1, 2] * u.m / u.s},
+                [True, True, False],
+            ),
+        ],
     )
+    def test_nan_values(self, args, kwargs, nan_mask):
+        if nan_mask is None:
+            assert np.all(np.isnan(gyroradius(*args, **kwargs)))
+        else:
+            rc_isnans = np.isnan(gyroradius(*args, **kwargs))
+            assert np.all(rc_isnans[nan_mask])
+            assert np.all(np.logical_not(rc_isnans[np.logical_not(nan_mask)]))
 
-    gyroPos = gyroradius(B, particle="p", Vperp=V)
-    gyroNeg = gyroradius(B, particle="p", Vperp=-V)
-    assert gyroPos == gyroNeg
-
-    Vperp = 1e6 * u.m / u.s
-    Bmag = 1 * u.T
-    omega_ci = gyrofrequency(Bmag, particle="p")
-    analytical_result = (Vperp / omega_ci).to(
-        u.m, equivalencies=u.dimensionless_angles()
+    @pytest.mark.parametrize(
+        "args, kwargs, expected, atol",
+        [
+            (
+                (1 * u.T,),
+                {"particle": "e-", "Vperp": 1e6 * u.m / u.s},
+                5.6856301e-06 * u.m,
+                None,
+            ),
+            (
+                (1 * u.T,),
+                {"particle": "p", "Vperp": 1e6 * u.m / u.s},
+                0.01043968 * u.m,
+                None,
+            ),
+            (
+                (1 * u.T,),
+                {"particle": "positron", "T": 1 * u.MK},
+                gyroradius(1 * u.T, particle="e-", T=1 * u.MK),
+                None,
+            ),
+            (
+                (B,),
+                {"particle": "p", "T": T_i},
+                gyroradius(B, particle="H+", T=T_i),
+                1e-6,
+            ),
+            (
+                (B,),
+                {"particle": "p", "Vperp": V},
+                gyroradius(B, particle="p", Vperp=-V),
+                None,
+            ),
+            (
+                (B_arr,),
+                {"particle": "e-", "Vperp": V_arr},
+                [1.42140753e-07, 1.42140753e-07] * u.m,
+                None,
+            ),
+            (
+                (B_arr,),
+                {"particle": "e-", "T": T_arr},
+                [0.03130334, 0.02213481] * u.m,
+                None,
+            ),
+            (
+                ([0.4, 0.6, 0.8] * u.T,),
+                {"particle": "e-", "T": [6, 4, 2] * u.eV},
+                [2.06499941e-05, 1.12404331e-05, 5.96113984e-06] * u.m,
+                None,
+            ),
+            ((0.4 * u.T, "p"), {"T": 5800 * u.K}, 0.00025539 * u.m, None),
+            (
+                (0.4 * u.T, "p"),
+                {"T": (5800 * u.K).to(u.eV, equivalencies=u.temperature_energy())},
+                0.00025539 * u.m,
+                None,
+            ),
+            #
+            # If both Vperp or T are given, but only one of the two is valid
+            # at each element, then the valid union is taken
+            (
+                ([0.001, 0.002] * u.T, "e-"),
+                {"Vperp": [25, np.nan] * u.m / u.s, "T": [np.nan, 2e6] * u.K},
+                [1.42140753e-07, 2.21348073e-02] * u.m,
+                None,
+            ),
+            #
+            # If either Vperp or T is a valid scalar and the other is a Qarray of
+            # all nans, then the Qarray of nans should be ignored
+            (
+                ([0.001, 0.002] * u.T, "e-"),
+                {"Vperp": 25.2 * u.m / u.s, "T": [np.nan, np.nan] * u.K},
+                [1.43277879e-07, 7.16389393e-08] * u.m,
+                None,
+            ),
+            (
+                ([0.001, 0.002] * u.T, "e-"),
+                {"Vperp": [np.nan, np.nan] * u.m / u.s, "T": 1e6 * u.K},
+                [0.03130334, 0.01565167] * u.m,
+                None,
+            ),
+        ],
     )
-    assert gyroradius(Bmag, particle="p", Vperp=Vperp) == analytical_result
-
-    T2 = 1.2 * u.MK
-    B2 = 123 * u.G
-    particle2 = "alpha"
-    Vperp2 = thermal_speed(T2, particle=particle2)
-    gyro_by_vperp = gyroradius(B2, particle="alpha", Vperp=Vperp2)
-    assert gyro_by_vperp == gyroradius(B2, particle="alpha", T=T2)
-
-    explicit_positron_gyro = gyroradius(1 * u.T, particle="positron", T=1 * u.MK)
-    assert explicit_positron_gyro == gyroradius(1 * u.T, "e-", T=1 * u.MK)
-
-    with pytest.raises(TypeError):
-        with pytest.warns(u.UnitsWarning):
-            gyroradius(u.T, particle="p", Vperp=8 * u.m / u.s)
-
-    with pytest.raises(ValueError):
-        gyroradius(B, particle="p", T=-1 * u.K)
-
-    with pytest.warns(u.UnitsWarning):
-        gyro_without_units = gyroradius(1.0, particle="p", Vperp=1.0)
-        gyro_with_units = gyroradius(1.0 * u.T, particle="p", Vperp=1.0 * u.m / u.s)
-        assert gyro_without_units == gyro_with_units
+    def test_values(self, args, kwargs, expected, atol):
+        if atol is None:
+            atol = 1e-8
 
-    with pytest.warns(u.UnitsWarning):
-        gyro_t_without_units = gyroradius(1.1, particle="p", T=1.2)
-        gyro_t_with_units = gyroradius(1.1 * u.T, particle="p", T=1.2 * u.K)
-        assert gyro_t_with_units == gyro_t_without_units
+        # note allclose() checks values and units
+        rc = gyroradius(*args, **kwargs)
+        assert np.allclose(rc, expected, atol=atol)
+        assert rc.unit == u.m
 
-    with pytest.raises(ValueError):
-        gyroradius(1.1 * u.T, particle="p", Vperp=1 * u.m / u.s, T=1.2 * u.K)
+    @pytest.mark.parametrize(
+        "args, kwargs, expected, _warns",
+        [
+            ((1.0, "e-"), {"Vperp": 1.0}, 5.6856301e-12 * u.m, u.UnitsWarning),
+            ((1.0 * u.T, "e-"), {"Vperp": 1.0}, 5.6856301e-12 * u.m, u.UnitsWarning),
+            (
+                (1.0, "e-"),
+                {"Vperp": 1.0 * u.m / u.s},
+                5.6856301e-12 * u.m,
+                u.UnitsWarning,
+            ),
+            ((1.1, "e-"), {"T": 1.2}, 3.11737236e-08 * u.m, u.UnitsWarning),
+            ((1.1 * u.T, "e-"), {"T": 1.2}, 3.11737236e-08 * u.m, u.UnitsWarning),
+            ((1.1, "e-"), {"T": 1.2 * u.K}, 3.11737236e-08 * u.m, u.UnitsWarning),
+            #
+            # Future warning for using T_i instead of T
+            (
+                (1.1 * u.T, "e-"),
+                {"T_i": 1.2 * u.K},
+                3.11737236e-08 * u.m,
+                PlasmaPyFutureWarning,
+            ),
+        ],
+    )
+    def test_warns(self, args, kwargs, expected, _warns):
+        with pytest.warns(_warns):
+            rc = gyroradius(*args, **kwargs)
+            if expected is not None:
+                assert np.allclose(rc, expected)
 
-    with pytest.raises(u.UnitTypeError):
-        gyroradius(1.1 * u.T, particle="p", Vperp=1.1 * u.m, T=1.2 * u.K)
+    def test_keeps_arguments_unchanged(self):
+        Vperp1 = u.Quantity([np.nan, 1], unit=u.m / u.s)
+        Vperp2 = Vperp1.copy()
+        T = u.Quantity([1, np.nan], unit=u.K)
 
-    with pytest.raises(u.UnitTypeError):
-        gyroradius(1.1 * u.T, particle="p", Vperp=1.2 * u.m, T=1.1 * u.K)
+        gyroradius(B_arr, "e-", Vperp=Vperp1, T=T)
 
+        assert_quantity_allclose(Vperp1, Vperp2)
 
-class Test_gyroradius:
+    def test_correct_thermal_speed_used(self):
+        """
+        Test the correct version of thermal_speed is used when
+        temperature is given.
+        """
+        B = 123 * u.G
+        T = 1.2 * u.MK
+        particle = "alpha"
 
-    # some custom numpy array tests here, because of the T / Vperp situation
-    def test_handle_numpy_array(self):
-        # Tests to verify that can handle Quantities with numpy array as the value:
-        assert gyroradius(B_arr, "e-", Vperp=V_arr)[0] == gyroradius(
-            B_arr[0], "e-", Vperp=V_arr[0]
-        )
-        assert gyroradius(B_arr, "e-", T=T_arr)[0] == gyroradius(
-            B_arr[0], "e-", T=T_arr[0]
-        )
+        vperp = thermal_speed(T, particle=particle, method="most_probable", ndim=3)
 
-    def test_handle_mixed_Qarrays(self):
-        # If both Vperp or T are input as Qarrays, but only one of the two is valid
-        # at each element, then that's fine, the function should work:
-        assert gyroradius(B_arr, "e-", Vperp=V_nanarr, T=T_nanarr2)[0] == gyroradius(
-            B_arr[0], "e-", Vperp=V_nanarr[0], T=T_nanarr2[0]
+        assert gyroradius(B, particle=particle, T=T) == gyroradius(
+            B, particle=particle, Vperp=vperp
         )
 
-    def test_raise_two_valid_inputs(self):
-        # If both Vperp or T are nan-less, Qarrays or not, should raise ValueError:
-        with pytest.raises(ValueError):
-            gyroradius(B_arr, "e-", Vperp=V, T=T_arr)
-        with pytest.raises(ValueError):
-            gyroradius(B_arr, "e-", Vperp=V_arr, T=T_i)
-
-    def test_all_valid_and_one_valid(self):
-        # If one of (Vperp, T) is a valid and one is Qarray with at least one valid, ValueError:
-        with pytest.raises(ValueError):
-            gyroradius(B_arr, "e-", Vperp=V, T=T_nanarr)
-        with pytest.raises(ValueError):
-            gyroradius(B_arr, "e-", Vperp=V_nanarr, T=T_i)
-
-    def test_scalar_and_nan_qarray(self):
-        # If either Vperp or T is a valid scalar and the other is a Qarray of all nans,
-        # should do something valid and not raise a ValueError
-        assert np.all(np.isfinite(gyroradius(B_arr, "e-", Vperp=V, T=T_allnanarr)))
-        assert np.all(np.isfinite(gyroradius(B_arr, "e-", Vperp=V_allnanarr, T=T_i)))
-
-    def test_keeps_arguments_unchanged(self):
-        Vperp1 = u.Quantity([np.nan, 1], unit=u.m / u.s)
-        Vperp2 = u.Quantity([np.nan, 1], unit=u.m / u.s)  # an exact copy
-        T_i = u.Quantity([1, np.nan], unit=u.K)
-
-        gyroradius(B_arr, "e-", Vperp=Vperp1, T=T_i)
-        assert_quantity_allclose(Vperp1, Vperp2)
-
 
 def test_Debye_length():
     r"""Test the Debye_length function in parameters.py."""
diff --git a/requirements/tests.txt b/requirements/tests.txt
index 5b014e45..38254bb9 100644
--- a/requirements/tests.txt
+++ b/requirements/tests.txt
@@ -4,3 +4,4 @@
 hypothesis
 pytest >= 5.1
 pytest-regressions
+pytest-xdist