You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2022/11/20 12:35:30 UTC

[commons-statistics] 04/04: Use parameterized tests

This is an automated email from the ASF dual-hosted git repository.

aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git

commit c32aa226e55812280afb1fc82b3e996dd458220d
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Sat Nov 19 08:43:40 2022 +0000

    Use parameterized tests
---
 .../statistics/distribution/FDistributionTest.java | 196 ++++++++++++---------
 .../distribution/GammaDistributionTest.java        |  25 +--
 .../distribution/GeometricDistributionTest.java    |  32 ++--
 .../HypergeometricDistributionTest.java            |  40 +++--
 .../distribution/ParetoDistributionTest.java       |  26 ++-
 .../distribution/PascalDistributionTest.java       |  28 +--
 .../statistics/distribution/TDistributionTest.java |  35 ++--
 .../distribution/TrapezoidalDistributionTest.java  |   6 +-
 .../distribution/TriangularDistributionTest.java   |  36 ++--
 .../TruncatedNormalDistributionTest.java           |   4 +-
 .../UniformContinuousDistributionTest.java         |  30 ++--
 .../UniformDiscreteDistributionTest.java           |  25 +--
 .../distribution/WeibullDistributionTest.java      |  55 +++---
 13 files changed, 293 insertions(+), 245 deletions(-)

diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java
index a0371e9..43fcb13 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/FDistributionTest.java
@@ -16,8 +16,12 @@
  */
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link FDistribution}.
@@ -53,21 +57,22 @@ class FDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testAdditionalMoments() {
-        FDistribution dist;
-
-        dist = FDistribution.of(1, 2);
-        Assertions.assertEquals(Double.NaN, dist.getMean());
-        Assertions.assertEquals(Double.NaN, dist.getVariance());
-
-        dist = FDistribution.of(1, 3);
-        Assertions.assertEquals(3d / (3d - 2d), dist.getMean());
-        Assertions.assertEquals(Double.NaN, dist.getVariance());
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double numeratorDegreesOfFreedom,
+                               double denominatorDegreesOfFreedom,
+                               double mean,
+                               double variance) {
+        final FDistribution dist = FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
 
-        dist = FDistribution.of(1, 5);
-        Assertions.assertEquals(5d / (5d - 2d), dist.getMean());
-        Assertions.assertEquals((2d * 5d * 5d * 4d) / 9d, dist.getVariance());
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(1, 2, Double.NaN, Double.NaN),
+            Arguments.of(1, 3, 3.0 / (3 - 2), Double.NaN),
+            Arguments.of(1, 5, 5.0 / (5 - 2), (2 * 5 * 5 * 4) / 9.0)
+        );
     }
 
     @Test
@@ -102,82 +107,105 @@ class FDistributionTest extends BaseContinuousDistributionTest {
         Assertions.assertTrue(result < 1.0, "Failing to calculate inverse cumulative probability");
     }
 
-    @Test
-    void testAdditionalLogDensity() {
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalLogDensity(double numeratorDegreesOfFreedom,
+                                  double denominatorDegreesOfFreedom,
+                                  double[] points,
+                                  double[] values) {
+        testLogDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom),
+            points, values, DoubleTolerances.relative(1e-15));
+    }
+
+    static Stream<Arguments> testAdditionalLogDensity() {
         // Computed using Boost multiprecision to 100 digits (output 25 digits).
 
         // Edge cases when the standard density is sub-normal or zero.
         final double[] x = new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9};
-        testLogDensity(FDistribution.of(100, 100), x,
-                       new double[] {-56.96014024624318913110565,
-                                     -165.8559950938238412964495,
-                                     -282.3927517845117162132265,
-                                     -399.7346409939330236149964,
-                                     -517.157481231596055999464,
-                                     -634.5884209792423525846316,
-                                     -752.0201707219881824362492,
-                                     -869.4520014646850073211334,
-                                     -986.883840307381342156051},
-                       DoubleTolerances.relative(1e-15));
-
-        testLogDensity(FDistribution.of(952, 912), x,
-                       new double[] {-509.5128641158461391223255,
-                                     -1485.417858108384337659572,
-                                     -2529.705750311339816652123,
-                                     -3581.184004620825529681231,
-                                     -4633.385040722443349533971,
-                                     -5685.658392700035382988623,
-                                     -6737.938976642435125691553,
-                                     -7790.220283785087985050541,
-                                     -8842.501663247803879775318},
-                       DoubleTolerances.relative(1e-15));
-
-        // This causes intermediate overflow of the density function
-        testLogDensity(FDistribution.of(1e-100, 1),
-                       new double[] {1e-200, 1e-250, 1e-300},
-                       new double[] {229.5653621188446231302736,
-                                     344.6946167685469072592738,
-                                     459.8238714182491914891139},
-                       DoubleTolerances.relative(1e-15));
+        return Stream.of(
+            Arguments.of(100, 100, x,
+                new double[] {
+                    -56.96014024624318913110565,
+                    -165.8559950938238412964495,
+                    -282.3927517845117162132265,
+                    -399.7346409939330236149964,
+                    -517.157481231596055999464,
+                    -634.5884209792423525846316,
+                    -752.0201707219881824362492,
+                    -869.4520014646850073211334,
+                    -986.883840307381342156051}),
+            Arguments.of(952, 912, x,
+                new double[] {
+                    -509.5128641158461391223255,
+                    -1485.417858108384337659572,
+                    -2529.705750311339816652123,
+                    -3581.184004620825529681231,
+                    -4633.385040722443349533971,
+                    -5685.658392700035382988623,
+                    -6737.938976642435125691553,
+                    -7790.220283785087985050541,
+                    -8842.501663247803879775318}),
+            // This causes intermediate overflow of the density function
+            Arguments.of(1e-100, 1,
+                new double[] {1e-200, 1e-250, 1e-300},
+                new double[] {
+                    229.5653621188446231302736,
+                    344.6946167685469072592738,
+                    459.8238714182491914891139})
+        );
     }
 
-    @Test
-    void testAdditionalDensity() {
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalDensity(double numeratorDegreesOfFreedom,
+                               double denominatorDegreesOfFreedom,
+                               double[] points,
+                               double[] values,
+                               double relativeError) {
+        testDensity(FDistribution.of(numeratorDegreesOfFreedom, denominatorDegreesOfFreedom),
+            points, values, DoubleTolerances.relative(relativeError));
+    }
+
+    static Stream<Arguments> testAdditionalDensity() {
+        // Computed using Boost multiprecision to 100 digits (output 25 digits).
+
         // Edge cases when the standard density is sub-normal.
-        testDensity(FDistribution.of(100, 100),
-                    new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 3e6, 4e6, 4.5e6, 5e6, 1e7},
-                    new double[] {1.830313161302986740491046e-25,
-                                  9.325165326363852979476269e-73,
-                                  2.282370632180103030176872e-123,
-                                  2.49718772086196154389661e-174,
-                                  2.51976260334572601372639e-225,
-                                  2.522031398014840106819471e-276,
-                                  1.171103964711921105069224e-300,
-                                  4.97420298008526384736197e-307,
-                                  1.224464123468993962344698e-309,
-                                  5.679564178845752345371413e-312,
-                                  0},
-                   DoubleTolerances.relative(3e-13));
-
-        testDensity(FDistribution.of(952, 912),
-                    new double[] {10, 11, 12, 13, 14, 15, 16, 17, 18},
-                    new double[] {5.264712450643104177155291e-222,
-                                  1.083049754753448067375765e-237,
-                                  2.996024821196787172008532e-252,
-                                  7.919262482129153149257417e-266,
-                                  1.511696585130734458293958e-278,
-                                  1.652611434344889324846565e-290,
-                                  8.522337060963566999523664e-302,
-                                  1.760000675560273604454495e-312,
-                                  1.266172656954210816606837e-322},
-                    DoubleTolerances.relative(2e-13));
-
-        // This causes intermediate overflow of the density function
-        testDensity(FDistribution.of(1e-100, 1),
-                    new double[] {1e-200, 1e-250, 1e-300},
-                    new double[] {5.000000000000000189458187e+99,
-                                  4.999999999999999829961813e+149,
-                                  4.99999999999999997466404e+199},
-                    DoubleTolerances.relative(5e-14));
+        return Stream.of(
+            Arguments.of(100, 100,
+                new double[] {1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 3e6, 4e6, 4.5e6, 5e6, 1e7},
+                new double[] {
+                    1.830313161302986740491046e-25,
+                    9.325165326363852979476269e-73,
+                    2.282370632180103030176872e-123,
+                    2.49718772086196154389661e-174,
+                    2.51976260334572601372639e-225,
+                    2.522031398014840106819471e-276,
+                    1.171103964711921105069224e-300,
+                    4.97420298008526384736197e-307,
+                    1.224464123468993962344698e-309,
+                    5.679564178845752345371413e-312,
+                    0
+                }, 3e-13),
+            Arguments.of(952, 912,
+                new double[] {10, 11, 12, 13, 14, 15, 16, 17, 18},
+                new double[] {5.264712450643104177155291e-222,
+                    1.083049754753448067375765e-237,
+                    2.996024821196787172008532e-252,
+                    7.919262482129153149257417e-266,
+                    1.511696585130734458293958e-278,
+                    1.652611434344889324846565e-290,
+                    8.522337060963566999523664e-302,
+                    1.760000675560273604454495e-312,
+                    1.266172656954210816606837e-322
+                }, 2e-13),
+            // This causes intermediate overflow of the density function
+            Arguments.of(1e-100, 1,
+                new double[] {1e-200, 1e-250, 1e-300},
+                new double[] {
+                    5.000000000000000189458187e+99,
+                    4.999999999999999829961813e+149,
+                    4.99999999999999997466404e+199
+                }, 5e-14)
+        );
     }
 }
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java
index 6b56fec..7c5ae4b 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GammaDistributionTest.java
@@ -21,10 +21,14 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.stream.Stream;
 import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
 import org.apache.commons.numbers.gamma.LanczosApproximation;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link GammaDistribution}.
@@ -62,17 +66,18 @@ class GammaDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testAdditionalMoments() {
-        GammaDistribution dist;
-
-        dist = GammaDistribution.of(1, 2);
-        Assertions.assertEquals(2, dist.getMean());
-        Assertions.assertEquals(4, dist.getVariance());
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double shape, double scale, double mean, double variance) {
+        final GammaDistribution dist = GammaDistribution.of(shape, scale);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
 
-        dist = GammaDistribution.of(1.1, 4.2);
-        Assertions.assertEquals(1.1 * 4.2, dist.getMean());
-        Assertions.assertEquals(1.1 * 4.2 * 4.2, dist.getVariance());
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(1, 2, 2, 4),
+            Arguments.of(1.1, 4.2, 1.1 * 4.2, 1.1 * 4.2 * 4.2)
+        );
     }
 
     @Test
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
index 7931147..1c47922 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
@@ -17,9 +17,12 @@
 package org.apache.commons.statistics.distribution;
 
 import java.util.Arrays;
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.junit.jupiter.params.provider.ValueSource;
 
 /**
@@ -49,6 +52,20 @@ class GeometricDistributionTest extends BaseDiscreteDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double p, double mean, double variance) {
+        final GeometricDistribution dist = GeometricDistribution.of(p);
+        testMoments(dist, mean, variance, DoubleTolerances.ulps(1));
+    }
+
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(0.5, (1.0 - 0.5) / 0.5, (1.0 - 0.5) / (0.5 * 0.5)),
+            Arguments.of(0.3, (1.0 - 0.3) / 0.3, (1.0 - 0.3) / (0.3 * 0.3))
+        );
+    }
+
     /**
      * Test the PMF is computed using the power function when p is above 0.5.
      * <p>Note: The geometric distribution PMF is defined as:
@@ -129,21 +146,6 @@ class GeometricDistributionTest extends BaseDiscreteDistributionTest {
         testSurvivalProbabilityInverseMapping(dist, x);
     }
 
-    @Test
-    void testAdditionalMoments() {
-        GeometricDistribution dist;
-
-        final DoubleTolerance tol = DoubleTolerances.ulps(1);
-
-        dist = GeometricDistribution.of(0.5);
-        TestUtils.assertEquals((1.0d - 0.5d) / 0.5d, dist.getMean(), tol);
-        TestUtils.assertEquals((1.0d - 0.5d) / (0.5d * 0.5d), dist.getVariance(), tol);
-
-        dist = GeometricDistribution.of(0.3);
-        TestUtils.assertEquals((1.0d - 0.3d) / 0.3d, dist.getMean(), tol);
-        TestUtils.assertEquals((1.0d - 0.3d) / (0.3d * 0.3d), dist.getVariance(), tol);
-    }
-
     /**
      * Test the most extreme parameters. Uses a small enough value of p that the distribution is
      * truncated by the maximum integer value. This creates a case where (x+1) will overflow.
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java
index d4ab2d1..34ecdb6 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/HypergeometricDistributionTest.java
@@ -17,10 +17,14 @@
 
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.apache.commons.numbers.core.Precision;
 import org.apache.commons.rng.simple.RandomSource;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link HypergeometricDistribution}.
@@ -54,23 +58,21 @@ class HypergeometricDistributionTest extends BaseDiscreteDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testAdditionalMoments() {
-        HypergeometricDistribution dist;
-
-        final DoubleTolerance tol = DoubleTolerances.ulps(1);
-
-        dist = HypergeometricDistribution.of(1500, 40, 100);
-        TestUtils.assertEquals(40d * 100d / 1500d,
-            dist.getMean(), tol);
-        TestUtils.assertEquals((100d * 40d * (1500d - 100d) * (1500d - 40d)) / ((1500d * 1500d * 1499d)),
-            dist.getVariance(), tol);
-
-        dist = HypergeometricDistribution.of(3000, 55, 200);
-        TestUtils.assertEquals(55d * 200d / 3000d,
-            dist.getMean(), tol);
-        TestUtils.assertEquals((200d * 55d * (3000d - 200d) * (3000d - 55d)) / ((3000d * 3000d * 2999d)),
-            dist.getVariance(), tol);
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(int populationSize,
+                               int numberOfSuccesses,
+                               int sampleSize,
+                               double mean, double variance) {
+        final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSuccesses, sampleSize);
+        testMoments(dist, mean, variance, DoubleTolerances.ulps(1));
+    }
+
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(1500, 40, 100, 40d * 100d / 1500d, (100d * 40d * (1500d - 100d) * (1500d - 40d)) / ((1500d * 1500d * 1499d))),
+            Arguments.of(3000, 55, 200, 55d * 200d / 3000d, (200d * 55d * (3000d - 200d) * (3000d - 55d)) / ((3000d * 3000d * 2999d)))
+        );
     }
 
     @Test
@@ -107,8 +109,8 @@ class HypergeometricDistributionTest extends BaseDiscreteDistributionTest {
     }
 
     private static void testHypergeometricDistributionProbabilities(int populationSize, int sampleSize,
-        int numberOfSucceses, double[][] data) {
-        final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSucceses, sampleSize);
+        int numberOfSuccesses, double[][] data) {
+        final HypergeometricDistribution dist = HypergeometricDistribution.of(populationSize, numberOfSuccesses, sampleSize);
         for (int i = 0; i < data.length; ++i) {
             final int x = (int)data[i][0];
             final double pmf = data[i][1];
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
index d3539ab..38450cf 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ParetoDistributionTest.java
@@ -19,6 +19,8 @@ package org.apache.commons.statistics.distribution;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 /**
  * Test cases for {@link ParetoDistribution}.
@@ -56,6 +58,16 @@ class ParetoDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
+    @ParameterizedTest
+    @CsvSource({
+        "1, 1, Infinity, Infinity",
+        "2.2, 2.4, 3.771428571428, 14.816326530",
+    })
+    void testAdditionalMoments(double scale, double shape, double mean, double variance) {
+        final ParetoDistribution dist = ParetoDistribution.of(scale, shape);
+        testMoments(dist, mean, variance, DoubleTolerances.relative(1e-9));
+    }
+
     @Test
     void testHighPrecision() {
         final ParetoDistribution dist = ParetoDistribution.of(2.1, 1.4);
@@ -91,20 +103,6 @@ class ParetoDistributionTest extends BaseContinuousDistributionTest {
         testCumulativeProbabilityHighPrecision(dist2, x, values2, DoubleTolerances.absolute(8e-17));
     }
 
-    @Test
-    void testAdditionalMoments() {
-        final double tol = 1e-9;
-        ParetoDistribution dist;
-
-        dist = ParetoDistribution.of(1, 1);
-        Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getMean(), tol);
-        Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance(), tol);
-
-        dist = ParetoDistribution.of(2.2, 2.4);
-        Assertions.assertEquals(3.771428571428, dist.getMean(), tol);
-        Assertions.assertEquals(14.816326530, dist.getVariance(), tol);
-    }
-
     /**
      * Check to make sure top-coding of extreme values works correctly.
      */
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
index b428f29..e2847e4 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/PascalDistributionTest.java
@@ -16,7 +16,10 @@
  */
 package org.apache.commons.statistics.distribution;
 
-import org.junit.jupiter.api.Test;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link PascalDistribution}.
@@ -49,18 +52,17 @@ class PascalDistributionTest extends BaseDiscreteDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testAdditionalMoments() {
-        PascalDistribution dist;
-
-        DoubleTolerance tol = DoubleTolerances.ulps(1);
-
-        dist = PascalDistribution.of(10, 0.5);
-        TestUtils.assertEquals((10d * 0.5d) / 0.5, dist.getMean(), tol);
-        TestUtils.assertEquals((10d * 0.5d) / (0.5d * 0.5d), dist.getVariance(), tol);
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(int r, double p, double mean, double variance) {
+        final PascalDistribution dist = PascalDistribution.of(r, p);
+        testMoments(dist, mean, variance, DoubleTolerances.ulps(1));
+    }
 
-        dist = PascalDistribution.of(25, 0.7);
-        TestUtils.assertEquals((25d * 0.3d) / 0.7, dist.getMean(), tol);
-        TestUtils.assertEquals((25d * 0.3d) / (0.7d * 0.7d), dist.getVariance(), tol);
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(10, 0.5, (10d * 0.5d) / 0.5, (10d * 0.5d) / (0.5d * 0.5d)),
+            Arguments.of(25, 0.7, (25d * 0.3d) / 0.7, (25d * 0.3d) / (0.7d * 0.7d))
+        );
     }
 }
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
index c862342..c67bc49 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TDistributionTest.java
@@ -16,10 +16,13 @@
  */
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link TDistribution}.
@@ -52,6 +55,21 @@ class TDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double df, double mean, double variance) {
+        final TDistribution dist = TDistribution.of(df);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
+
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(1.5, 0, Double.POSITIVE_INFINITY),
+            Arguments.of(2.1, 0, 2.1 / (2.1 - 2.0)),
+            Arguments.of(12.1, 0, 12.1 / (12.1 - 2.0))
+        );
+    }
+
     /**
      * @see <a href="https://issues.apache.orgg/bugzilla/show_bug.cgi?id=27243">
      *      Bug report that prompted this unit test.</a>
@@ -65,23 +83,6 @@ class TDistributionTest extends BaseContinuousDistributionTest {
         });
     }
 
-    @Test
-    void testAdditionalMoments() {
-        TDistribution dist;
-
-        dist = TDistribution.of(1.5);
-        Assertions.assertEquals(0, dist.getMean());
-        Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance());
-
-        dist = TDistribution.of(2.1);
-        Assertions.assertEquals(0, dist.getMean());
-        Assertions.assertEquals(2.1 / (2.1 - 2.0), dist.getVariance());
-
-        dist = TDistribution.of(12.1);
-        Assertions.assertEquals(0, dist.getMean());
-        Assertions.assertEquals(12.1 / (12.1 - 2.0), dist.getVariance());
-    }
-
     /*
      * Adding this test to benchmark against tables published by NIST
      * http://itl.nist.gov/div898/handbook/eda/section3/eda3672.htm
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java
index 5578cf4..2670124 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TrapezoidalDistributionTest.java
@@ -75,11 +75,9 @@ class TrapezoidalDistributionTest extends BaseContinuousDistributionTest {
 
     @ParameterizedTest
     @MethodSource
-    void testAdditionalMoments(double a, double b, double c, double d, double mean, double var) {
+    void testAdditionalMoments(double a, double b, double c, double d, double mean, double variance) {
         final TrapezoidalDistribution dist = TrapezoidalDistribution.of(a, b, c, d);
-        final DoubleTolerance tol = DoubleTolerances.ulps(8);
-        TestUtils.assertEquals(mean, dist.getMean(), tol);
-        TestUtils.assertEquals(var, dist.getVariance(), tol);
+        testMoments(dist, mean, variance, DoubleTolerances.ulps(8));
     }
 
     static Stream<Arguments> testAdditionalMoments() {
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
index 8dd4b44..80d2393 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TriangularDistributionTest.java
@@ -17,10 +17,12 @@
 
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link TriangularDistribution}.
@@ -58,6 +60,21 @@ class TriangularDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double a, double b, double c, double mean, double variance) {
+        final TriangularDistribution dist = TriangularDistribution.of(a, b, c);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
+
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(0, 0.5, 1.0, 0.5, 1 / 24.0),
+            Arguments.of(0, 1, 1, 2 / 3.0, 1 / 18.0),
+            Arguments.of(-3, 2, 12, 3 + (2 / 3.0), 175 / 18.0)
+        );
+    }
+
     @ParameterizedTest
     @CsvSource({
         "1, 2, 3",
@@ -69,21 +86,4 @@ class TriangularDistributionTest extends BaseContinuousDistributionTest {
         Assertions.assertEquals(mode, dist.getMode());
         Assertions.assertEquals(upper, dist.getSupportUpperBound());
     }
-
-    @Test
-    void testAdditionalMoments() {
-        TriangularDistribution dist;
-
-        dist = TriangularDistribution.of(0, 0.5, 1.0);
-        Assertions.assertEquals(0.5, dist.getMean());
-        Assertions.assertEquals(1 / 24.0, dist.getVariance());
-
-        dist = TriangularDistribution.of(0, 1, 1);
-        Assertions.assertEquals(2 / 3.0, dist.getMean());
-        Assertions.assertEquals(1 / 18.0, dist.getVariance());
-
-        dist = TriangularDistribution.of(-3, 2, 12);
-        Assertions.assertEquals(3 + (2 / 3.0), dist.getMean());
-        Assertions.assertEquals(175 / 18.0, dist.getVariance());
-    }
 }
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java
index 2d8290e..0dbf539 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/TruncatedNormalDistributionTest.java
@@ -57,6 +57,8 @@ class TruncatedNormalDistributionTest extends BaseContinuousDistributionTest {
         return new String[] {null, null, "SupportLowerBound", "SupportUpperBound"};
     }
 
+    //-------------------- Additional test cases -------------------------------
+
     /**
      * Hit the edge cases where the lower and upper bound are not infinite but the
      * CDF of the parent distribution is either 0 or 1. This is effectively no truncation.
@@ -73,7 +75,7 @@ class TruncatedNormalDistributionTest extends BaseContinuousDistributionTest {
         "1.0, 2.0, -4, 6",
         "3.45, 6.78, -8, 10",
     })
-    void testEffectivelyNoTruncation(double mean, double sd, double lower, double upper) {
+    void testMomentsEffectivelyNoTruncation(double mean, double sd, double lower, double upper) {
         double inf = Double.POSITIVE_INFINITY;
         double max = Double.MAX_VALUE;
         TruncatedNormalDistribution dist1;
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
index c56fde0..287d283 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformContinuousDistributionTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.apache.commons.rng.UniformRandomProvider;
 import org.apache.commons.rng.sampling.distribution.ContinuousSampler;
 import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler;
@@ -24,7 +25,9 @@ import org.apache.commons.rng.simple.RandomSource;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link UniformContinuousDistribution}.
@@ -62,22 +65,19 @@ class UniformContinuousDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testAdditionalMoments() {
-        UniformContinuousDistribution dist;
-
-        dist = UniformContinuousDistribution.of(0, 1);
-        Assertions.assertEquals(0.5, dist.getMean());
-        Assertions.assertEquals(1 / 12.0, dist.getVariance());
-
-        dist = UniformContinuousDistribution.of(-1.5, 0.6);
-        Assertions.assertEquals(-0.45, dist.getMean());
-        Assertions.assertEquals(0.3675, dist.getVariance());
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double lower, double upper, double mean, double variance) {
+        final UniformContinuousDistribution dist = UniformContinuousDistribution.of(lower, upper);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
 
-        // Overflow of 0.5 * (lower + upper)
-        dist = UniformContinuousDistribution.of(Double.MAX_VALUE / 2, Double.MAX_VALUE);
-        Assertions.assertEquals(Double.MAX_VALUE - Double.MAX_VALUE / 4, dist.getMean());
-        Assertions.assertEquals(Double.POSITIVE_INFINITY, dist.getVariance());
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(0, 1, 0.5, 1 / 12.0),
+            Arguments.of(-1.5, 0.6, -0.45, 0.3675),
+            Arguments.of(Double.MAX_VALUE / 2, Double.MAX_VALUE, Double.MAX_VALUE - Double.MAX_VALUE / 4, Double.POSITIVE_INFINITY)
+        );
     }
 
     /**
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
index c8f6912..33d5ecb 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/UniformDiscreteDistributionTest.java
@@ -17,11 +17,14 @@
 
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.apache.commons.math3.util.MathArrays;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link UniformDiscreteDistribution}.
@@ -52,18 +55,18 @@ class UniformDiscreteDistributionTest extends BaseDiscreteDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    /** Test mean/variance. */
-    @Test
-    void testAdditionalMoments() {
-        UniformDiscreteDistribution dist;
-
-        dist = UniformDiscreteDistribution.of(0, 5);
-        Assertions.assertEquals(2.5, dist.getMean());
-        Assertions.assertEquals(35 / 12.0, dist.getVariance());
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(int lower, int upper, double mean, double variance) {
+        final UniformDiscreteDistribution dist = UniformDiscreteDistribution.of(lower, upper);
+        testMoments(dist, mean, variance, DoubleTolerances.equals());
+    }
 
-        dist = UniformDiscreteDistribution.of(0, 1);
-        Assertions.assertEquals(0.5, dist.getMean());
-        Assertions.assertEquals(3 / 12.0, dist.getVariance());
+    static Stream<Arguments> testAdditionalMoments() {
+        return Stream.of(
+            Arguments.of(0, 5, 2.5, 35 / 12.0),
+            Arguments.of(0, 1, 0.5, 3 / 12.0)
+        );
     }
 
     // MATH-1396
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
index 1c10306..cb5ee80 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/WeibullDistributionTest.java
@@ -17,11 +17,14 @@
 
 package org.apache.commons.statistics.distribution;
 
+import java.util.stream.Stream;
 import org.apache.commons.numbers.gamma.LogGamma;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.MethodSource;
 
 /**
  * Test cases for {@link WeibullDistribution}.
@@ -53,14 +56,27 @@ class WeibullDistributionTest extends BaseContinuousDistributionTest {
 
     //-------------------- Additional test cases -------------------------------
 
-    @Test
-    void testInverseCumulativeProbabilitySmallPAccuracy() {
-        final WeibullDistribution dist = WeibullDistribution.of(2, 3);
-        final double t = dist.inverseCumulativeProbability(1e-17);
-        // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2)
-        // x = sqrt(-9*log(1-1e-17))
-        // If we're not careful, answer will be 0. Answer below is computed with care in Octave:
-        Assertions.assertEquals(9.48683298050514e-9, t, 1e-17);
+    @ParameterizedTest
+    @MethodSource
+    void testAdditionalMoments(double shape, double scale, double mean, double variance) {
+        final WeibullDistribution dist = WeibullDistribution.of(shape, scale);
+        testMoments(dist, mean, variance, DoubleTolerances.absolute(1e-9));
+    }
+
+    static Stream<Arguments> testAdditionalMoments() {
+        // In R: 3.5*gamma(1+(1/2.5)) (or empirically: mean(rweibull(10000, 2.5, 3.5)))
+        double mu1 = 3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5)));
+        double mu2 = 2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4)));
+        return Stream.of(
+            Arguments.of(2.5, 3.5, mu1,
+                (3.5 * 3.5) *
+                Math.exp(LogGamma.value(1 + (2 / 2.5))) -
+                (mu1 * mu1)),
+            Arguments.of(10.4, 2.222, mu2,
+                (2.222 * 2.222) *
+                Math.exp(LogGamma.value(1 + (2 / 10.4))) -
+                (mu2 * mu2))
+        );
     }
 
     @ParameterizedTest
@@ -75,21 +91,12 @@ class WeibullDistributionTest extends BaseContinuousDistributionTest {
     }
 
     @Test
-    void testAdditionalMoments() {
-        final double tol = 1e-9;
-        WeibullDistribution dist;
-
-        dist = WeibullDistribution.of(2.5, 3.5);
-        // In R: 3.5*gamma(1+(1/2.5)) (or empirically: mean(rweibull(10000, 2.5, 3.5)))
-        Assertions.assertEquals(3.5 * Math.exp(LogGamma.value(1 + (1 / 2.5))), dist.getMean(), tol);
-        Assertions.assertEquals((3.5 * 3.5) *
-            Math.exp(LogGamma.value(1 + (2 / 2.5))) -
-            (dist.getMean() * dist.getMean()), dist.getVariance(), tol);
-
-        dist = WeibullDistribution.of(10.4, 2.222);
-        Assertions.assertEquals(2.222 * Math.exp(LogGamma.value(1 + (1 / 10.4))), dist.getMean(), tol);
-        Assertions.assertEquals((2.222 * 2.222) *
-            Math.exp(LogGamma.value(1 + (2 / 10.4))) -
-            (dist.getMean() * dist.getMean()), dist.getVariance(), tol);
+    void testInverseCumulativeProbabilitySmallPAccuracy() {
+        final WeibullDistribution dist = WeibullDistribution.of(2, 3);
+        final double t = dist.inverseCumulativeProbability(1e-17);
+        // Analytically, answer is solution to 1e-17 = 1-exp(-(x/3)^2)
+        // x = sqrt(-9*log(1-1e-17))
+        // If we're not careful, answer will be 0. Answer below is computed with care in Octave:
+        Assertions.assertEquals(9.48683298050514e-9, t, 1e-17);
     }
 }