Repository: scipy/scipy
Pull request: TST: stats: break up and mark slow tests
#### Reference issue
Closes gh-12132

#### What does this implement/fix?
Skips some slow stats tests, including
16.43s call     scipy/stats/tests/test_mstats_basic.py::test_kendall_p_exact_large (split up into medium and large)
1.64s call     scipy/stats/tests/test_stats.py::TestKSTwoSamples::test_gh12218
1.50s call     scipy/stats/tests/test_continuous_basic.py::test_cont_basic[norminvgauss-arg77]
1.36s call     scipy/stats/tests/test_kdeoth.py::test_logpdf_overflow
1.17s call     scipy/stats/tests/test_mstats_basic.py::TestCorr::test_kendalltau - moved slow part to separate test

I also reconsidered the list of distributions to skip for `test_cont_basic`, adding some quick ones back in. 

I'll comment on the changes and reach out about the two bug tests inline.

Problem statement:
Slow tests to be trimmed or moved to test('full')
Running:
```
$ python -c "import scipy as s; s.test(extra_argv=['--durations=20'])"
```
on current master (`1.5.0.dev0+9f1addd`) gives:
```
============================== slowest 20 test durations ===============================
19.01s call     stats/tests/test_continuous_basic.py::test_cont_basic[kstwo-arg59]
6.42s call     _lib/tests/test_import_cycles.py::test_modules_importable
5.16s call     stats/tests/test_stats.py::TestMGCStat::test_random_state
4.93s call     _build_utils/tests/test_circular_imports.py::test_importing_submodules
3.70s call     stats/tests/test_stats.py::TestMGCStat::test_workers
3.29s call     stats/tests/test_continuous_basic.py::test_cont_basic[ksone-arg58]
2.60s call     optimize/tests/test__differential_evolution.py::TestDifferentialEvolutionSolver::test_L4
2.37s call     optimize/tests/test__differential_evolution.py::TestDifferentialEvolutionSolver::test_L1
2.00s call     stats/tests/test_stats.py::TestKSTwoSamples::testMediumBoth
1.89s call     optimize/tests/test_lsq_linear.py::TestTRF::test_sparse_bounds
1.83s call     stats/tests/test_stats.py::TestKSTwoSamples::testMiddlingBoth
1.69s call     signal/tests/test_signaltools.py::test_filtfilt_gust
1.63s call     signal/tests/test_filter_design.py::TestBessel::test_fs_param
1.46s call     stats/tests/test_continuous_basic.py::test_cont_basic[norminvgauss-arg78]
1.39s call     optimize/tests/test__basinhopping.py::TestBasinHopping::test_all_nograd_minimizers
1.32s call     stats/tests/test_mstats_basic.py::TestCorr::test_kendalltau
1.26s call     optimize/tests/test__differential_evolution.py::TestDifferentialEvolutionSolver::test_impossible_constraint
1.25s call     optimize/tests/test__differential_evolution.py::TestDifferentialEvolutionSolver::test_L2
1.21s call     spatial/tests/test_distance.py::TestCdist::test_cdist_calling_conventions
1.11s call     stats/tests/test_stats.py::TestKSTwoSamples::test_some_code_paths
= 24022 passed, 1976 skipped, 10965 deselected, 76 xfailed, 6 xpassed in 344.18s (0:05:44) =
```

Speeding up the default test suite by 10-20% shouldn't be difficult, and given that some CI is marginal on completing in time, this is worth doing.

Hints from issue discussion:
We can now use the numpy pre-built wheels for arm. That will save some time.
And in fact when you look at the slowest tests on CI the list changes a lot.
Sure, both true - this is still worth doing though, tests shouldn't as long as the slowest ones here, and this help help both on CI and local development.
The travisCI runs also have the [10 slowest durations](https://travis-ci.org/github/scipy/scipy/jobs/687971253#L1308)
I'm having a look at the `stats` ones.
> The travisCI runs also have the [10 slowest durations](https://travis-ci.org/github/scipy/scipy/jobs/687971253#L1308)

Was puzzled why I didn't see some of those; that's with `TESTMODE=full`, which isn't relevant for arm64 or ppc64le.


Has this been addressed, or is there still more to do?

Commit message: TST: stats: break up and mark slow tests

Patch to review:
diff --git a/scipy/stats/tests/test_continuous_basic.py b/scipy/stats/tests/test_continuous_basic.py
index c37b86fa78da..45e086c657ab 100644
--- a/scipy/stats/tests/test_continuous_basic.py
+++ b/scipy/stats/tests/test_continuous_basic.py
@@ -45,9 +45,9 @@
 ]
 
 
-distslow = ['kstwo', 'ksone', 'kappa4', 'gausshyper', 'recipinvgauss',
-            'genexpon', 'vonmises', 'vonmises_line', 'cosine', 'invweibull',
-            'powerlognorm', 'johnsonsu', 'kstwobign']
+distslow = ['kstwo', 'genexpon', 'ksone', 'recipinvgauss', 'vonmises',
+            'kappa4', 'vonmises_line', 'gausshyper', 'norminvgauss',
+            'geninvgauss']
 # distslow are sorted by speed (very slow to slow)
 
 # skip check_fit_args (test is slow)
diff --git a/scipy/stats/tests/test_kdeoth.py b/scipy/stats/tests/test_kdeoth.py
index 2e9216b42cd6..4e3a2898a78b 100644
--- a/scipy/stats/tests/test_kdeoth.py
+++ b/scipy/stats/tests/test_kdeoth.py
@@ -396,6 +396,7 @@ def test_pdf_logpdf_weighted():
     assert_almost_equal(pdf, pdf2, decimal=12)
 
 
+@pytest.mark.slow
 def test_logpdf_overflow():
     # regression test for gh-12988; testing against linalg instability for
     # very high dimensionality kde
diff --git a/scipy/stats/tests/test_mstats_basic.py b/scipy/stats/tests/test_mstats_basic.py
index 7a293108ab93..9c2a1e2b22bd 100644
--- a/scipy/stats/tests/test_mstats_basic.py
+++ b/scipy/stats/tests/test_mstats_basic.py
@@ -332,6 +332,14 @@ def test_kendalltau(self):
                             25, 80, 80, 80, 80, 80, 80, 0, 10, 45, np.nan, 0])
         result = mstats.kendalltau(x, y)
         assert_almost_equal(np.asarray(result), [-0.1585188, 0.4128009])
+
+        # test for namedtuple attributes
+        attributes = ('correlation', 'pvalue')
+        check_named_results(result, attributes, ma=True)
+
+
+    @pytest.mark.slow
+    def test_kendalltau_large(self):
         # make sure internal variable use correct precision with
         # larger arrays
         x = np.arange(2000, dtype=float)
@@ -340,10 +348,6 @@ def test_kendalltau(self):
         y = np.concatenate((y[1000:], y[:1000]))
         assert_(np.isfinite(mstats.kendalltau(x, y)[1]))
 
-        # test for namedtuple attributes
-        res = mstats.kendalltau(x, y)
-        attributes = ('correlation', 'pvalue')
-        check_named_results(res, attributes, ma=True)
 
     def test_kendalltau_seasonal(self):
         # Tests the seasonal Kendall tau.
@@ -358,27 +362,37 @@ def test_kendalltau_seasonal(self):
                             [0.18,0.53,0.20,0.04])
 
 
-def test_kendall_p_exact_large():
-    # Test for the exact method with large samples (n >= 171)
-    # expected values generated using SymPy
-    expectations = {(100, 2393): 0.62822615287956040664,
-                    (101, 2436): 0.60439525773513602669,
-                    (170, 0): 2.755801935583541e-307,
-                    (171, 0): 0.0,
-                    (171, 1): 2.755801935583541e-307,
-                    (172, 1): 0.0,
-                    (200, 9797): 0.74753983745929675209,
-                    (201, 9656): 0.40959218958120363618,
-                    (400, 38965): 0.48444283672113314099,
-                    (401, 39516): 0.66363159823474837662,
-                    (800, 156772): 0.42265448483120932055,
-                    (801, 157849): 0.53437553412194416236,
-                    (1600, 637472): 0.84200727400323538419,
-                    (1601, 630304): 0.34465255088058593946}
-    
-    for nc, expected in expectations.items():
-        res = mstats_basic._kendall_p_exact(nc[0], nc[1])
-        assert_almost_equal(res, expected)
+    def test_kendall_p_exact_medium(self):
+        # Test for the exact method with medium samples (some n >= 171)
+        # expected values generated using SymPy
+        expectations = {(100, 2393): 0.62822615287956040664,
+                        (101, 2436): 0.60439525773513602669,
+                        (170, 0): 2.755801935583541e-307,
+                        (171, 0): 0.0,
+                        (171, 1): 2.755801935583541e-307,
+                        (172, 1): 0.0,
+                        (200, 9797): 0.74753983745929675209,
+                        (201, 9656): 0.40959218958120363618}
+        for nc, expected in expectations.items():
+            res = mstats_basic._kendall_p_exact(nc[0], nc[1])
+            assert_almost_equal(res, expected)
+
+
+    @pytest.mark.slow
+    def test_kendall_p_exact_large(self):
+        # Test for the exact method with large samples (n >= 171)
+        # expected values generated using SymPy
+        expectations = {(400, 38965): 0.48444283672113314099,
+                        (401, 39516): 0.66363159823474837662,
+                        (800, 156772): 0.42265448483120932055,
+                        (801, 157849): 0.53437553412194416236,
+                        (1600, 637472): 0.84200727400323538419,
+                        (1601, 630304): 0.34465255088058593946}
+
+        for nc, expected in expectations.items():
+            res = mstats_basic._kendall_p_exact(nc[0], nc[1])
+            assert_almost_equal(res, expected)
+
 
     def test_pointbiserial(self):
         x = [1,0,1,1,1,1,0,1,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,
diff --git a/scipy/stats/tests/test_stats.py b/scipy/stats/tests/test_stats.py
index b9b801ba3589..6460edf1b577 100644
--- a/scipy/stats/tests/test_stats.py
+++ b/scipy/stats/tests/test_stats.py
@@ -3463,6 +3463,8 @@ def test_argument_checking(self):
         assert_raises(ValueError, stats.ks_2samp, [1], [])
         assert_raises(ValueError, stats.ks_2samp, [], [])
 
+
+    @pytest.mark.slow
     def test_gh12218(self):
         """Ensure gh-12218 is fixed."""
         # gh-1228 triggered a TypeError calculating sqrt(n1*n2*(n1+n2)).


Code review comments:
diff_hunk: @@ -332,6 +332,14 @@ def test_kendalltau(self):
                             25, 80, 80, 80, 80, 80, 80, 0, 10, 45, np.nan, 0])
         result = mstats.kendalltau(x, y)
         assert_almost_equal(np.asarray(result), [-0.1585188, 0.4128009])
+
+        # test for namedtuple attributes
+        attributes = ('correlation', 'pvalue')
+        check_named_results(result, attributes, ma=True)
+
+
+    @pytest.mark.slow
path: scipy/stats/tests/test_mstats_basic.py
text: @user1:
You lost the `ppc64le` skip here, let's put that back.

@author:
Oops, good catch.

diff_hunk: @@ -332,6 +332,14 @@ def test_kendalltau(self):
                             25, 80, 80, 80, 80, 80, 80, 0, 10, 45, np.nan, 0])
         result = mstats.kendalltau(x, y)
         assert_almost_equal(np.asarray(result), [-0.1585188, 0.4128009])
+
+        # test for namedtuple attributes
+        attributes = ('correlation', 'pvalue')
+        check_named_results(result, attributes, ma=True)
+
+
path: scipy/stats/tests/test_mstats_basic.py
text: @author:
```suggestion
    @user1.mark.skipif(platform.machine() == 'ppc64le',
                        reason="fails/crashes on ppc64le")
```