You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by dw...@apache.org on 2020/02/05 08:03:38 UTC

[flink] branch release-1.10 updated (92d130c -> f4c25df)

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

dwysakowicz pushed a change to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git.


    from 92d130c  [hotfix][docs] Fix missing double quotes in catalog docs
     new 1fa2901  [FLINK-15706][table-planner-blink] Fix LastValueAggFunctionWithOrderTest compilation error due to incompatible types
     new f4c25df  [FLINK-15706][table-planner-blink] Reorder and split into sections classes in aggfunctions tests.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../aggfunctions/AggFunctionTestBase.java          |  23 -
 ...FirstLastValueAggFunctionWithOrderTestBase.java |  17 -
 .../FirstValueAggFunctionWithOrderTest.java        | 726 ++++++++++-------
 .../FirstValueAggFunctionWithoutOrderTest.java     | 516 +++++++-----
 ...stValueWithRetractAggFunctionWithOrderTest.java | 739 +++++++++--------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 523 +++++++-----
 .../LastValueAggFunctionWithOrderTest.java         | 724 ++++++++++-------
 .../LastValueAggFunctionWithoutOrderTest.java      | 517 +++++++-----
 ...stValueWithRetractAggFunctionWithOrderTest.java | 754 +++++++++--------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 524 +++++++-----
 .../ListAggWithRetractAggFunctionTest.java         |   2 +-
 .../ListAggWsWithRetractAggFunctionTest.java       |   2 +-
 .../MaxWithRetractAggFunctionTest.java             | 905 +++++++++++++--------
 .../MinWithRetractAggFunctionTest.java             | 897 ++++++++++++--------
 14 files changed, 4023 insertions(+), 2846 deletions(-)


[flink] 02/02: [FLINK-15706][table-planner-blink] Reorder and split into sections classes in aggfunctions tests.

Posted by dw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dwysakowicz pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git

commit f4c25df707571f60724c8516dfb7a1055b0fa63c
Author: Dawid Wysakowicz <dw...@apache.org>
AuthorDate: Tue Feb 4 14:36:33 2020 +0100

    [FLINK-15706][table-planner-blink] Reorder and split into sections classes in aggfunctions tests.
---
 .../FirstValueAggFunctionWithOrderTest.java        | 192 ++++++++++----------
 .../FirstValueAggFunctionWithoutOrderTest.java     | 138 +++++++-------
 ...stValueWithRetractAggFunctionWithOrderTest.java | 201 ++++++++++----------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 151 ++++++++-------
 .../LastValueAggFunctionWithOrderTest.java         | 190 +++++++++----------
 .../LastValueAggFunctionWithoutOrderTest.java      | 138 +++++++-------
 ...stValueWithRetractAggFunctionWithOrderTest.java | 202 +++++++++++----------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 151 ++++++++-------
 .../ListAggWithRetractAggFunctionTest.java         |   2 +-
 .../ListAggWsWithRetractAggFunctionTest.java       |   2 +-
 .../MaxWithRetractAggFunctionTest.java             | 177 +++++++++---------
 .../MinWithRetractAggFunctionTest.java             | 177 +++++++++---------
 12 files changed, 922 insertions(+), 799 deletions(-)

diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
index 658541c..23de255 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
@@ -44,93 +44,20 @@ import java.util.List;
  * This class tests `accumulate` method with order argument.
  */
 @RunWith(Enclosed.class)
-public class FirstValueAggFunctionWithOrderTest {
+public final class FirstValueAggFunctionWithOrderTest {
 
-	/**
-	 * The base test class for FirstValueAggFunction with order.
-	 */
-	public abstract static class FirstValueAggFunctionWithOrderTestBase<T>
-			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
-
-	}
-
-	/**
-	 * Test FirstValueAggFunction for number type.
-	 */
-	public abstract static class NumberFirstValueAggFunctionWithOrderTestBase<T>
-			extends FirstValueAggFunctionWithOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null,
-							getValue("3"),
-							getValue("2"),
-							getValue("-99")
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("5")
-					)
-			);
-		}
-
-		@Override
-		protected List<List<Long>> getInputOrderSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							10L,
-							2L,
-							5L,
-							6L,
-							11L,
-							3L,
-							7L,
-							5L
-					),
-					Arrays.asList(
-							8L,
-							6L,
-							9L,
-							5L
-					),
-					Arrays.asList(
-							null,
-							6L,
-							4L,
-							3L
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("3"),
-					null,
-					getValue("5")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - FirstLastValueAggFunctionWithOrderTestBase -> tests specific for FirstValue and LastValue
+	//  - AggFunctionTestBase -> tests that apply to all aggregate functions
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteFirstValueAggFunction.
 	 */
-	public static class ByteFirstValueAggFunctionWithOrderTest
+	public static final class ByteFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Byte> {
 
 		@Override
@@ -147,7 +74,7 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for ShortFirstValueAggFunction.
 	 */
-	public static class ShortFirstValueAggFunctionWithOrderTest
+	public static final class ShortFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Short> {
 
 		@Override
@@ -164,7 +91,7 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for IntFirstValueAggFunction.
 	 */
-	public static class IntFirstValueAggFunctionWithOrderTest
+	public static final class IntFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Integer> {
 
 		@Override
@@ -181,7 +108,7 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for LongFirstValueAggFunction.
 	 */
-	public static class LongFirstValueAggFunctionWithOrderTest
+	public static final class LongFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Long> {
 
 		@Override
@@ -198,7 +125,7 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for FloatFirstValueAggFunction.
 	 */
-	public static class FloatFirstValueAggFunctionWithOrderTest
+	public static final class FloatFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Float> {
 
 		@Override
@@ -215,7 +142,7 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for DoubleFirstValueAggFunction.
 	 */
-	public static class DoubleFirstValueAggFunctionWithOrderTest
+	public static final class DoubleFirstValueAggFunctionWithOrderTest
 			extends NumberFirstValueAggFunctionWithOrderTestBase<Double> {
 
 		@Override
@@ -232,8 +159,8 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for BooleanFirstValueAggFunction.
 	 */
-	public static class BooleanFirstValueAggFunctionWithOrderTest
-			extends FirstValueAggFunctionWithOrderTestBase<Boolean> {
+	public static final class BooleanFirstValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<Boolean> {
 
 		@Override
 		protected List<List<Boolean>> getInputValueSets() {
@@ -322,8 +249,8 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for DecimalFirstValueAggFunction.
 	 */
-	public static class DecimalFirstValueAggFunctionWithOrderTest
-			extends FirstValueAggFunctionWithOrderTestBase<Decimal> {
+	public static final class DecimalFirstValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<Decimal> {
 
 		private int precision = 20;
 		private int scale = 6;
@@ -402,8 +329,8 @@ public class FirstValueAggFunctionWithOrderTest {
 	/**
 	 * Test for StringFirstValueAggFunction.
 	 */
-	public static class StringFirstValueAggFunctionWithOrderTest
-			extends FirstValueAggFunctionWithOrderTestBase<BinaryString> {
+	public static final class StringFirstValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<BinaryString> {
 
 		@Override
 		protected List<List<BinaryString>> getInputValueSets() {
@@ -476,4 +403,83 @@ public class FirstValueAggFunctionWithOrderTest {
 			return new StringFirstValueAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide:
+	//  - common inputs
+	// for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * Test FirstValueAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueAggFunctionWithOrderTestBase<T>
+		extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null,
+					getValue("3"),
+					getValue("2"),
+					getValue("-99")
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("5")
+				)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					10L,
+					2L,
+					5L,
+					6L,
+					11L,
+					3L,
+					7L,
+					5L
+				),
+				Arrays.asList(
+					8L,
+					6L,
+					9L,
+					5L
+				),
+				Arrays.asList(
+					null,
+					6L,
+					4L,
+					3L
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("3"),
+				null,
+				getValue("5")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
index 62be99c..8348251 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
@@ -44,65 +44,19 @@ import java.util.List;
  * This class tests `accumulate` method without order argument.
  */
 @RunWith(Enclosed.class)
-public class FirstValueAggFunctionWithoutOrderTest {
+public final class FirstValueAggFunctionWithoutOrderTest {
 
-	/**
-	 * The base test class for FirstValueAggFunction without order.
-	 */
-	public abstract static class FirstValueAggFunctionWithoutOrderTestBase<T>
-			extends AggFunctionTestBase<T, GenericRow> {
-		@Override
-		protected Class<?> getAccClass() {
-			return GenericRow.class;
-		}
-	}
-
-	/**
-	 * Test FirstValueAggFunction for number type.
-	 */
-	public abstract static class NumberFirstValueAggFunctionWithoutOrderTest<T>
-			extends FirstValueAggFunctionWithoutOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("3")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("1"),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteFirstValueAggFunction.
 	 */
-	public static class ByteFirstValueAggFunctionWithoutOrderTest
+	public static final class ByteFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Byte> {
 
 		@Override
@@ -119,7 +73,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for ShortFirstValueAggFunction.
 	 */
-	public static class ShortFirstValueAggFunctionWithoutOrderTest
+	public static final class ShortFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Short> {
 
 		@Override
@@ -136,7 +90,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for IntFirstValueAggFunction.
 	 */
-	public static class IntFirstValueAggFunctionWithoutOrderTest
+	public static final class IntFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Integer> {
 
 		@Override
@@ -153,7 +107,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for LongFirstValueAggFunction.
 	 */
-	public static class LongFirstValueAggFunctionWithoutOrderTest
+	public static final class LongFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Long> {
 
 		@Override
@@ -170,7 +124,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for FloatFirstValueAggFunction.
 	 */
-	public static class FloatFirstValueAggFunctionWithoutOrderTest
+	public static final class FloatFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Float> {
 
 		@Override
@@ -187,7 +141,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DoubleFirstValueAggFunction.
 	 */
-	public static class DoubleFirstValueAggFunctionWithoutOrderTest
+	public static final class DoubleFirstValueAggFunctionWithoutOrderTest
 			extends NumberFirstValueAggFunctionWithoutOrderTest<Double> {
 
 		@Override
@@ -204,7 +158,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for BooleanFirstValueAggFunction.
 	 */
-	public static class BooleanFirstValueAggFunctionWithoutOrderTest extends
+	public static final class BooleanFirstValueAggFunctionWithoutOrderTest extends
 			FirstValueAggFunctionWithoutOrderTestBase<Boolean> {
 
 		@Override
@@ -260,7 +214,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DecimalFirstValueAggFunction.
 	 */
-	public static class DecimalFirstValueAggFunctionWithoutOrderTest extends
+	public static final class DecimalFirstValueAggFunctionWithoutOrderTest extends
 			FirstValueAggFunctionWithoutOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -312,7 +266,7 @@ public class FirstValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for StringFirstValueAggFunction.
 	 */
-	public static class StringFirstValueAggFunctionWithoutOrderTest extends
+	public static final class StringFirstValueAggFunctionWithoutOrderTest extends
 			FirstValueAggFunctionWithoutOrderTestBase<BinaryString> {
 
 		@Override
@@ -358,4 +312,64 @@ public class FirstValueAggFunctionWithoutOrderTest {
 			return new StringFirstValueAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide:
+	//  - common inputs
+	//  - accumulator class
+	// for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for FirstValueAggFunction without order.
+	 */
+	public abstract static class FirstValueAggFunctionWithoutOrderTestBase<T>
+		extends AggFunctionTestBase<T, GenericRow> {
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+	}
+
+	/**
+	 * Test FirstValueAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueAggFunctionWithoutOrderTest<T>
+		extends FirstValueAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("3")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("1"),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
index 770f75a..ef8fa23 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
@@ -45,97 +45,20 @@ import java.util.List;
  * This class tests `accumulate` method with order argument.
  */
 @RunWith(Enclosed.class)
-public class FirstValueWithRetractAggFunctionWithOrderTest {
+public final class FirstValueWithRetractAggFunctionWithOrderTest {
 
-	/**
-	 * The base test class for FirstValueWithRetractAggFunction with order.
-	 */
-	public abstract static class FirstValueWithRetractAggFunctionWithOrderTestBase<T>
-			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
-
-	@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
-		}
-	}
-
-	/**
-	 * Test FirstValueWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberFirstValueWithRetractAggFunctionWithOrderTestBase<T>
-			extends FirstValueWithRetractAggFunctionWithOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null,
-							getValue("3"),
-							getValue("2"),
-							getValue("-99")
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("5")
-					)
-			);
-		}
-
-		@Override
-		protected List<List<Long>> getInputOrderSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							10L,
-							2L,
-							5L,
-							6L,
-							11L,
-							3L,
-							7L,
-							5L
-					),
-					Arrays.asList(
-							8L,
-							6L,
-							9L,
-							5L
-					),
-					Arrays.asList(
-							null,
-							6L,
-							4L,
-							3L
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("3"),
-					null,
-					getValue("5")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - FirstLastValueAggFunctionWithOrderTestBase -> tests specific for FirstValue and LastValue
+	//  - AggFunctionTestBase -> tests that apply to all aggregate functions
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteFirstValueWithRetractAggFunction.
 	 */
-	public static class ByteFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class ByteFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Byte> {
 
 		@Override
@@ -152,7 +75,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for ShortFirstValueWithRetractAggFunction.
 	 */
-	public static class ShortFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class ShortFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Short> {
 
 		@Override
@@ -169,7 +92,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for IntFirstValueWithRetractAggFunction.
 	 */
-	public static class IntFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class IntFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Integer> {
 
 		@Override
@@ -186,7 +109,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for LongFirstValueWithRetractAggFunction.
 	 */
-	public static class LongFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class LongFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Long> {
 
 		@Override
@@ -203,7 +126,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for FloatFirstValueWithRetractAggFunction.
 	 */
-	public static class FloatFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class FloatFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Float> {
 
 		@Override
@@ -220,7 +143,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for DoubleFirstValueWithRetractAggFunction.
 	 */
-	public static class DoubleFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class DoubleFirstValueWithRetractAggFunctionWithOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Double> {
 
 		@Override
@@ -237,7 +160,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for BooleanFirstValueWithRetractAggFunction.
 	 */
-	public static class BooleanFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class BooleanFirstValueWithRetractAggFunctionWithOrderTest
 			extends FirstValueWithRetractAggFunctionWithOrderTestBase<Boolean> {
 
 		@Override
@@ -327,7 +250,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for DecimalFirstValueWithRetractAggFunction.
 	 */
-	public static class DecimalFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class DecimalFirstValueWithRetractAggFunctionWithOrderTest
 			extends FirstValueWithRetractAggFunctionWithOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -407,7 +330,7 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for StringFirstValueWithRetractAggFunction.
 	 */
-	public static class StringFirstValueWithRetractAggFunctionWithOrderTest
+	public static final class StringFirstValueWithRetractAggFunctionWithOrderTest
 			extends FirstValueWithRetractAggFunctionWithOrderTestBase<BinaryString> {
 
 		@Override
@@ -481,4 +404,94 @@ public class FirstValueWithRetractAggFunctionWithOrderTest {
 			return new StringFirstValueWithRetractAggFunction();
 		}
 	}
+
+	/**
+	 * The base test class for FirstValueWithRetractAggFunction with order.
+	 */
+	public abstract static class FirstValueWithRetractAggFunctionWithOrderTestBase<T>
+		extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+		}
+	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide common inputs for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * Test FirstValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueWithRetractAggFunctionWithOrderTestBase<T>
+		extends FirstValueWithRetractAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null,
+					getValue("3"),
+					getValue("2"),
+					getValue("-99")
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("5")
+				)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					10L,
+					2L,
+					5L,
+					6L,
+					11L,
+					3L,
+					7L,
+					5L
+				),
+				Arrays.asList(
+					8L,
+					6L,
+					9L,
+					5L
+				),
+				Arrays.asList(
+					null,
+					6L,
+					4L,
+					3L
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("3"),
+				null,
+				getValue("5")
+			);
+		}
+	}
+
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
index 2125885..cd31cef 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
@@ -45,71 +45,19 @@ import java.util.List;
  * This class tests `accumulate` method without order argument.
  */
 @RunWith(Enclosed.class)
-public class FirstValueWithRetractAggFunctionWithoutOrderTest {
+public final class FirstValueWithRetractAggFunctionWithoutOrderTest {
 
-	/**
-	 * The base test class for FirstValueWithRetractAggFunction without order.
-	 */
-	public abstract static class FirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
-			extends AggFunctionTestBase<T, GenericRow> {
-
-		@Override
-		protected Class<?> getAccClass() {
-			return GenericRow.class;
-		}
-
-		@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
-		}
-	}
-
-	/**
-	 * Test FirstValueWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
-			extends FirstValueWithRetractAggFunctionWithoutOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("3")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("1"),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteFirstValueWithRetractAggFunction.
 	 */
-	public static class ByteFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class ByteFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Byte> {
 
 		@Override
@@ -126,7 +74,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for ShortFirstValueWithRetractAggFunction.
 	 */
-	public static class ShortFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class ShortFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Short> {
 
 		@Override
@@ -143,7 +91,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for IntFirstValueWithRetractAggFunction.
 	 */
-	public static class IntFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class IntFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Integer> {
 
 		@Override
@@ -160,7 +108,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for LongFirstValueWithRetractAggFunction.
 	 */
-	public static class LongFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class LongFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Long> {
 
 		@Override
@@ -177,7 +125,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for FloatFirstValueWithRetractAggFunction.
 	 */
-	public static class FloatFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class FloatFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Float> {
 
 		@Override
@@ -194,7 +142,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DoubleFirstValueWithRetractAggFunction.
 	 */
-	public static class DoubleFirstValueWithRetractAggFunctionWithoutOrderTest
+	public static final class DoubleFirstValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Double> {
 
 		@Override
@@ -211,7 +159,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for BooleanFirstValueWithRetractAggFunction.
 	 */
-	public static class BooleanFirstValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class BooleanFirstValueWithRetractAggFunctionWithoutOrderTest extends
 			FirstValueWithRetractAggFunctionWithoutOrderTestBase<Boolean> {
 
 		@Override
@@ -267,7 +215,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DecimalFirstValueWithRetractAggFunction.
 	 */
-	public static class DecimalFirstValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class DecimalFirstValueWithRetractAggFunctionWithoutOrderTest extends
 			FirstValueWithRetractAggFunctionWithoutOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -319,7 +267,7 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for StringFirstValueWithRetractAggFunction.
 	 */
-	public static class StringFirstValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class StringFirstValueWithRetractAggFunctionWithoutOrderTest extends
 			FirstValueWithRetractAggFunctionWithoutOrderTestBase<BinaryString> {
 
 		@Override
@@ -365,4 +313,71 @@ public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 			return new StringFirstValueWithRetractAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide common:
+	//  - inputs
+	//  - accumulator class
+	//  - accessor for retract function
+	//  for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for FirstValueWithRetractAggFunction without order.
+	 */
+	public abstract static class FirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
+		extends AggFunctionTestBase<T, GenericRow> {
+
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
+	}
+
+	/**
+	 * Test FirstValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
+		extends FirstValueWithRetractAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("3")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("1"),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
index 478c3e5..fb09301 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
@@ -44,93 +44,20 @@ import java.util.List;
  * This class tests `accumulate` method with order argument.
  */
 @RunWith(Enclosed.class)
-public class LastValueAggFunctionWithOrderTest {
+public final class LastValueAggFunctionWithOrderTest {
 
-	/**
-	 * The base test class for LastValueAggFunction with order.
-	 */
-	public abstract static class LastValueAggFunctionWithOrderTestBase<T>
-			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
-
-	}
-
-	/**
-	 * Test LastValueAggFunction for number type.
-	 */
-	public abstract static class NumberLastValueAggFunctionWithOrderTestBase<T>
-			extends LastValueAggFunctionWithOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null,
-							getValue("3"),
-							getValue("2"),
-							getValue("-99")
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("5")
-					)
-			);
-		}
-
-		@Override
-		protected List<List<Long>> getInputOrderSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							10L,
-							2L,
-							5L,
-							6L,
-							11L,
-							3L,
-							17L,
-							5L
-					),
-					Arrays.asList(
-							8L,
-							6L,
-							9L,
-							5L
-					),
-					Arrays.asList(
-							null,
-							6L,
-							4L,
-							3L
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("2"),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - FirstLastValueAggFunctionWithOrderTestBase -> tests specific for FirstValue and LastValue
+	//  - AggFunctionTestBase -> tests that apply to all aggregate functions
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteLastValueAggFunction.
 	 */
-	public static class ByteLastValueAggFunctionWithOrderTest
+	public static final class ByteLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Byte> {
 
 		@Override
@@ -147,7 +74,7 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for ShortLastValueAggFunction.
 	 */
-	public static class ShortLastValueAggFunctionWithOrderTest
+	public static final class ShortLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Short> {
 
 		@Override
@@ -164,7 +91,7 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for IntLastValueAggFunction.
 	 */
-	public static class IntLastValueAggFunctionWithOrderTest
+	public static final class IntLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Integer> {
 
 		@Override
@@ -181,7 +108,7 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for LongLastValueAggFunction.
 	 */
-	public static class LongLastValueAggFunctionWithOrderTest
+	public static final class LongLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Long> {
 
 		@Override
@@ -198,7 +125,7 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for FloatLastValueAggFunction.
 	 */
-	public static class FloatLastValueAggFunctionWithOrderTest
+	public static final class FloatLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Float> {
 
 		@Override
@@ -215,7 +142,7 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for DoubleLastValueAggFunction.
 	 */
-	public static class DoubleLastValueAggFunctionWithOrderTest
+	public static final class DoubleLastValueAggFunctionWithOrderTest
 			extends NumberLastValueAggFunctionWithOrderTestBase<Double> {
 
 		@Override
@@ -232,8 +159,8 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for BooleanLastValueAggFunction.
 	 */
-	public static class BooleanLastValueAggFunctionWithOrderTest
-			extends LastValueAggFunctionWithOrderTestBase<Boolean> {
+	public static final class BooleanLastValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<Boolean> {
 
 		@Override
 		protected List<List<Boolean>> getInputValueSets() {
@@ -322,8 +249,8 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for DecimalLastValueAggFunction.
 	 */
-	public static class DecimalLastValueAggFunctionWithOrderTest
-			extends LastValueAggFunctionWithOrderTestBase<Decimal> {
+	public static final class DecimalLastValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<Decimal> {
 
 		private int precision = 20;
 		private int scale = 6;
@@ -402,8 +329,8 @@ public class LastValueAggFunctionWithOrderTest {
 	/**
 	 * Test for StringLastValueAggFunction.
 	 */
-	public static class StringLastValueAggFunctionWithOrderTest
-			extends LastValueAggFunctionWithOrderTestBase<BinaryString> {
+	public static final class StringLastValueAggFunctionWithOrderTest
+			extends FirstLastValueAggFunctionWithOrderTestBase<BinaryString> {
 
 		@Override
 		protected List<List<BinaryString>> getInputValueSets() {
@@ -476,4 +403,81 @@ public class LastValueAggFunctionWithOrderTest {
 			return new StringLastValueAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide common inputs for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * Test LastValueAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueAggFunctionWithOrderTestBase<T>
+		extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null,
+					getValue("3"),
+					getValue("2"),
+					getValue("-99")
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("5")
+				)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					10L,
+					2L,
+					5L,
+					6L,
+					11L,
+					3L,
+					17L,
+					5L
+				),
+				Arrays.asList(
+					8L,
+					6L,
+					9L,
+					5L
+				),
+				Arrays.asList(
+					null,
+					6L,
+					4L,
+					3L
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("2"),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
index 4af3f87..1f65604 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
@@ -44,66 +44,19 @@ import java.util.List;
  * This class tests `accumulate` method without order argument.
  */
 @RunWith(Enclosed.class)
-public class LastValueAggFunctionWithoutOrderTest {
+public final class LastValueAggFunctionWithoutOrderTest {
 
-	/**
-	 * The base test class for LastValueAggFunction without order.
-	 */
-	public abstract static class LastValueAggFunctionWithoutOrderTestBase<T>
-			extends AggFunctionTestBase<T, GenericRow> {
-
-		@Override
-		protected Class<?> getAccClass() {
-			return GenericRow.class;
-		}
-	}
-
-	/**
-	 * Test LastValueAggFunction for number type.
-	 */
-	public abstract static class NumberLastValueAggFunctionWithoutOrderTestBase<T>
-			extends LastValueAggFunctionWithoutOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("3")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("3"),
-					null,
-					getValue("3")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteLastValueAggFunction.
 	 */
-	public static class ByteLastValueAggFunctionWithoutOrderTest
+	public static final class ByteLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Byte> {
 
 		@Override
@@ -120,7 +73,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for ShortLastValueAggFunction.
 	 */
-	public static class ShortLastValueAggFunctionWithoutOrderTest
+	public static final class ShortLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Short> {
 
 		@Override
@@ -137,7 +90,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for IntLastValueAggFunction.
 	 */
-	public static class IntLastValueAggFunctionWithoutOrderTest
+	public static final class IntLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Integer> {
 
 		@Override
@@ -154,7 +107,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for LongLastValueAggFunction.
 	 */
-	public static class LongLastValueAggFunctionWithoutOrderTest
+	public static final class LongLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Long> {
 
 		@Override
@@ -171,7 +124,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for FloatLastValueAggFunction.
 	 */
-	public static class FloatLastValueAggFunctionWithoutOrderTest
+	public static final class FloatLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Float> {
 
 		@Override
@@ -188,7 +141,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DoubleLastValueAggFunction.
 	 */
-	public static class DoubleLastValueAggFunctionWithoutOrderTest
+	public static final class DoubleLastValueAggFunctionWithoutOrderTest
 			extends NumberLastValueAggFunctionWithoutOrderTestBase<Double> {
 
 		@Override
@@ -205,7 +158,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for BooleanLastValueAggFunction.
 	 */
-	public static class BooleanLastValueAggFunctionWithoutOrderTest extends
+	public static final class BooleanLastValueAggFunctionWithoutOrderTest extends
 			LastValueAggFunctionWithoutOrderTestBase<Boolean> {
 
 		@Override
@@ -261,7 +214,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DecimalLastValueAggFunction.
 	 */
-	public static class DecimalLastValueAggFunctionWithoutOrderTest extends
+	public static final class DecimalLastValueAggFunctionWithoutOrderTest extends
 			LastValueAggFunctionWithoutOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -313,7 +266,7 @@ public class LastValueAggFunctionWithoutOrderTest {
 	/**
 	 * Test for StringLastValueAggFunction.
 	 */
-	public static class StringLastValueAggFunctionWithoutOrderTest extends
+	public static final class StringLastValueAggFunctionWithoutOrderTest extends
 			LastValueAggFunctionWithoutOrderTestBase<BinaryString> {
 
 		@Override
@@ -360,4 +313,63 @@ public class LastValueAggFunctionWithoutOrderTest {
 			return new StringLastValueAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide common inputs and declare the accumulator
+	// class type for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for LastValueAggFunction without order.
+	 */
+	public abstract static class LastValueAggFunctionWithoutOrderTestBase<T>
+		extends AggFunctionTestBase<T, GenericRow> {
+
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+	}
+
+	/**
+	 * Test LastValueAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueAggFunctionWithoutOrderTestBase<T>
+		extends LastValueAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("3")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("3"),
+				null,
+				getValue("3")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
index 8ef1cf4..bb3e052 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
@@ -45,97 +45,20 @@ import java.util.List;
  * This class tests `accumulate` method with order argument.
  */
 @RunWith(Enclosed.class)
-public class LastValueWithRetractAggFunctionWithOrderTest {
+public final class LastValueWithRetractAggFunctionWithOrderTest {
 
-	/**
-	 * The base test class for LastValueWithRetractAggFunction with order.
-	 */
-	public abstract static class LastValueWithRetractAggFunctionWithOrderTestBase<T>
-			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
-
-		@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
-		}
-	}
-
-	/**
-	 * Test LastValueWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberLastValueWithRetractAggFunctionWithOrderTestBase<T>
-			extends LastValueWithRetractAggFunctionWithOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null,
-							getValue("3"),
-							getValue("2"),
-							getValue("-99")
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("5")
-					)
-			);
-		}
-
-		@Override
-		protected List<List<Long>> getInputOrderSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							10L,
-							2L,
-							5L,
-							6L,
-							11L,
-							13L,
-							7L,
-							5L
-					),
-					Arrays.asList(
-							8L,
-							6L,
-							9L,
-							5L
-					),
-					Arrays.asList(
-							null,
-							6L,
-							4L,
-							3L
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("3"),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - FirstLastValueAggFunctionWithOrderTestBase -> tests specific for FirstValue and LastValue
+	//  - AggFunctionTestBase -> tests that apply to all aggregate functions
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteLastValueWithRetractAggFunction.
 	 */
-	public static class ByteLastValueWithRetractAggFunctionWithOrderTest
+	public static final class ByteLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Byte> {
 
 		@Override
@@ -152,7 +75,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for ShortLastValueWithRetractAggFunction.
 	 */
-	public static class ShortLastValueWithRetractAggFunctionWithOrderTest
+	public static final class ShortLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Short> {
 
 		@Override
@@ -169,7 +92,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for IntLastValueWithRetractAggFunction.
 	 */
-	public static class IntLastValueWithRetractAggFunctionWithOrderTest
+	public static final class IntLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Integer> {
 
 		@Override
@@ -186,7 +109,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for LongLastValueWithRetractAggFunction.
 	 */
-	public static class LongLastValueWithRetractAggFunctionWithOrderTest
+	public static final class LongLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Long> {
 
 		@Override
@@ -203,7 +126,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for FloatLastValueWithRetractAggFunction.
 	 */
-	public static class FloatLastValueWithRetractAggFunctionWithOrderTest
+	public static final class FloatLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Float> {
 
 		@Override
@@ -220,7 +143,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for DoubleLastValueWithRetractAggFunction.
 	 */
-	public static class DoubleLastValueWithRetractAggFunctionWithOrderTest
+	public static final class DoubleLastValueWithRetractAggFunctionWithOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Double> {
 
 		@Override
@@ -237,7 +160,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for BooleanLastValueWithRetractAggFunction.
 	 */
-	public static class BooleanLastValueWithRetractAggFunctionWithOrderTest
+	public static final class BooleanLastValueWithRetractAggFunctionWithOrderTest
 			extends LastValueWithRetractAggFunctionWithOrderTestBase<Boolean> {
 
 		@Override
@@ -324,10 +247,11 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 		}
 	}
 
+
 	/**
 	 * Test for DecimalLastValueWithRetractAggFunction.
 	 */
-	public static class DecimalLastValueWithRetractAggFunctionWithOrderTest
+	public static final class DecimalLastValueWithRetractAggFunctionWithOrderTest
 			extends LastValueWithRetractAggFunctionWithOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -407,7 +331,7 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 	/**
 	 * Test for StringLastValueWithRetractAggFunction.
 	 */
-	public static class StringLastValueWithRetractAggFunctionWithOrderTest
+	public static final class StringLastValueWithRetractAggFunctionWithOrderTest
 			extends LastValueWithRetractAggFunctionWithOrderTestBase<BinaryString> {
 
 		@Override
@@ -487,4 +411,94 @@ public class LastValueWithRetractAggFunctionWithOrderTest {
 			return new StringLastValueWithRetractAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide common inputs and accessor for retract function
+	// for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for LastValueWithRetractAggFunction with order.
+	 */
+	public abstract static class LastValueWithRetractAggFunctionWithOrderTestBase<T>
+		extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+		}
+	}
+
+	/**
+	 * Test LastValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueWithRetractAggFunctionWithOrderTestBase<T>
+		extends LastValueWithRetractAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null,
+					getValue("3"),
+					getValue("2"),
+					getValue("-99")
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("5")
+				)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					10L,
+					2L,
+					5L,
+					6L,
+					11L,
+					13L,
+					7L,
+					5L
+				),
+				Arrays.asList(
+					8L,
+					6L,
+					9L,
+					5L
+				),
+				Arrays.asList(
+					null,
+					6L,
+					4L,
+					3L
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("3"),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
index 801a4ed..ed72709 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
@@ -45,71 +45,19 @@ import java.util.List;
  * This class tests `accumulate` method without order argument.
  */
 @RunWith(Enclosed.class)
-public class LastValueWithRetractAggFunctionWithoutOrderTest {
+public final class LastValueWithRetractAggFunctionWithoutOrderTest {
 
-	/**
-	 * The base test class for LastValueWithRetractAggFunction without order.
-	 */
-	public abstract static class LastValueWithRetractAggFunctionWithoutOrderTestBase<T>
-			extends AggFunctionTestBase<T, GenericRow> {
-
-		@Override
-		protected Class<?> getAccClass() {
-			return GenericRow.class;
-		}
-
-		@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
-		}
-	}
-
-	/**
-	 * Test LastValueWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<T>
-			extends LastValueWithRetractAggFunctionWithoutOrderTestBase<T> {
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getValue("-99"),
-							getValue("3"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10"),
-							null,
-							getValue("3")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getValue("3"),
-					null,
-					getValue("3")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteLastValueWithRetractAggFunction.
 	 */
-	public static class ByteLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class ByteLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Byte> {
 
 		@Override
@@ -126,7 +74,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for ShortLastValueWithRetractAggFunction.
 	 */
-	public static class ShortLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class ShortLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Short> {
 
 		@Override
@@ -143,7 +91,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for IntLastValueWithRetractAggFunction.
 	 */
-	public static class IntLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class IntLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Integer> {
 
 		@Override
@@ -160,7 +108,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for LongLastValueWithRetractAggFunction.
 	 */
-	public static class LongLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class LongLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Long> {
 
 		@Override
@@ -177,7 +125,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for FloatLastValueWithRetractAggFunction.
 	 */
-	public static class FloatLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class FloatLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Float> {
 
 		@Override
@@ -194,7 +142,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DoubleLastValueWithRetractAggFunction.
 	 */
-	public static class DoubleLastValueWithRetractAggFunctionWithoutOrderTest
+	public static final class DoubleLastValueWithRetractAggFunctionWithoutOrderTest
 			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Double> {
 
 		@Override
@@ -211,7 +159,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for BooleanLastValueWithRetractAggFunction.
 	 */
-	public static class BooleanLastValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class BooleanLastValueWithRetractAggFunctionWithoutOrderTest extends
 			LastValueWithRetractAggFunctionWithoutOrderTestBase<Boolean> {
 
 		@Override
@@ -267,7 +215,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for DecimalLastValueWithRetractAggFunction.
 	 */
-	public static class DecimalLastValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class DecimalLastValueWithRetractAggFunctionWithoutOrderTest extends
 			LastValueWithRetractAggFunctionWithoutOrderTestBase<Decimal> {
 
 		private int precision = 20;
@@ -319,7 +267,7 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 	/**
 	 * Test for StringLastValueWithRetractAggFunction.
 	 */
-	public static class StringLastValueWithRetractAggFunctionWithoutOrderTest extends
+	public static final class StringLastValueWithRetractAggFunctionWithoutOrderTest extends
 			LastValueWithRetractAggFunctionWithoutOrderTestBase<BinaryString> {
 
 		@Override
@@ -365,4 +313,71 @@ public class LastValueWithRetractAggFunctionWithoutOrderTest {
 			return new StringLastValueWithRetractAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide:
+	//  - common inputs
+	//  - declare the accumulator class
+	//  - accessor for retract function
+	//  for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for LastValueWithRetractAggFunction without order.
+	 */
+	public abstract static class LastValueWithRetractAggFunctionWithoutOrderTestBase<T>
+		extends AggFunctionTestBase<T, GenericRow> {
+
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
+	}
+
+	/**
+	 * Test LastValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<T>
+		extends LastValueWithRetractAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("-99"),
+					getValue("3"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10"),
+					null,
+					getValue("3")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getValue("3"),
+				null,
+				getValue("3")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWithRetractAggFunctionTest.java
index 5c5566e..d8a848b 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWithRetractAggFunctionTest.java
@@ -29,7 +29,7 @@ import java.util.List;
 /**
  * Test case for built-in LISTAGG with retraction aggregate function.
  */
-public class ListAggWithRetractAggFunctionTest
+public final class ListAggWithRetractAggFunctionTest
 	extends AggFunctionTestBase<BinaryString, ListAggWithRetractAccumulator> {
 
 	@Override
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWsWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWsWithRetractAggFunctionTest.java
index 08c4998..07ca080 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWsWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/ListAggWsWithRetractAggFunctionTest.java
@@ -35,7 +35,7 @@ import static org.junit.Assert.assertEquals;
 /**
  * Test case for built-in ListAggWs with retraction aggregate function.
  */
-public class ListAggWsWithRetractAggFunctionTest
+public final class ListAggWsWithRetractAggFunctionTest
 	extends AggFunctionTestBase<BinaryString, ListAggWsWithRetractAccumulator> {
 
 	@Override
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
index 0ee6899..f9eb15b 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
@@ -50,80 +50,19 @@ import java.util.List;
  * Test case for built-in Max with retraction aggregate function.
  */
 @RunWith(Enclosed.class)
-public class MaxWithRetractAggFunctionTest {
+public final class MaxWithRetractAggFunctionTest {
 
-	/**
-	 * The base test class for MaxWithRetractAggFunction.
-	 */
-	public abstract static class MaxWithRetractAggFunctionTestBase<T>
-			extends AggFunctionTestBase<T, MaxWithRetractAccumulator<T>> {
-
-		@Override
-		protected Class<?> getAccClass() {
-			return MaxWithRetractAccumulator.class;
-		}
-
-		@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
-		}
-	}
-
-	/**
-	 * Test MaxWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberMaxWithRetractAggFunctionTest<T> extends MaxWithRetractAggFunctionTestBase {
-		protected abstract T getMinValue();
-
-		protected abstract T getMaxValue();
-
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getMaxValue(),
-							getValue("-99"),
-							getValue("3"),
-							getValue("56"),
-							getValue("0"),
-							getMinValue(),
-							getValue("-20"),
-							getValue("17"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getMaxValue(),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteMaxWithRetractAggFunction.
 	 */
-	public static class ByteMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Byte> {
+	public static final class ByteMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Byte> {
 
 		@Override
 		protected Byte getMinValue() {
@@ -149,7 +88,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for ShortMaxWithRetractAggFunction.
 	 */
-	public static class ShortMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Short> {
+	public static final class ShortMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Short> {
 
 		@Override
 		protected Short getMinValue() {
@@ -175,7 +114,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for IntMaxWithRetractAggFunction.
 	 */
-	public static class IntMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Integer> {
+	public static final class IntMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Integer> {
 
 		@Override
 		protected Integer getMinValue() {
@@ -201,7 +140,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for LongMaxWithRetractAggFunction.
 	 */
-	public static class LongMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Long> {
+	public static final class LongMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Long> {
 
 		@Override
 		protected Long getMinValue() {
@@ -227,7 +166,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for FloatMaxWithRetractAggFunction.
 	 */
-	public static class FloatMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Float> {
+	public static final class FloatMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Float> {
 
 		@Override
 		protected Float getMinValue() {
@@ -253,7 +192,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for DoubleMaxWithRetractAggFunction.
 	 */
-	public static class DoubleMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Double> {
+	public static final class DoubleMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Double> {
 
 		@Override
 		protected Double getMinValue() {
@@ -279,7 +218,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for BooleanMaxWithRetractAggFunction.
 	 */
-	public static class BooleanMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Boolean> {
+	public static final class BooleanMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Boolean> {
 
 		@Override
 		protected List<List<Boolean>> getInputValueSets() {
@@ -344,7 +283,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for DecimalMaxWithRetractAggFunction.
 	 */
-	public static class DecimalMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Decimal> {
+	public static final class DecimalMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Decimal> {
 
 		private int precision = 20;
 		private int scale = 6;
@@ -395,7 +334,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for StringMaxWithRetractAggFunction.
 	 */
-	public static class StringMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<BinaryString> {
+	public static final class StringMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<BinaryString> {
 
 		@Override
 		protected List<List<BinaryString>> getInputValueSets() {
@@ -444,7 +383,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for TimestampMaxWithRetractAggFunction.
 	 */
-	public static class TimestampMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
+	public static final class TimestampMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
 
 		@Override
 		protected List<List<SqlTimestamp>> getInputValueSets() {
@@ -488,7 +427,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for TimestampMaxWithRetractAggFunction, precision is 9.
 	 */
-	public static class Timestamp9MaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
+	public static final class Timestamp9MaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
 
 		@Override
 		protected List<List<SqlTimestamp>> getInputValueSets() {
@@ -534,7 +473,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for DateMaxWithRetractAggFunction.
 	 */
-	public static class DateMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Date> {
+	public static final class DateMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Date> {
 
 		@Override
 		protected List<List<Date>> getInputValueSets() {
@@ -578,7 +517,7 @@ public class MaxWithRetractAggFunctionTest {
 	/**
 	 * Test for TimeMaxWithRetractAggFunction.
 	 */
-	public static class TimeMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Time> {
+	public static final class TimeMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Time> {
 
 		@Override
 		protected List<List<Time>> getInputValueSets() {
@@ -618,4 +557,80 @@ public class MaxWithRetractAggFunctionTest {
 			return new TimeMaxWithRetractAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide:
+	//  - common inputs
+	//  - declare the accumulator class
+	//  - accessor for retract function
+	//  for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for MaxWithRetractAggFunction.
+	 */
+	public abstract static class MaxWithRetractAggFunctionTestBase<T>
+		extends AggFunctionTestBase<T, MaxWithRetractAccumulator<T>> {
+
+		@Override
+		protected Class<?> getAccClass() {
+			return MaxWithRetractAccumulator.class;
+		}
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
+	}
+
+	/**
+	 * Test MaxWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberMaxWithRetractAggFunctionTest<T> extends MaxWithRetractAggFunctionTestBase<T> {
+		protected abstract T getMinValue();
+
+		protected abstract T getMaxValue();
+
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getMaxValue(),
+					getValue("-99"),
+					getValue("3"),
+					getValue("56"),
+					getValue("0"),
+					getMinValue(),
+					getValue("-20"),
+					getValue("17"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getMaxValue(),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
index 3d48b9b..a922cf2 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
@@ -50,80 +50,19 @@ import java.util.List;
  * Test case for built-in Min with retraction aggregate function.
  */
 @RunWith(Enclosed.class)
-public class MinWithRetractAggFunctionTest {
+public final class MinWithRetractAggFunctionTest {
 
-	/**
-	 * The base test class for MinWithRetractAggFunction.
-	 */
-	public abstract static class MinWithRetractAggFunctionTestBase<T>
-			extends AggFunctionTestBase<T, MinWithRetractAccumulator<T>> {
-
-		@Override
-		protected Class<?> getAccClass() {
-			return MinWithRetractAccumulator.class;
-		}
-
-		@Override
-		protected Method getRetractFunc() throws NoSuchMethodException {
-			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
-		}
-	}
-
-	/**
-	 * Test MinWithRetractAggFunction for number type.
-	 */
-	public abstract static class NumberMinWithRetractAggFunctionTestBase<T> extends MinWithRetractAggFunctionTestBase<T> {
-		protected abstract T getMinValue();
-
-		protected abstract T getMaxValue();
-
-		protected abstract T getValue(String v);
-
-		@Override
-		protected List<List<T>> getInputValueSets() {
-			return Arrays.asList(
-					Arrays.asList(
-							getValue("1"),
-							null,
-							getMaxValue(),
-							getValue("-99"),
-							getValue("3"),
-							getValue("56"),
-							getValue("0"),
-							getMinValue(),
-							getValue("-20"),
-							getValue("17"),
-							null
-					),
-					Arrays.asList(
-							null,
-							null,
-							null,
-							null,
-							null,
-							null
-					),
-					Arrays.asList(
-							null,
-							getValue("10")
-					)
-			);
-		}
-
-		@Override
-		protected List<T> getExpectedResults() {
-			return Arrays.asList(
-					getMinValue(),
-					null,
-					getValue("10")
-			);
-		}
-	}
+	// --------------------------------------------------------------------------------------------
+	// Test sets for a particular type being aggregated
+	//
+	// Actual tests are implemented in:
+	//  - AggFunctionTestBase
+	// --------------------------------------------------------------------------------------------
 
 	/**
 	 * Test for ByteMinWithRetractAggFunction.
 	 */
-	public static class ByteMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Byte> {
+	public static final class ByteMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Byte> {
 
 		@Override
 		protected Byte getMinValue() {
@@ -149,7 +88,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for ShortMinWithRetractAggFunction.
 	 */
-	public static class ShortMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Short> {
+	public static final class ShortMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Short> {
 
 		@Override
 		protected Short getMinValue() {
@@ -175,7 +114,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for IntMinWithRetractAggFunction.
 	 */
-	public static class IntMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Integer> {
+	public static final class IntMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Integer> {
 
 		@Override
 		protected Integer getMinValue() {
@@ -201,7 +140,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for LongMinWithRetractAggFunction.
 	 */
-	public static class LongMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Long> {
+	public static final class LongMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Long> {
 
 		@Override
 		protected Long getMinValue() {
@@ -227,7 +166,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for FloatMinWithRetractAggFunction.
 	 */
-	public static class FloatMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Float> {
+	public static final class FloatMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Float> {
 
 		@Override
 		protected Float getMinValue() {
@@ -253,7 +192,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for DoubleMinWithRetractAggFunction.
 	 */
-	public static class DoubleMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Double> {
+	public static final class DoubleMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Double> {
 
 		@Override
 		protected Double getMinValue() {
@@ -279,7 +218,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for BooleanMinWithRetractAggFunction.
 	 */
-	public static class BooleanMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Boolean> {
+	public static final class BooleanMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Boolean> {
 
 		@Override
 		protected List<List<Boolean>> getInputValueSets() {
@@ -334,7 +273,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for DecimalMinWithRetractAggFunction.
 	 */
-	public static class DecimalMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Decimal> {
+	public static final class DecimalMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Decimal> {
 
 		private int precision = 20;
 		private int scale = 6;
@@ -385,7 +324,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for StringMinWithRetractAggFunction.
 	 */
-	public static class StringMinWithRetractAggFunctionTest
+	public static final class StringMinWithRetractAggFunctionTest
 			extends MinWithRetractAggFunctionTestBase<BinaryString> {
 
 		@Override
@@ -435,7 +374,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for TimestampMinWithRetractAggFunction.
 	 */
-	public static class TimestampMinWithRetractAggFunctionTest
+	public static final class TimestampMinWithRetractAggFunctionTest
 			extends MinWithRetractAggFunctionTestBase<SqlTimestamp> {
 
 		@Override
@@ -480,7 +419,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for TimestampMinWithRetractAggFunction, precision is 9.
 	 */
-	public static class Timestamp9MinWithRetractAggFunctionTest
+	public static final class Timestamp9MinWithRetractAggFunctionTest
 			extends MinWithRetractAggFunctionTestBase<SqlTimestamp> {
 
 		@Override
@@ -527,7 +466,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for DateMinWithRetractAggFunction.
 	 */
-	public static class DateMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Date> {
+	public static final class DateMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Date> {
 
 		@Override
 		protected List<List<Date>> getInputValueSets() {
@@ -571,7 +510,7 @@ public class MinWithRetractAggFunctionTest {
 	/**
 	 * Test for TimeMinWithRetractAggFunction.
 	 */
-	public static class TimeMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Time> {
+	public static final class TimeMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Time> {
 
 		@Override
 		protected List<List<Time>> getInputValueSets() {
@@ -611,4 +550,80 @@ public class MinWithRetractAggFunctionTest {
 			return new TimeMinWithRetractAggFunction();
 		}
 	}
+
+	// --------------------------------------------------------------------------------------------
+	// This section contain base classes that provide:
+	//  - common inputs
+	//  - declare the accumulator class
+	//  - accessor for retract function
+	//  for tests declared above.
+	// --------------------------------------------------------------------------------------------
+
+	/**
+	 * The base test class for MinWithRetractAggFunction.
+	 */
+	public abstract static class MinWithRetractAggFunctionTestBase<T>
+		extends AggFunctionTestBase<T, MinWithRetractAccumulator<T>> {
+
+		@Override
+		protected Class<?> getAccClass() {
+			return MinWithRetractAccumulator.class;
+		}
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
+	}
+
+	/**
+	 * Test MinWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberMinWithRetractAggFunctionTestBase<T> extends MinWithRetractAggFunctionTestBase<T> {
+		protected abstract T getMinValue();
+
+		protected abstract T getMaxValue();
+
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+				Arrays.asList(
+					getValue("1"),
+					null,
+					getMaxValue(),
+					getValue("-99"),
+					getValue("3"),
+					getValue("56"),
+					getValue("0"),
+					getMinValue(),
+					getValue("-20"),
+					getValue("17"),
+					null
+				),
+				Arrays.asList(
+					null,
+					null,
+					null,
+					null,
+					null,
+					null
+				),
+				Arrays.asList(
+					null,
+					getValue("10")
+				)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+				getMinValue(),
+				null,
+				getValue("10")
+			);
+		}
+	}
 }


[flink] 01/02: [FLINK-15706][table-planner-blink] Fix LastValueAggFunctionWithOrderTest compilation error due to incompatible types

Posted by dw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dwysakowicz pushed a commit to branch release-1.10
in repository https://gitbox.apache.org/repos/asf/flink.git

commit 1fa29014ad8dba0a5595c51cf01e5ace1d7930af
Author: JingsongLi <lz...@aliyun.com>
AuthorDate: Tue Jan 21 19:09:15 2020 +0800

    [FLINK-15706][table-planner-blink] Fix LastValueAggFunctionWithOrderTest compilation error due to incompatible types
    
    This partially reverts the commit dcc1330375826b779e4902176bb2473704dabb11 and uses the initial approach from #10158 of using Enclosed annotation. The problem with the TestSpec approach was that the top level classes shouldn't use generics as they are stripped when instantiated by JUnit runner which may lead to generic signature mismatch.
    
    This closes #10915
---
 .../aggfunctions/AggFunctionTestBase.java          |  23 -
 ...FirstLastValueAggFunctionWithOrderTestBase.java |  17 -
 .../FirstValueAggFunctionWithOrderTest.java        | 742 +++++++++--------
 .../FirstValueAggFunctionWithoutOrderTest.java     | 514 +++++++-----
 ...stValueWithRetractAggFunctionWithOrderTest.java | 748 +++++++++--------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 522 +++++++-----
 .../LastValueAggFunctionWithOrderTest.java         | 742 +++++++++--------
 .../LastValueAggFunctionWithoutOrderTest.java      | 517 +++++++-----
 ...stValueWithRetractAggFunctionWithOrderTest.java | 760 +++++++++--------
 ...alueWithRetractAggFunctionWithoutOrderTest.java | 523 +++++++-----
 .../MaxWithRetractAggFunctionTest.java             | 902 +++++++++++++--------
 .../MinWithRetractAggFunctionTest.java             | 896 ++++++++++++--------
 12 files changed, 3980 insertions(+), 2926 deletions(-)

diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/AggFunctionTestBase.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/AggFunctionTestBase.java
index 6202359..365e874 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/AggFunctionTestBase.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/AggFunctionTestBase.java
@@ -54,29 +54,6 @@ import static org.junit.Assert.assertThat;
  */
 public abstract class AggFunctionTestBase<T, ACC> {
 
-	/**
-	 * Spec for parameterized aggregate function tests.
-	 */
-	protected static class AggFunctionTestSpec<T, ACC> {
-		final AggregateFunction<T, ACC> aggregator;
-		final List<List<T>> inputValueSets;
-		final List<T> expectedResults;
-
-		public AggFunctionTestSpec(
-				AggregateFunction<T, ACC> aggregator,
-				List<List<T>> inputValueSets,
-				List<T> expectedResults) {
-			this.aggregator = aggregator;
-			this.inputValueSets = inputValueSets;
-			this.expectedResults = expectedResults;
-		}
-
-		@Override
-		public String toString() {
-			return aggregator.getClass().getSimpleName();
-		}
-	}
-
 	protected abstract List<List<T>> getInputValueSets();
 
 	protected abstract List<T> getExpectedResults();
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstLastValueAggFunctionWithOrderTestBase.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstLastValueAggFunctionWithOrderTestBase.java
index 06f84a5..96eb0e2 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstLastValueAggFunctionWithOrderTestBase.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstLastValueAggFunctionWithOrderTestBase.java
@@ -36,23 +36,6 @@ import java.util.List;
  */
 public abstract class FirstLastValueAggFunctionWithOrderTestBase<T> extends AggFunctionTestBase<T, GenericRow> {
 
-	/**
-	 * An AggFunctionTestSpec with input order.
-	 */
-	protected static class AggFunctionWithOrderTestSpec<T> extends AggFunctionTestSpec<T, GenericRow> {
-
-		final List<List<Long>> inputOrderSets;
-
-		public AggFunctionWithOrderTestSpec(
-				AggregateFunction<T, GenericRow> aggregator,
-				List<List<Long>> inputOrderSets,
-				List<List<T>> inputValueSets,
-				List<T> expectedResults) {
-			super(aggregator, inputValueSets, expectedResults);
-			this.inputOrderSets = inputOrderSets;
-		}
-	}
-
 	protected Method getAccumulateFunc() throws NoSuchMethodException {
 		return getAggregator().getClass().getMethod("accumulate", getAccClass(), Object.class, Long.class);
 	}
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
index dbd9b83..658541c 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithOrderTest.java
@@ -33,357 +33,447 @@ import org.apache.flink.table.planner.functions.aggfunctions.FirstValueAggFuncti
 import org.apache.flink.table.planner.functions.aggfunctions.FirstValueAggFunction.StringFirstValueAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in FirstValue aggregate function.
  * This class tests `accumulate` method with order argument.
  */
-@RunWith(Parameterized.class)
-public class FirstValueAggFunctionWithOrderTest<T> extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+@RunWith(Enclosed.class)
+public class FirstValueAggFunctionWithOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionWithOrderTestSpec<T> aggFunctionTestSpec;
+	/**
+	 * The base test class for FirstValueAggFunction with order.
+	 */
+	public abstract static class FirstValueAggFunctionWithOrderTestBase<T>
+			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+	}
+
+	/**
+	 * Test FirstValueAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueAggFunctionWithOrderTestBase<T>
+			extends FirstValueAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null,
+							getValue("3"),
+							getValue("2"),
+							getValue("-99")
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("5")
+					)
+			);
+		}
 
-	@Override
-	protected List<List<Long>> getInputOrderSets() {
-		return aggFunctionTestSpec.inputOrderSets;
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							6L,
+							11L,
+							3L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							null,
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("3"),
+					null,
+					getValue("5")
+			);
+		}
 	}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+	/**
+	 * Test for ByteFirstValueAggFunction.
+	 */
+	public static class ByteFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteFirstValueAggFunction();
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ShortFirstValueAggFunction.
+	 */
+	public static class ShortFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortFirstValueAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for IntFirstValueAggFunction.
+	 */
+	public static class IntFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntFirstValueAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ByteFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ShortFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new IntFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new LongFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new FloatFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DoubleFirstValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new BooleanFirstValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										6L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										1L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										11L,
-										3L,
-										7L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										9L,
-										5L
-								),
-								Arrays.asList(
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								false,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DecimalFirstValueAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										1L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L,
-										2L
-								),
-								Arrays.asList(
-										6L,
-										5L,
-										null,
-										8L,
-										null
-								),
-								Arrays.asList(
-										8L,
-										6L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringFirstValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new StringFirstValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										5L
-								),
-								Arrays.asList(
-										8L,
-										6L
-								),
-								Arrays.asList(
-										6L,
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("def"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("e")
-						)
-				)
-				);
+	/**
+	 * Test for LongFirstValueAggFunction.
+	 */
+	public static class LongFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongFirstValueAggFunction();
+		}
 	}
 
-	private static List<List<Long>> numberInputOrderSets() {
-		return Arrays.asList(
-				Arrays.asList(
-						10L,
-						2L,
-						5L,
-						6L,
-						11L,
-						3L,
-						7L,
-						5L
-				),
-				Arrays.asList(
-						8L,
-						6L,
-						9L,
-						5L
-				),
-				Arrays.asList(
-						null,
-						6L,
-						4L,
-						3L
-				)
-		);
+	/**
+	 * Test for FloatFirstValueAggFunction.
+	 */
+	public static class FloatFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatFirstValueAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null,
-						strToValueFun.apply("3"),
-						strToValueFun.apply("2"),
-						strToValueFun.apply("-99")
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("5")
-				)
-		);
+	/**
+	 * Test for DoubleFirstValueAggFunction.
+	 */
+	public static class DoubleFirstValueAggFunctionWithOrderTest
+			extends NumberFirstValueAggFunctionWithOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleFirstValueAggFunction();
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("3"),
-				null,
-				strToValueFun.apply("5")
-		);
+	/**
+	 * Test for BooleanFirstValueAggFunction.
+	 */
+	public static class BooleanFirstValueAggFunctionWithOrderTest
+			extends FirstValueAggFunctionWithOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							6L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							1L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							11L,
+							3L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					false,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanFirstValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DecimalFirstValueAggFunction.
+	 */
+	public static class DecimalFirstValueAggFunctionWithOrderTest
+			extends FirstValueAggFunctionWithOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							1L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L,
+							2L
+					),
+					Arrays.asList(
+							6L,
+							5L,
+							null,
+							8L,
+							null
+					),
+					Arrays.asList(
+							8L,
+							6L
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("-1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalFirstValueAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
+	}
+
+	/**
+	 * Test for StringFirstValueAggFunction.
+	 */
+	public static class StringFirstValueAggFunctionWithOrderTest
+			extends FirstValueAggFunctionWithOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L
+					),
+					Arrays.asList(
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("def"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("e")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringFirstValueAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
index 3bfe52a..62be99c 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueAggFunctionWithoutOrderTest.java
@@ -33,243 +33,329 @@ import org.apache.flink.table.planner.functions.aggfunctions.FirstValueAggFuncti
 import org.apache.flink.table.planner.functions.aggfunctions.FirstValueAggFunction.StringFirstValueAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in FirstValue aggregate function.
  * This class tests `accumulate` method without order argument.
  */
-@RunWith(Parameterized.class)
-public class FirstValueAggFunctionWithoutOrderTest<T> extends AggFunctionTestBase<T, GenericRow> {
+@RunWith(Enclosed.class)
+public class FirstValueAggFunctionWithoutOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, GenericRow> aggFunctionTestSpec;
+	/**
+	 * The base test class for FirstValueAggFunction without order.
+	 */
+	public abstract static class FirstValueAggFunctionWithoutOrderTestBase<T>
+			extends AggFunctionTestBase<T, GenericRow> {
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+	}
+
+	/**
+	 * Test FirstValueAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueAggFunctionWithoutOrderTest<T>
+			extends FirstValueAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("3")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("10")
+			);
+		}
+	}
+
+	/**
+	 * Test for ByteFirstValueAggFunction.
+	 */
+	public static class ByteFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Byte> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteFirstValueAggFunction();
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ShortFirstValueAggFunction.
+	 */
+	public static class ShortFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortFirstValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for IntFirstValueAggFunction.
+	 */
+	public static class IntFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntFirstValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for LongFirstValueAggFunction.
+	 */
+	public static class LongFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongFirstValueAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for FloatFirstValueAggFunction.
+	 */
+	public static class FloatFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatFirstValueAggFunction();
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return GenericRow.class;
+	/**
+	 * Test for DoubleFirstValueAggFunction.
+	 */
+	public static class DoubleFirstValueAggFunctionWithoutOrderTest
+			extends NumberFirstValueAggFunctionWithoutOrderTest<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleFirstValueAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteFirstValueAggFunction(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortFirstValueAggFunction(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntFirstValueAggFunction(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongFirstValueAggFunction(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatFirstValueAggFunction(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleFirstValueAggFunction(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanFirstValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalFirstValueAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringFirstValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringFirstValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("abc"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("x")
-						)
-				)
-		);
+	/**
+	 * Test for BooleanFirstValueAggFunction.
+	 */
+	public static class BooleanFirstValueAggFunctionWithoutOrderTest extends
+			FirstValueAggFunctionWithoutOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanFirstValueAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("3")
-				)
-		);
+	/**
+	 * Test for DecimalFirstValueAggFunction.
+	 */
+	public static class DecimalFirstValueAggFunctionWithoutOrderTest extends
+			FirstValueAggFunctionWithoutOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalFirstValueAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("1"),
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for StringFirstValueAggFunction.
+	 */
+	public static class StringFirstValueAggFunctionWithoutOrderTest extends
+			FirstValueAggFunctionWithoutOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("abc"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("x")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringFirstValueAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
index caf1485..770f75a 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithOrderTest.java
@@ -33,364 +33,452 @@ import org.apache.flink.table.planner.functions.aggfunctions.FirstValueWithRetra
 import org.apache.flink.table.planner.functions.aggfunctions.FirstValueWithRetractAggFunction.StringFirstValueWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in FirstValue with retract aggregate function.
  * This class tests `accumulate` method with order argument.
  */
-@RunWith(Parameterized.class)
-public class FirstValueWithRetractAggFunctionWithOrderTest<T> extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+@RunWith(Enclosed.class)
+public class FirstValueWithRetractAggFunctionWithOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionWithOrderTestSpec<T> aggFunctionTestSpec;
-
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+	/**
+	 * The base test class for FirstValueWithRetractAggFunction with order.
+	 */
+	public abstract static class FirstValueWithRetractAggFunctionWithOrderTestBase<T>
+			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
 
 	@Override
-	protected List<List<Long>> getInputOrderSets() {
-		return aggFunctionTestSpec.inputOrderSets;
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+		}
 	}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+	/**
+	 * Test FirstValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueWithRetractAggFunctionWithOrderTestBase<T>
+			extends FirstValueWithRetractAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null,
+							getValue("3"),
+							getValue("2"),
+							getValue("-99")
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("5")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							6L,
+							11L,
+							3L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							null,
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("3"),
+					null,
+					getValue("5")
+			);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ByteFirstValueWithRetractAggFunction.
+	 */
+	public static class ByteFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for ShortFirstValueWithRetractAggFunction.
+	 */
+	public static class ShortFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+	/**
+	 * Test for IntFirstValueWithRetractAggFunction.
+	 */
+	public static class IntFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ByteFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ShortFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new IntFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new LongFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new FloatFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DoubleFirstValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new BooleanFirstValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										6L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										1L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										11L,
-										3L,
-										7L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										9L,
-										5L
-								),
-								Arrays.asList(
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								false,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DecimalFirstValueWithRetractAggFunction(
-								DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										1L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L,
-										2L
-								),
-								Arrays.asList(
-										6L,
-										5L,
-										null,
-										8L,
-										null
-								),
-								Arrays.asList(
-										8L,
-										6L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new StringFirstValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										5L
-								),
-								Arrays.asList(
-										8L,
-										6L
-								),
-								Arrays.asList(
-										6L,
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("def"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("e")
-						)
-				)
-		);
+	/**
+	 * Test for LongFirstValueWithRetractAggFunction.
+	 */
+	public static class LongFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongFirstValueWithRetractAggFunction();
+		}
 	}
 
-	private static List<List<Long>> numberInputOrderSets() {
-		return Arrays.asList(
-				Arrays.asList(
-						10L,
-						2L,
-						5L,
-						6L,
-						11L,
-						3L,
-						7L,
-						5L
-				),
-				Arrays.asList(
-						8L,
-						6L,
-						9L,
-						5L
-				),
-				Arrays.asList(
-						null,
-						6L,
-						4L,
-						3L
-				)
-		);
+	/**
+	 * Test for FloatFirstValueWithRetractAggFunction.
+	 */
+	public static class FloatFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatFirstValueWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null,
-						strToValueFun.apply("3"),
-						strToValueFun.apply("2"),
-						strToValueFun.apply("-99")
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("5")
-				)
-		);
+	/**
+	 * Test for DoubleFirstValueWithRetractAggFunction.
+	 */
+	public static class DoubleFirstValueWithRetractAggFunctionWithOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleFirstValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for BooleanFirstValueWithRetractAggFunction.
+	 */
+	public static class BooleanFirstValueWithRetractAggFunctionWithOrderTest
+			extends FirstValueWithRetractAggFunctionWithOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							6L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							1L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							11L,
+							3L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					false,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanFirstValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DecimalFirstValueWithRetractAggFunction.
+	 */
+	public static class DecimalFirstValueWithRetractAggFunctionWithOrderTest
+			extends FirstValueWithRetractAggFunctionWithOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							1L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L,
+							2L
+					),
+					Arrays.asList(
+							6L,
+							5L,
+							null,
+							8L,
+							null
+					),
+					Arrays.asList(
+							8L,
+							6L
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("-1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalFirstValueWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("3"),
-				null,
-				strToValueFun.apply("5")
-		);
+	/**
+	 * Test for StringFirstValueWithRetractAggFunction.
+	 */
+	public static class StringFirstValueWithRetractAggFunctionWithOrderTest
+			extends FirstValueWithRetractAggFunctionWithOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L
+					),
+					Arrays.asList(
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("def"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("e")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringFirstValueWithRetractAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
index 386f803..2125885 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/FirstValueWithRetractAggFunctionWithoutOrderTest.java
@@ -33,250 +33,336 @@ import org.apache.flink.table.planner.functions.aggfunctions.FirstValueWithRetra
 import org.apache.flink.table.planner.functions.aggfunctions.FirstValueWithRetractAggFunction.StringFirstValueWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in FirstValue with retract aggregate function.
  * This class tests `accumulate` method without order argument.
  */
-@RunWith(Parameterized.class)
-public class FirstValueWithRetractAggFunctionWithoutOrderTest<T> extends AggFunctionTestBase<T, GenericRow> {
+@RunWith(Enclosed.class)
+public class FirstValueWithRetractAggFunctionWithoutOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, GenericRow> aggFunctionTestSpec;
+	/**
+	 * The base test class for FirstValueWithRetractAggFunction without order.
+	 */
+	public abstract static class FirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
+			extends AggFunctionTestBase<T, GenericRow> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test FirstValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<T>
+			extends FirstValueWithRetractAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("3")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("1"),
+					null,
+					getValue("10")
+			);
+		}
+	}
+
+	/**
+	 * Test for ByteFirstValueWithRetractAggFunction.
+	 */
+	public static class ByteFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for ShortFirstValueWithRetractAggFunction.
+	 */
+	public static class ShortFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortFirstValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for IntFirstValueWithRetractAggFunction.
+	 */
+	public static class IntFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntFirstValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for LongFirstValueWithRetractAggFunction.
+	 */
+	public static class LongFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return GenericRow.class;
+	/**
+	 * Test for FloatFirstValueWithRetractAggFunction.
+	 */
+	public static class FloatFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+	/**
+	 * Test for DoubleFirstValueWithRetractAggFunction.
+	 */
+	public static class DoubleFirstValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberFirstValueWithRetractAggFunctionWithoutOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleFirstValueWithRetractAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleFirstValueWithRetractAggFunction(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanFirstValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalFirstValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalFirstValueWithRetractAggFunction(
-								DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringFirstValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("abc"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("x")
-						)
-				)
-
-		);
+	/**
+	 * Test for BooleanFirstValueWithRetractAggFunction.
+	 */
+	public static class BooleanFirstValueWithRetractAggFunctionWithoutOrderTest extends
+			FirstValueWithRetractAggFunctionWithoutOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanFirstValueWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("3")
-				)
-		);
+	/**
+	 * Test for DecimalFirstValueWithRetractAggFunction.
+	 */
+	public static class DecimalFirstValueWithRetractAggFunctionWithoutOrderTest extends
+			FirstValueWithRetractAggFunctionWithoutOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalFirstValueWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("1"),
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for StringFirstValueWithRetractAggFunction.
+	 */
+	public static class StringFirstValueWithRetractAggFunctionWithoutOrderTest extends
+			FirstValueWithRetractAggFunctionWithoutOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("abc"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("x")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringFirstValueWithRetractAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
index 1ffad8a..478c3e5 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithOrderTest.java
@@ -33,357 +33,447 @@ import org.apache.flink.table.planner.functions.aggfunctions.LastValueAggFunctio
 import org.apache.flink.table.planner.functions.aggfunctions.LastValueAggFunction.StringLastValueAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in LastValue aggregate function.
  * This class tests `accumulate` method with order argument.
  */
-@RunWith(Parameterized.class)
-public class LastValueAggFunctionWithOrderTest<T> extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+@RunWith(Enclosed.class)
+public class LastValueAggFunctionWithOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionWithOrderTestSpec<T> aggFunctionTestSpec;
+	/**
+	 * The base test class for LastValueAggFunction with order.
+	 */
+	public abstract static class LastValueAggFunctionWithOrderTestBase<T>
+			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+	}
+
+	/**
+	 * Test LastValueAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueAggFunctionWithOrderTestBase<T>
+			extends LastValueAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null,
+							getValue("3"),
+							getValue("2"),
+							getValue("-99")
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("5")
+					)
+			);
+		}
 
-	@Override
-	protected List<List<Long>> getInputOrderSets() {
-		return aggFunctionTestSpec.inputOrderSets;
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							6L,
+							11L,
+							3L,
+							17L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							null,
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("2"),
+					null,
+					getValue("10")
+			);
+		}
 	}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+	/**
+	 * Test for ByteLastValueAggFunction.
+	 */
+	public static class ByteLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteLastValueAggFunction();
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ShortLastValueAggFunction.
+	 */
+	public static class ShortLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortLastValueAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for IntLastValueAggFunction.
+	 */
+	public static class IntLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntLastValueAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ByteLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ShortLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new IntLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new LongLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new FloatLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DoubleLastValueAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new BooleanLastValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										6L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										1L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										3L,
-										11L,
-										7L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										9L,
-										5L
-								),
-								Arrays.asList(
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								false,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DecimalLastValueAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										1L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L,
-										2L
-								),
-								Arrays.asList(
-										6L,
-										5L,
-										null,
-										8L,
-										null
-								),
-								Arrays.asList(
-										8L,
-										6L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringLastValueAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new StringLastValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										null,
-										3L,
-										1L,
-										15L
-								),
-								Arrays.asList(
-										6L,
-										5L
-								),
-								Arrays.asList(
-										8L,
-										6L
-								),
-								Arrays.asList(
-										6L,
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("zzz"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("x")
-						)
-				)
-		);
+	/**
+	 * Test for LongLastValueAggFunction.
+	 */
+	public static class LongLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongLastValueAggFunction();
+		}
 	}
 
-	private static List<List<Long>> numberInputOrderSets() {
-		return Arrays.asList(
-				Arrays.asList(
-						10L,
-						2L,
-						5L,
-						6L,
-						11L,
-						3L,
-						17L,
-						5L
-				),
-				Arrays.asList(
-						8L,
-						6L,
-						9L,
-						5L
-				),
-				Arrays.asList(
-						null,
-						6L,
-						4L,
-						3L
-				)
-		);
+	/**
+	 * Test for FloatLastValueAggFunction.
+	 */
+	public static class FloatLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatLastValueAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null,
-						strToValueFun.apply("3"),
-						strToValueFun.apply("2"),
-						strToValueFun.apply("-99")
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("5")
-				)
-		);
+	/**
+	 * Test for DoubleLastValueAggFunction.
+	 */
+	public static class DoubleLastValueAggFunctionWithOrderTest
+			extends NumberLastValueAggFunctionWithOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleLastValueAggFunction();
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("2"),
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for BooleanLastValueAggFunction.
+	 */
+	public static class BooleanLastValueAggFunctionWithOrderTest
+			extends LastValueAggFunctionWithOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							6L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							1L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							3L,
+							11L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					false,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanLastValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DecimalLastValueAggFunction.
+	 */
+	public static class DecimalLastValueAggFunctionWithOrderTest
+			extends LastValueAggFunctionWithOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							1L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L,
+							2L
+					),
+					Arrays.asList(
+							6L,
+							5L,
+							null,
+							8L,
+							null
+					),
+					Arrays.asList(
+							8L,
+							6L
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalLastValueAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
+	}
+
+	/**
+	 * Test for StringLastValueAggFunction.
+	 */
+	public static class StringLastValueAggFunctionWithOrderTest
+			extends LastValueAggFunctionWithOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							null,
+							3L,
+							1L,
+							15L
+					),
+					Arrays.asList(
+							6L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L
+					),
+					Arrays.asList(
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("zzz"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("x")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringLastValueAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
index 96d199e..4af3f87 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueAggFunctionWithoutOrderTest.java
@@ -33,244 +33,331 @@ import org.apache.flink.table.planner.functions.aggfunctions.LastValueAggFunctio
 import org.apache.flink.table.planner.functions.aggfunctions.LastValueAggFunction.StringLastValueAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in LastValue aggregate function.
  * This class tests `accumulate` method without order argument.
  */
-@RunWith(Parameterized.class)
-public class LastValueAggFunctionWithoutOrderTest<T> extends AggFunctionTestBase<T, GenericRow> {
+@RunWith(Enclosed.class)
+public class LastValueAggFunctionWithoutOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, GenericRow> aggFunctionTestSpec;
+	/**
+	 * The base test class for LastValueAggFunction without order.
+	 */
+	public abstract static class LastValueAggFunctionWithoutOrderTestBase<T>
+			extends AggFunctionTestBase<T, GenericRow> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
+	}
+
+	/**
+	 * Test LastValueAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueAggFunctionWithoutOrderTestBase<T>
+			extends LastValueAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("3")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("3"),
+					null,
+					getValue("3")
+			);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ByteLastValueAggFunction.
+	 */
+	public static class ByteLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteLastValueAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for ShortLastValueAggFunction.
+	 */
+	public static class ShortLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortLastValueAggFunction();
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return GenericRow.class;
+	/**
+	 * Test for IntLastValueAggFunction.
+	 */
+	public static class IntLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntLastValueAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteLastValueAggFunction(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortLastValueAggFunction(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntLastValueAggFunction(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongLastValueAggFunction(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatLastValueAggFunction(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleLastValueAggFunction(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanLastValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalLastValueAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringLastValueAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringLastValueAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a"),
-										null
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("zzz"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("e")
-						)
-				)
-		);
+	/**
+	 * Test for LongLastValueAggFunction.
+	 */
+	public static class LongLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongLastValueAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("3")
-				)
-		);
+	/**
+	 * Test for FloatLastValueAggFunction.
+	 */
+	public static class FloatLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatLastValueAggFunction();
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("3"),
-				null,
-				strToValueFun.apply("3")
-		);
+	/**
+	 * Test for DoubleLastValueAggFunction.
+	 */
+	public static class DoubleLastValueAggFunctionWithoutOrderTest
+			extends NumberLastValueAggFunctionWithoutOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleLastValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for BooleanLastValueAggFunction.
+	 */
+	public static class BooleanLastValueAggFunctionWithoutOrderTest extends
+			LastValueAggFunctionWithoutOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanLastValueAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DecimalLastValueAggFunction.
+	 */
+	public static class DecimalLastValueAggFunctionWithoutOrderTest extends
+			LastValueAggFunctionWithoutOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("999.999", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalLastValueAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
+	}
+
+	/**
+	 * Test for StringLastValueAggFunction.
+	 */
+	public static class StringLastValueAggFunctionWithoutOrderTest extends
+			LastValueAggFunctionWithoutOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a"),
+							null
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("zzz"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("e")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringLastValueAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
index 861953e..8ef1cf4 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithOrderTest.java
@@ -33,372 +33,458 @@ import org.apache.flink.table.planner.functions.aggfunctions.LastValueWithRetrac
 import org.apache.flink.table.planner.functions.aggfunctions.LastValueWithRetractAggFunction.StringLastValueWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in LastValue with retract aggregate function.
  * This class tests `accumulate` method with order argument.
  */
-@RunWith(Parameterized.class)
-public class LastValueWithRetractAggFunctionWithOrderTest<T> extends FirstLastValueAggFunctionWithOrderTestBase<T> {
+@RunWith(Enclosed.class)
+public class LastValueWithRetractAggFunctionWithOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionWithOrderTestSpec<T> aggFunctionTestSpec;
+	/**
+	 * The base test class for LastValueWithRetractAggFunction with order.
+	 */
+	public abstract static class LastValueWithRetractAggFunctionWithOrderTestBase<T>
+			extends FirstLastValueAggFunctionWithOrderTestBase<T> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+		}
+	}
+
+	/**
+	 * Test LastValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueWithRetractAggFunctionWithOrderTestBase<T>
+			extends LastValueWithRetractAggFunctionWithOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null,
+							getValue("3"),
+							getValue("2"),
+							getValue("-99")
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("5")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							6L,
+							11L,
+							13L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							null,
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
 
-	@Override
-	protected List<List<Long>> getInputOrderSets() {
-		return aggFunctionTestSpec.inputOrderSets;
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("3"),
+					null,
+					getValue("10")
+			);
+		}
 	}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+	/**
+	 * Test for ByteLastValueWithRetractAggFunction.
+	 */
+	public static class ByteLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test for ShortLastValueWithRetractAggFunction.
+	 */
+	public static class ShortLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for IntLastValueWithRetractAggFunction.
+	 */
+	public static class IntLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class, Long.class);
+	/**
+	 * Test for LongLastValueWithRetractAggFunction.
+	 */
+	public static class LongLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ByteLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new ShortLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new IntLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new LongLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new FloatLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DoubleLastValueWithRetractAggFunction(),
-						numberInputOrderSets(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new BooleanLastValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										6L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										1L,
-										2L,
-										3L
-								),
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										11L,
-										3L,
-										7L,
-										5L
-								),
-								Arrays.asList(
-										6L,
-										9L,
-										5L
-								),
-								Arrays.asList(
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new DecimalLastValueWithRetractAggFunction(
-								DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										1L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L,
-										2L
-								),
-								Arrays.asList(
-										6L,
-										5L,
-										null,
-										8L,
-										null
-								),
-								Arrays.asList(
-										8L,
-										6L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionWithOrderTestSpec<>(
-						new StringLastValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										10L,
-										2L,
-										5L,
-										null,
-										3L,
-										1L,
-										5L,
-										10L,
-										15L,
-										11L
-								),
-								Arrays.asList(
-										6L,
-										5L
-								),
-								Arrays.asList(
-										8L,
-										6L
-								),
-								Arrays.asList(
-										6L,
-										4L,
-										3L
-								)
-						),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz"),
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("abc")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("def"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("x")
-						)
-				)
-		);
+	/**
+	 * Test for FloatLastValueWithRetractAggFunction.
+	 */
+	public static class FloatLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatLastValueWithRetractAggFunction();
+		}
 	}
 
-	private static List<List<Long>> numberInputOrderSets() {
-		return Arrays.asList(
-				Arrays.asList(
-						10L,
-						2L,
-						5L,
-						6L,
-						11L,
-						13L,
-						7L,
-						5L
-				),
-				Arrays.asList(
-						8L,
-						6L,
-						9L,
-						5L
-				),
-				Arrays.asList(
-						null,
-						6L,
-						4L,
-						3L
-				)
-		);
+	/**
+	 * Test for DoubleLastValueWithRetractAggFunction.
+	 */
+	public static class DoubleLastValueWithRetractAggFunctionWithOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleLastValueWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null,
-						strToValueFun.apply("3"),
-						strToValueFun.apply("2"),
-						strToValueFun.apply("-99")
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("5")
-				)
-		);
+	/**
+	 * Test for BooleanLastValueWithRetractAggFunction.
+	 */
+	public static class BooleanLastValueWithRetractAggFunctionWithOrderTest
+			extends LastValueWithRetractAggFunctionWithOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							6L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							1L,
+							2L,
+							3L
+					),
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							11L,
+							3L,
+							7L,
+							5L
+					),
+					Arrays.asList(
+							6L,
+							9L,
+							5L
+					),
+					Arrays.asList(
+							4L,
+							3L
+					)
+			);
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanLastValueWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("3"),
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for DecimalLastValueWithRetractAggFunction.
+	 */
+	public static class DecimalLastValueWithRetractAggFunctionWithOrderTest
+			extends LastValueWithRetractAggFunctionWithOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							1L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L,
+							2L
+					),
+					Arrays.asList(
+							6L,
+							5L,
+							null,
+							8L,
+							null
+					),
+					Arrays.asList(
+							8L,
+							6L
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("1", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalLastValueWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
-}
 
+	/**
+	 * Test for StringLastValueWithRetractAggFunction.
+	 */
+	public static class StringLastValueWithRetractAggFunctionWithOrderTest
+			extends LastValueWithRetractAggFunctionWithOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz"),
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("abc")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<List<Long>> getInputOrderSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							10L,
+							2L,
+							5L,
+							null,
+							3L,
+							1L,
+							5L,
+							10L,
+							15L,
+							11L
+					),
+					Arrays.asList(
+							6L,
+							5L
+					),
+					Arrays.asList(
+							8L,
+							6L
+					),
+					Arrays.asList(
+							6L,
+							4L,
+							3L
+					)
+			);
+		}
 
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("def"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("x")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringLastValueWithRetractAggFunction();
+		}
+	}
+}
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
index 774f82e..801a4ed 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/LastValueWithRetractAggFunctionWithoutOrderTest.java
@@ -33,251 +33,336 @@ import org.apache.flink.table.planner.functions.aggfunctions.LastValueWithRetrac
 import org.apache.flink.table.planner.functions.aggfunctions.LastValueWithRetractAggFunction.StringLastValueWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in LastValue with retract aggregate function.
  * This class tests `accumulate` method without order argument.
  */
-@RunWith(Parameterized.class)
-public class LastValueWithRetractAggFunctionWithoutOrderTest<T> extends AggFunctionTestBase<T, GenericRow> {
+@RunWith(Enclosed.class)
+public class LastValueWithRetractAggFunctionWithoutOrderTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, GenericRow> aggFunctionTestSpec;
+	/**
+	 * The base test class for LastValueWithRetractAggFunction without order.
+	 */
+	public abstract static class LastValueWithRetractAggFunctionWithoutOrderTestBase<T>
+			extends AggFunctionTestBase<T, GenericRow> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Class<?> getAccClass() {
+			return GenericRow.class;
+		}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test LastValueWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<T>
+			extends LastValueWithRetractAggFunctionWithoutOrderTestBase<T> {
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getValue("-99"),
+							getValue("3"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10"),
+							null,
+							getValue("3")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getValue("3"),
+					null,
+					getValue("3")
+			);
+		}
+	}
+
+	/**
+	 * Test for ByteLastValueWithRetractAggFunction.
+	 */
+	public static class ByteLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Byte> {
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, GenericRow> getAggregator() {
+			return new ByteLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, GenericRow> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for ShortLastValueWithRetractAggFunction.
+	 */
+	public static class ShortLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Short> {
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, GenericRow> getAggregator() {
+			return new ShortLastValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for IntLastValueWithRetractAggFunction.
+	 */
+	public static class IntLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Integer> {
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, GenericRow> getAggregator() {
+			return new IntLastValueWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for LongLastValueWithRetractAggFunction.
+	 */
+	public static class LongLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Long> {
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, GenericRow> getAggregator() {
+			return new LongLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return GenericRow.class;
+	/**
+	 * Test for FloatLastValueWithRetractAggFunction.
+	 */
+	public static class FloatLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Float> {
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, GenericRow> getAggregator() {
+			return new FloatLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+	/**
+	 * Test for DoubleLastValueWithRetractAggFunction.
+	 */
+	public static class DoubleLastValueWithRetractAggFunctionWithoutOrderTest
+			extends NumberLastValueWithRetractAggFunctionWithoutOrderTestBase<Double> {
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, GenericRow> getAggregator() {
+			return new DoubleLastValueWithRetractAggFunction();
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteLastValueWithRetractAggFunction(),
-						numberInputValueSets(Byte::valueOf),
-						numberExpectedResults(Byte::valueOf)
-				),
-				/**
-				 * Test for ShortLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortLastValueWithRetractAggFunction(),
-						numberInputValueSets(Short::valueOf),
-						numberExpectedResults(Short::valueOf)
-				),
-				/**
-				 * Test for IntLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntLastValueWithRetractAggFunction(),
-						numberInputValueSets(Integer::valueOf),
-						numberExpectedResults(Integer::valueOf)
-				),
-				/**
-				 * Test for LongLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongLastValueWithRetractAggFunction(),
-						numberInputValueSets(Long::valueOf),
-						numberExpectedResults(Long::valueOf)
-				),
-				/**
-				 * Test for FloatLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatLastValueWithRetractAggFunction(),
-						numberInputValueSets(Float::valueOf),
-						numberExpectedResults(Float::valueOf)
-				),
-				/**
-				 * Test for DoubleLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleLastValueWithRetractAggFunction(),
-						numberInputValueSets(Double::valueOf),
-						numberExpectedResults(Double::valueOf)
-				),
-				/**
-				 * Test for BooleanLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanLastValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalLastValueWithRetractAggFunction(
-								DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringLastValueWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringLastValueWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("zzz"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("e")
-						)
-				)
-
-		);
+	/**
+	 * Test for BooleanLastValueWithRetractAggFunction.
+	 */
+	public static class BooleanLastValueWithRetractAggFunctionWithoutOrderTest extends
+			LastValueWithRetractAggFunctionWithoutOrderTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, GenericRow> getAggregator() {
+			return new BooleanLastValueWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10"),
-						null,
-						strToValueFun.apply("3")
-				)
-		);
+	/**
+	 * Test for DecimalLastValueWithRetractAggFunction.
+	 */
+	public static class DecimalLastValueWithRetractAggFunctionWithoutOrderTest extends
+			LastValueWithRetractAggFunctionWithoutOrderTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("999.999", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, GenericRow> getAggregator() {
+			return new DecimalLastValueWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				strToValueFun.apply("3"),
-				null,
-				strToValueFun.apply("3")
-		);
+	/**
+	 * Test for StringLastValueWithRetractAggFunction.
+	 */
+	public static class StringLastValueWithRetractAggFunctionWithoutOrderTest extends
+			LastValueWithRetractAggFunctionWithoutOrderTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("zzz"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("e")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, GenericRow> getAggregator() {
+			return new StringLastValueWithRetractAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
index aa02763..0ee6899 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MaxWithRetractAggFunctionTest.java
@@ -37,383 +37,585 @@ import org.apache.flink.table.planner.functions.aggfunctions.MaxWithRetractAggFu
 import org.apache.flink.table.planner.functions.aggfunctions.MaxWithRetractAggFunction.TimestampMaxWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.sql.Date;
 import java.sql.Time;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in Max with retraction aggregate function.
  */
-@RunWith(Parameterized.class)
-public class MaxWithRetractAggFunctionTest<T> extends AggFunctionTestBase<T, MaxWithRetractAccumulator<T>> {
+@RunWith(Enclosed.class)
+public class MaxWithRetractAggFunctionTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, MaxWithRetractAccumulator<T>> aggFunctionTestSpec;
+	/**
+	 * The base test class for MaxWithRetractAggFunction.
+	 */
+	public abstract static class MaxWithRetractAggFunctionTestBase<T>
+			extends AggFunctionTestBase<T, MaxWithRetractAccumulator<T>> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Class<?> getAccClass() {
+			return MaxWithRetractAccumulator.class;
+		}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test MaxWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberMaxWithRetractAggFunctionTest<T> extends MaxWithRetractAggFunctionTestBase {
+		protected abstract T getMinValue();
+
+		protected abstract T getMaxValue();
+
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getMaxValue(),
+							getValue("-99"),
+							getValue("3"),
+							getValue("56"),
+							getValue("0"),
+							getMinValue(),
+							getValue("-20"),
+							getValue("17"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getMaxValue(),
+					null,
+					getValue("10")
+			);
+		}
+	}
+
+	/**
+	 * Test for ByteMaxWithRetractAggFunction.
+	 */
+	public static class ByteMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Byte> {
+
+		@Override
+		protected Byte getMinValue() {
+			return Byte.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Byte getMaxValue() {
+			return Byte.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, MaxWithRetractAccumulator<Byte>> getAggregator() {
+			return new ByteMaxWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for ShortMaxWithRetractAggFunction.
+	 */
+	public static class ShortMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Short> {
+
+		@Override
+		protected Short getMinValue() {
+			return Short.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Short getMaxValue() {
+			return Short.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, MaxWithRetractAccumulator<Short>> getAggregator() {
+			return new ShortMaxWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for IntMaxWithRetractAggFunction.
+	 */
+	public static class IntMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Integer> {
+
+		@Override
+		protected Integer getMinValue() {
+			return Integer.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Integer getMaxValue() {
+			return Integer.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, MaxWithRetractAccumulator<Integer>> getAggregator() {
+			return new IntMaxWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for LongMaxWithRetractAggFunction.
+	 */
+	public static class LongMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Long> {
+
+		@Override
+		protected Long getMinValue() {
+			return Long.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Long getMaxValue() {
+			return Long.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, MaxWithRetractAccumulator<Long>> getAggregator() {
+			return new LongMaxWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for FloatMaxWithRetractAggFunction.
+	 */
+	public static class FloatMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Float> {
+
+		@Override
+		protected Float getMinValue() {
+			return -Float.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Float getMaxValue() {
+			return Float.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, MaxWithRetractAccumulator<Float>> getAggregator() {
+			return new FloatMaxWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, MaxWithRetractAccumulator<T>> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for DoubleMaxWithRetractAggFunction.
+	 */
+	public static class DoubleMaxWithRetractAggFunctionTest extends NumberMaxWithRetractAggFunctionTest<Double> {
+
+		@Override
+		protected Double getMinValue() {
+			return -Double.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Double getMaxValue() {
+			return Double.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, MaxWithRetractAccumulator<Double>> getAggregator() {
+			return new DoubleMaxWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return MaxWithRetractAccumulator.class;
+	/**
+	 * Test for BooleanMaxWithRetractAggFunction.
+	 */
+	public static class BooleanMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					true,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, MaxWithRetractAccumulator<Boolean>> getAggregator() {
+			return new BooleanMaxWithRetractAggFunction();
+		}
+
+		@Override
+		protected Class<?> getAccClass() {
+			return MaxWithRetractAccumulator.class;
+		}
+
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+	/**
+	 * Test for DecimalMaxWithRetractAggFunction.
+	 */
+	public static class DecimalMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000.000001", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("1000.000001", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, MaxWithRetractAccumulator<Decimal>> getAggregator() {
+			return new DecimalMaxWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteMaxWithRetractAggFunction(),
-						numberInputValueSets((byte) (Byte.MIN_VALUE + 1), (byte) (Byte.MAX_VALUE - 1), Byte::valueOf),
-						numberExpectedResults((byte) (Byte.MAX_VALUE - 1), Byte::valueOf)
-				),
-				/**
-				 * Test for ShortMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortMaxWithRetractAggFunction(),
-						numberInputValueSets(
-								(short) (Short.MIN_VALUE + 1), (short) (Short.MAX_VALUE - 1), Short::valueOf),
-						numberExpectedResults((short) (Short.MAX_VALUE - 1), Short::valueOf)
-				),
-				/**
-				 * Test for IntMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntMaxWithRetractAggFunction(),
-						numberInputValueSets(Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, Integer::valueOf),
-						numberExpectedResults(Integer.MAX_VALUE - 1, Integer::valueOf)
-				),
-				/**
-				 * Test for LongMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongMaxWithRetractAggFunction(),
-						numberInputValueSets(Long.MIN_VALUE + 1L, Long.MAX_VALUE - 1L, Long::valueOf),
-						numberExpectedResults(Long.MAX_VALUE - 1L, Long::valueOf)
-				),
-				/**
-				 * Test for FloatMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatMaxWithRetractAggFunction(),
-						numberInputValueSets((-Float.MAX_VALUE / 2), (Float.MAX_VALUE / 2), Float::valueOf),
-						numberExpectedResults((Float.MAX_VALUE / 2), Float::valueOf)
-				),
-				/**
-				 * Test for DoubleMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleMaxWithRetractAggFunction(),
-						numberInputValueSets((-Double.MAX_VALUE / 2), (Double.MAX_VALUE / 2), Double::valueOf),
-						numberExpectedResults((Double.MAX_VALUE / 2), Double::valueOf)
-				),
-				/**
-				 * Test for BooleanMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanMaxWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								true,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalMaxWithRetractAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("1000.000001", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringMaxWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("zzz"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("x")
-						)
-				),
-				/**
-				 * Test for TimestampMaxWithRetractAggFunction with millisecond's precision.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimestampMaxWithRetractAggFunction(3),
-						Arrays.asList(
-								Arrays.asList(
-										SqlTimestamp.fromEpochMillis(0),
-										SqlTimestamp.fromEpochMillis(1000),
-										SqlTimestamp.fromEpochMillis(100),
-										null,
-										SqlTimestamp.fromEpochMillis(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										SqlTimestamp.fromEpochMillis(1)
-								)
-						),
-						Arrays.asList(
-								SqlTimestamp.fromEpochMillis(1000),
-								null,
-								SqlTimestamp.fromEpochMillis(1)
-						)
-				),
-				/**
-				 * Test for TimestampMaxWithRetractAggFunction with nanosecond's precision.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimestampMaxWithRetractAggFunction(9),
-						Arrays.asList(
-								Arrays.asList(
-										SqlTimestamp.fromEpochMillis(0, 0),
-										SqlTimestamp.fromEpochMillis(1000, 0),
-										SqlTimestamp.fromEpochMillis(1000, 1),
-										SqlTimestamp.fromEpochMillis(100, 0),
-										null,
-										SqlTimestamp.fromEpochMillis(10, 0)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										SqlTimestamp.fromEpochMillis(1, 0),
-										SqlTimestamp.fromEpochMillis(1, 1)
-								)
-						),
-						Arrays.asList(
-								SqlTimestamp.fromEpochMillis(1000, 1),
-								null,
-								SqlTimestamp.fromEpochMillis(1, 1)
-						)
-				),
-				/**
-				 * Test for DateMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DateMaxWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										new Date(0),
-										new Date(1000),
-										new Date(100),
-										null,
-										new Date(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										new Date(1)
-								)
-						),
-						Arrays.asList(
-								new Date(1000),
-								null,
-								new Date(1)
-						)
-				),
-				/**
-				 * Test for TimeMaxWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimeMaxWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										new Time(0),
-										new Time(1000),
-										new Time(100),
-										null,
-										new Time(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										new Time(1)
-								)
-						),
-						Arrays.asList(
-								new Time(1000),
-								null,
-								new Time(1)
-						)
-				)
-		);
+	/**
+	 * Test for StringMaxWithRetractAggFunction.
+	 */
+	public static class StringMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("zzz"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("x")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, MaxWithRetractAccumulator<BinaryString>> getAggregator() {
+			return new StringMaxWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(N minValue, N maxValue, Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						maxValue,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						strToValueFun.apply("56"),
-						strToValueFun.apply("0"),
-						minValue,
-						strToValueFun.apply("-20"),
-						strToValueFun.apply("17"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10")
-				)
-		);
+	/**
+	 * Test for TimestampMaxWithRetractAggFunction.
+	 */
+	public static class TimestampMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
+
+		@Override
+		protected List<List<SqlTimestamp>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							SqlTimestamp.fromEpochMillis(0),
+							SqlTimestamp.fromEpochMillis(1000),
+							SqlTimestamp.fromEpochMillis(100),
+							null,
+							SqlTimestamp.fromEpochMillis(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							SqlTimestamp.fromEpochMillis(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<SqlTimestamp> getExpectedResults() {
+			return Arrays.asList(
+					SqlTimestamp.fromEpochMillis(1000),
+					null,
+					SqlTimestamp.fromEpochMillis(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<SqlTimestamp, MaxWithRetractAccumulator<SqlTimestamp>> getAggregator() {
+			return new TimestampMaxWithRetractAggFunction(3);
+		}
+	}
+
+	/**
+	 * Test for TimestampMaxWithRetractAggFunction, precision is 9.
+	 */
+	public static class Timestamp9MaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<SqlTimestamp> {
+
+		@Override
+		protected List<List<SqlTimestamp>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							SqlTimestamp.fromEpochMillis(0, 0),
+							SqlTimestamp.fromEpochMillis(1000, 0),
+							SqlTimestamp.fromEpochMillis(1000, 1),
+							SqlTimestamp.fromEpochMillis(100, 0),
+							null,
+							SqlTimestamp.fromEpochMillis(10, 0)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							SqlTimestamp.fromEpochMillis(1, 0),
+							SqlTimestamp.fromEpochMillis(1, 1)
+					)
+			);
+		}
+
+		@Override
+		protected List<SqlTimestamp> getExpectedResults() {
+			return Arrays.asList(
+					SqlTimestamp.fromEpochMillis(1000, 1),
+					null,
+					SqlTimestamp.fromEpochMillis(1, 1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<SqlTimestamp, MaxWithRetractAccumulator<SqlTimestamp>> getAggregator() {
+			return new TimestampMaxWithRetractAggFunction(9);
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(N maxValue, Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				maxValue,
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for DateMaxWithRetractAggFunction.
+	 */
+	public static class DateMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Date> {
+
+		@Override
+		protected List<List<Date>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							new Date(0),
+							new Date(1000),
+							new Date(100),
+							null,
+							new Date(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							new Date(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<Date> getExpectedResults() {
+			return Arrays.asList(
+					new Date(1000),
+					null,
+					new Date(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Date, MaxWithRetractAccumulator<Date>> getAggregator() {
+			return new DateMaxWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for TimeMaxWithRetractAggFunction.
+	 */
+	public static class TimeMaxWithRetractAggFunctionTest extends MaxWithRetractAggFunctionTestBase<Time> {
+
+		@Override
+		protected List<List<Time>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							new Time(0),
+							new Time(1000),
+							new Time(100),
+							null,
+							new Time(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							new Time(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<Time> getExpectedResults() {
+			return Arrays.asList(
+					new Time(1000),
+					null,
+					new Time(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Time, MaxWithRetractAccumulator<Time>> getAggregator() {
+			return new TimeMaxWithRetractAggFunction();
+		}
 	}
 }
diff --git a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
index 2091055..3d48b9b 100644
--- a/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
+++ b/flink-table/flink-table-planner-blink/src/test/java/org/apache/flink/table/planner/functions/aggfunctions/MinWithRetractAggFunctionTest.java
@@ -37,384 +37,578 @@ import org.apache.flink.table.planner.functions.aggfunctions.MinWithRetractAggFu
 import org.apache.flink.table.planner.functions.aggfunctions.MinWithRetractAggFunction.TimestampMinWithRetractAggFunction;
 import org.apache.flink.table.runtime.typeutils.DecimalTypeInfo;
 
+import org.junit.experimental.runners.Enclosed;
 import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
 import java.lang.reflect.Method;
 import java.sql.Date;
 import java.sql.Time;
 import java.util.Arrays;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * Test case for built-in Min with retraction aggregate function.
  */
-@RunWith(Parameterized.class)
-public class MinWithRetractAggFunctionTest<T> extends AggFunctionTestBase<T, MinWithRetractAccumulator<T>> {
+@RunWith(Enclosed.class)
+public class MinWithRetractAggFunctionTest {
 
-	@Parameterized.Parameter
-	public AggFunctionTestSpec<T, MinWithRetractAccumulator<T>> aggFunctionTestSpec;
+	/**
+	 * The base test class for MinWithRetractAggFunction.
+	 */
+	public abstract static class MinWithRetractAggFunctionTestBase<T>
+			extends AggFunctionTestBase<T, MinWithRetractAccumulator<T>> {
 
-	private static final int DECIMAL_PRECISION = 20;
-	private static final int DECIMAL_SCALE = 6;
+		@Override
+		protected Class<?> getAccClass() {
+			return MinWithRetractAccumulator.class;
+		}
 
-	@Override
-	protected List<List<T>> getInputValueSets() {
-		return aggFunctionTestSpec.inputValueSets;
+		@Override
+		protected Method getRetractFunc() throws NoSuchMethodException {
+			return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+		}
 	}
 
-	@Override
-	protected List<T> getExpectedResults() {
-		return aggFunctionTestSpec.expectedResults;
+	/**
+	 * Test MinWithRetractAggFunction for number type.
+	 */
+	public abstract static class NumberMinWithRetractAggFunctionTestBase<T> extends MinWithRetractAggFunctionTestBase<T> {
+		protected abstract T getMinValue();
+
+		protected abstract T getMaxValue();
+
+		protected abstract T getValue(String v);
+
+		@Override
+		protected List<List<T>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							getValue("1"),
+							null,
+							getMaxValue(),
+							getValue("-99"),
+							getValue("3"),
+							getValue("56"),
+							getValue("0"),
+							getMinValue(),
+							getValue("-20"),
+							getValue("17"),
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							getValue("10")
+					)
+			);
+		}
+
+		@Override
+		protected List<T> getExpectedResults() {
+			return Arrays.asList(
+					getMinValue(),
+					null,
+					getValue("10")
+			);
+		}
+	}
+
+	/**
+	 * Test for ByteMinWithRetractAggFunction.
+	 */
+	public static class ByteMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Byte> {
+
+		@Override
+		protected Byte getMinValue() {
+			return Byte.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Byte getMaxValue() {
+			return Byte.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Byte getValue(String v) {
+			return Byte.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Byte, MinWithRetractAccumulator<Byte>> getAggregator() {
+			return new ByteMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for ShortMinWithRetractAggFunction.
+	 */
+	public static class ShortMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Short> {
+
+		@Override
+		protected Short getMinValue() {
+			return Short.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Short getMaxValue() {
+			return Short.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Short getValue(String v) {
+			return Short.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Short, MinWithRetractAccumulator<Short>> getAggregator() {
+			return new ShortMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for IntMinWithRetractAggFunction.
+	 */
+	public static class IntMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Integer> {
+
+		@Override
+		protected Integer getMinValue() {
+			return Integer.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Integer getMaxValue() {
+			return Integer.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Integer getValue(String v) {
+			return Integer.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Integer, MinWithRetractAccumulator<Integer>> getAggregator() {
+			return new IntMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for LongMinWithRetractAggFunction.
+	 */
+	public static class LongMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Long> {
+
+		@Override
+		protected Long getMinValue() {
+			return Long.MIN_VALUE + 1;
+		}
+
+		@Override
+		protected Long getMaxValue() {
+			return Long.MAX_VALUE - 1;
+		}
+
+		@Override
+		protected Long getValue(String v) {
+			return Long.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Long, MinWithRetractAccumulator<Long>> getAggregator() {
+			return new LongMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for FloatMinWithRetractAggFunction.
+	 */
+	public static class FloatMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Float> {
+
+		@Override
+		protected Float getMinValue() {
+			return -Float.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Float getMaxValue() {
+			return Float.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Float getValue(String v) {
+			return Float.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Float, MinWithRetractAccumulator<Float>> getAggregator() {
+			return new FloatMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DoubleMinWithRetractAggFunction.
+	 */
+	public static class DoubleMinWithRetractAggFunctionTest extends NumberMinWithRetractAggFunctionTestBase<Double> {
+
+		@Override
+		protected Double getMinValue() {
+			return -Double.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Double getMaxValue() {
+			return Double.MAX_VALUE / 2;
+		}
+
+		@Override
+		protected Double getValue(String v) {
+			return Double.valueOf(v);
+		}
+
+		@Override
+		protected AggregateFunction<Double, MinWithRetractAccumulator<Double>> getAggregator() {
+			return new DoubleMinWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected AggregateFunction<T, MinWithRetractAccumulator<T>> getAggregator() {
-		return aggFunctionTestSpec.aggregator;
+	/**
+	 * Test for BooleanMinWithRetractAggFunction.
+	 */
+	public static class BooleanMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Boolean> {
+
+		@Override
+		protected List<List<Boolean>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							false,
+							false,
+							false
+					),
+					Arrays.asList(
+							true,
+							true,
+							true
+					),
+					Arrays.asList(
+							true,
+							false,
+							null,
+							true,
+							false,
+							true,
+							null
+					),
+					Arrays.asList(
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							true
+					));
+		}
+
+		@Override
+		protected List<Boolean> getExpectedResults() {
+			return Arrays.asList(
+					false,
+					true,
+					false,
+					null,
+					true
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Boolean, MinWithRetractAccumulator<Boolean>> getAggregator() {
+			return new BooleanMinWithRetractAggFunction();
+		}
+	}
+
+	/**
+	 * Test for DecimalMinWithRetractAggFunction.
+	 */
+	public static class DecimalMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Decimal> {
+
+		private int precision = 20;
+		private int scale = 6;
+
+		@Override
+		protected List<List<Decimal>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							Decimal.castFrom("1", precision, scale),
+							Decimal.castFrom("1000", precision, scale),
+							Decimal.castFrom("-1", precision, scale),
+							Decimal.castFrom("-999.998999", precision, scale),
+							null,
+							Decimal.castFrom("0", precision, scale),
+							Decimal.castFrom("-999.999", precision, scale),
+							null,
+							Decimal.castFrom("999.999", precision, scale)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							Decimal.castFrom("0", precision, scale)
+					)
+			);
+		}
+
+		@Override
+		protected List<Decimal> getExpectedResults() {
+			return Arrays.asList(
+					Decimal.castFrom("-999.999", precision, scale),
+					null,
+					Decimal.castFrom("0", precision, scale)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Decimal, MinWithRetractAccumulator<Decimal>> getAggregator() {
+			return new DecimalMinWithRetractAggFunction(DecimalTypeInfo.of(precision, scale));
+		}
 	}
 
-	@Override
-	protected Class<?> getAccClass() {
-		return MinWithRetractAccumulator.class;
+	/**
+	 * Test for StringMinWithRetractAggFunction.
+	 */
+	public static class StringMinWithRetractAggFunctionTest
+			extends MinWithRetractAggFunctionTestBase<BinaryString> {
+
+		@Override
+		protected List<List<BinaryString>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							BinaryString.fromString("abc"),
+							BinaryString.fromString("def"),
+							BinaryString.fromString("ghi"),
+							null,
+							BinaryString.fromString("jkl"),
+							null,
+							BinaryString.fromString("zzz")
+					),
+					Arrays.asList(
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							BinaryString.fromString("a")
+					),
+					Arrays.asList(
+							BinaryString.fromString("x"),
+							null,
+							BinaryString.fromString("e")
+					)
+			);
+		}
+
+		@Override
+		protected List<BinaryString> getExpectedResults() {
+			return Arrays.asList(
+					BinaryString.fromString("abc"),
+					null,
+					BinaryString.fromString("a"),
+					BinaryString.fromString("e")
+			);
+		}
+
+		@Override
+		protected AggregateFunction<BinaryString, MinWithRetractAccumulator<BinaryString>> getAggregator() {
+			return new StringMinWithRetractAggFunction();
+		}
 	}
 
-	@Override
-	protected Method getRetractFunc() throws NoSuchMethodException {
-		return getAggregator().getClass().getMethod("retract", getAccClass(), Object.class);
+	/**
+	 * Test for TimestampMinWithRetractAggFunction.
+	 */
+	public static class TimestampMinWithRetractAggFunctionTest
+			extends MinWithRetractAggFunctionTestBase<SqlTimestamp> {
+
+		@Override
+		protected List<List<SqlTimestamp>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							SqlTimestamp.fromEpochMillis(0),
+							SqlTimestamp.fromEpochMillis(1000),
+							SqlTimestamp.fromEpochMillis(100),
+							null,
+							SqlTimestamp.fromEpochMillis(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							SqlTimestamp.fromEpochMillis(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<SqlTimestamp> getExpectedResults() {
+			return Arrays.asList(
+					SqlTimestamp.fromEpochMillis(0),
+					null,
+					SqlTimestamp.fromEpochMillis(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<SqlTimestamp, MinWithRetractAccumulator<SqlTimestamp>> getAggregator() {
+			return new TimestampMinWithRetractAggFunction(3);
+		}
 	}
 
-	@Parameterized.Parameters(name = "{index}: {0}")
-	public static List<AggFunctionTestSpec> testData() {
-		return Arrays.asList(
-				/**
-				 * Test for ByteMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ByteMinWithRetractAggFunction(),
-						numberInputValueSets((byte) (Byte.MIN_VALUE + 1), (byte) (Byte.MAX_VALUE - 1), Byte::valueOf),
-						numberExpectedResults((byte) (Byte.MIN_VALUE + 1), Byte::valueOf)
-				),
-				/**
-				 * Test for ShortMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new ShortMinWithRetractAggFunction(),
-						numberInputValueSets(
-								(short) (Short.MIN_VALUE + 1), (short) (Short.MAX_VALUE - 1), Short::valueOf),
-						numberExpectedResults((short) (Short.MIN_VALUE + 1), Short::valueOf)
-				),
-				/**
-				 * Test for IntMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new IntMinWithRetractAggFunction(),
-						numberInputValueSets(Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, Integer::valueOf),
-						numberExpectedResults(Integer.MIN_VALUE + 1, Integer::valueOf)
-				),
-				/**
-				 * Test for LongMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new LongMinWithRetractAggFunction(),
-						numberInputValueSets(Long.MIN_VALUE + 1L, Long.MAX_VALUE - 1L, Long::valueOf),
-						numberExpectedResults(Long.MIN_VALUE + 1L, Long::valueOf)
-				),
-				/**
-				 * Test for FloatMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new FloatMinWithRetractAggFunction(),
-						numberInputValueSets((-Float.MAX_VALUE / 2), (Float.MAX_VALUE / 2), Float::valueOf),
-						numberExpectedResults((-Float.MAX_VALUE / 2), Float::valueOf)
-				),
-				/**
-				 * Test for DoubleMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DoubleMinWithRetractAggFunction(),
-						numberInputValueSets((-Double.MAX_VALUE / 2), (Double.MAX_VALUE / 2), Double::valueOf),
-						numberExpectedResults((-Double.MAX_VALUE / 2), Double::valueOf)
-				),
-				/**
-				 * Test for BooleanMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new BooleanMinWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										false,
-										false,
-										false
-								),
-								Arrays.asList(
-										true,
-										true,
-										true
-								),
-								Arrays.asList(
-										true,
-										false,
-										null,
-										true,
-										false,
-										true,
-										null
-								),
-								Arrays.asList(
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										true
-								)
-						),
-						Arrays.asList(
-								false,
-								true,
-								false,
-								null,
-								true
-						)
-				),
-				/**
-				 * Test for DecimalMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DecimalMinWithRetractAggFunction(DecimalTypeInfo.of(DECIMAL_PRECISION, DECIMAL_SCALE)),
-						Arrays.asList(
-								Arrays.asList(
-										Decimal.castFrom("1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("1000", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-1", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.998999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE),
-										Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-										null,
-										Decimal.castFrom("999.999", DECIMAL_PRECISION, DECIMAL_SCALE)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-								)
-						),
-						Arrays.asList(
-								Decimal.castFrom("-999.999", DECIMAL_PRECISION, DECIMAL_SCALE),
-								null,
-								Decimal.castFrom("0", DECIMAL_PRECISION, DECIMAL_SCALE)
-						)
-				),
-				/**
-				 * Test for StringMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new StringMinWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										BinaryString.fromString("abc"),
-										BinaryString.fromString("def"),
-										BinaryString.fromString("ghi"),
-										null,
-										BinaryString.fromString("jkl"),
-										null,
-										BinaryString.fromString("zzz")
-								),
-								Arrays.asList(
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										BinaryString.fromString("a")
-								),
-								Arrays.asList(
-										BinaryString.fromString("x"),
-										null,
-										BinaryString.fromString("e")
-								)
-						),
-						Arrays.asList(
-								BinaryString.fromString("abc"),
-								null,
-								BinaryString.fromString("a"),
-								BinaryString.fromString("e")
-						)
-				),
-				/**
-				 * Test for TimestampMinWithRetractAggFunction with millisecond's precision.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimestampMinWithRetractAggFunction(3),
-						Arrays.asList(
-								Arrays.asList(
-										SqlTimestamp.fromEpochMillis(0),
-										SqlTimestamp.fromEpochMillis(1000),
-										SqlTimestamp.fromEpochMillis(100),
-										null,
-										SqlTimestamp.fromEpochMillis(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										SqlTimestamp.fromEpochMillis(1)
-								)
-						),
-						Arrays.asList(
-								SqlTimestamp.fromEpochMillis(0),
-								null,
-								SqlTimestamp.fromEpochMillis(1)
-						)
-				),
-				/**
-				 * Test for TimestampMinWithRetractAggFunction with nanosecond's precision.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimestampMinWithRetractAggFunction(9),
-						Arrays.asList(
-								Arrays.asList(
-										SqlTimestamp.fromEpochMillis(0, 1),
-										SqlTimestamp.fromEpochMillis(0, 2),
-										SqlTimestamp.fromEpochMillis(1000, 0),
-										SqlTimestamp.fromEpochMillis(100, 0),
-										null,
-										SqlTimestamp.fromEpochMillis(10, 0)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										SqlTimestamp.fromEpochMillis(1, 1),
-										SqlTimestamp.fromEpochMillis(1, 2)
-								)
-						),
-						Arrays.asList(
-								SqlTimestamp.fromEpochMillis(0, 1),
-								null,
-								SqlTimestamp.fromEpochMillis(1, 1)
-						)
-				),
-
-				/**
-				 * Test for DateMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new DateMinWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										new Date(0),
-										new Date(1000),
-										new Date(100),
-										null,
-										new Date(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										new Date(1)
-								)
-						),
-						Arrays.asList(
-								new Date(0),
-								null,
-								new Date(1)
-						)
-				),
-				/**
-				 * Test for TimeMinWithRetractAggFunction.
-				 */
-				new AggFunctionTestSpec<>(
-						new TimeMinWithRetractAggFunction(),
-						Arrays.asList(
-								Arrays.asList(
-										new Time(0),
-										new Time(1000),
-										new Time(100),
-										null,
-										new Time(10)
-								),
-								Arrays.asList(
-										null,
-										null,
-										null,
-										null,
-										null
-								),
-								Arrays.asList(
-										null,
-										new Time(1)
-								)
-						),
-						Arrays.asList(
-								new Time(0),
-								null,
-								new Time(1)
-						)
-				)
-		);
+	/**
+	 * Test for TimestampMinWithRetractAggFunction, precision is 9.
+	 */
+	public static class Timestamp9MinWithRetractAggFunctionTest
+			extends MinWithRetractAggFunctionTestBase<SqlTimestamp> {
+
+		@Override
+		protected List<List<SqlTimestamp>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							SqlTimestamp.fromEpochMillis(0, 1),
+							SqlTimestamp.fromEpochMillis(0, 2),
+							SqlTimestamp.fromEpochMillis(1000, 0),
+							SqlTimestamp.fromEpochMillis(100, 0),
+							null,
+							SqlTimestamp.fromEpochMillis(10, 0)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							SqlTimestamp.fromEpochMillis(1, 1),
+							SqlTimestamp.fromEpochMillis(1, 2)
+					)
+			);
+		}
+
+		@Override
+		protected List<SqlTimestamp> getExpectedResults() {
+			return Arrays.asList(
+					SqlTimestamp.fromEpochMillis(0, 1),
+					null,
+					SqlTimestamp.fromEpochMillis(1, 1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<SqlTimestamp, MinWithRetractAccumulator<SqlTimestamp>> getAggregator() {
+			return new TimestampMinWithRetractAggFunction(9);
+		}
 	}
 
-	private static <N> List<List<N>> numberInputValueSets(N minValue, N maxValue, Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				Arrays.asList(
-						strToValueFun.apply("1"),
-						null,
-						maxValue,
-						strToValueFun.apply("-99"),
-						strToValueFun.apply("3"),
-						strToValueFun.apply("56"),
-						strToValueFun.apply("0"),
-						minValue,
-						strToValueFun.apply("-20"),
-						strToValueFun.apply("17"),
-						null
-				),
-				Arrays.asList(
-						null,
-						null,
-						null,
-						null,
-						null,
-						null
-				),
-				Arrays.asList(
-						null,
-						strToValueFun.apply("10")
-				)
-		);
+	/**
+	 * Test for DateMinWithRetractAggFunction.
+	 */
+	public static class DateMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Date> {
+
+		@Override
+		protected List<List<Date>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							new Date(0),
+							new Date(1000),
+							new Date(100),
+							null,
+							new Date(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							new Date(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<Date> getExpectedResults() {
+			return Arrays.asList(
+					new Date(0),
+					null,
+					new Date(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Date, MinWithRetractAccumulator<Date>> getAggregator() {
+			return new DateMinWithRetractAggFunction();
+		}
 	}
 
-	private static <N> List<N> numberExpectedResults(N minValue, Function<String, N> strToValueFun) {
-		return Arrays.asList(
-				minValue,
-				null,
-				strToValueFun.apply("10")
-		);
+	/**
+	 * Test for TimeMinWithRetractAggFunction.
+	 */
+	public static class TimeMinWithRetractAggFunctionTest extends MinWithRetractAggFunctionTestBase<Time> {
+
+		@Override
+		protected List<List<Time>> getInputValueSets() {
+			return Arrays.asList(
+					Arrays.asList(
+							new Time(0),
+							new Time(1000),
+							new Time(100),
+							null,
+							new Time(10)
+					),
+					Arrays.asList(
+							null,
+							null,
+							null,
+							null,
+							null
+					),
+					Arrays.asList(
+							null,
+							new Time(1)
+					)
+			);
+		}
+
+		@Override
+		protected List<Time> getExpectedResults() {
+			return Arrays.asList(
+					new Time(0),
+					null,
+					new Time(1)
+			);
+		}
+
+		@Override
+		protected AggregateFunction<Time, MinWithRetractAccumulator<Time>> getAggregator() {
+			return new TimeMinWithRetractAggFunction();
+		}
 	}
 }