You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2026/05/15 16:00:56 UTC

(hbase) branch branch-3 updated: HBASE-30082 Upgrade hbase-server to use junit5 Part12 (#8190)

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

Apache9 pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new 50cbbb15346 HBASE-30082 Upgrade hbase-server to use junit5 Part12 (#8190)
50cbbb15346 is described below

commit 50cbbb15346c58c129a0c40e7e559a3bc0ec5f07
Author: Duo Zhang <zh...@apache.org>
AuthorDate: Fri May 15 23:53:42 2026 +0800

    HBASE-30082 Upgrade hbase-server to use junit5 Part12 (#8190)
    
    Signed-off-by: Xiao Liu <li...@apache.org>
    (cherry picked from commit 61e78cdec0a2848a26285f9061a42e2cd044b50c)
---
 .../AbstractTestAsyncTableRegionReplicasRead.java  |  46 +--
 .../client/AbstractTestCIOperationTimeout.java     |  10 +-
 .../hbase/client/AbstractTestCIRpcTimeout.java     |  10 +-
 .../hadoop/hbase/client/AbstractTestCITimeout.java |  16 +-
 .../hbase/client/AbstractTestRegionLocator.java    |  10 +-
 .../client/AbstractTestResultScannerCursor.java    |   8 +-
 .../hbase/client/AbstractTestScanCursor.java       |   8 +-
 ...eWithDifferentConnectionRegistriesTestBase.java |   4 +-
 .../hbase/client/ClientPushbackTestBase.java       |  40 +-
 .../hadoop/hbase/client/FromClientSideTest4.java   |   4 +-
 .../hbase/client/FromClientSideTestBase.java       |   6 +-
 .../hbase/client/MetaWithReplicasTestBase.java     |  22 +-
 .../hbase/client/RegionReplicaTestHelper.java      |   6 +-
 ...java => SnapshotCloneIndependenceTestBase.java} | 108 ++---
 ...Client.java => SnapshotFromClientTestBase.java} |  95 ++---
 ...ava => SnapshotTemporaryDirectoryTestBase.java} |  82 ++--
 .../hbase/client/SnapshotWithAclTestBase.java      |  50 +--
 .../org/apache/hadoop/hbase/client/TestAdmin.java  | 105 +++--
 .../org/apache/hadoop/hbase/client/TestAdmin1.java |  67 ++-
 .../org/apache/hadoop/hbase/client/TestAdmin2.java | 177 ++++----
 .../org/apache/hadoop/hbase/client/TestAdmin3.java |  75 ++--
 .../org/apache/hadoop/hbase/client/TestAdmin4.java |  26 +-
 .../apache/hadoop/hbase/client/TestAdminBase.java  |  26 +-
 .../client/TestAllowPartialScanResultCache.java    |  25 +-
 .../hbase/client/TestAlwaysSetScannerId.java       |  25 +-
 .../hbase/client/TestAppendFromClientSide.java     |  37 +-
 .../hadoop/hbase/client/TestAsyncAdminBuilder.java |  58 ++-
 .../hbase/client/TestAsyncBufferMutator.java       |  33 +-
 .../TestAsyncClientPauseForRpcThrottling.java      |  32 +-
 .../TestAsyncClientPauseForServerOverloaded.java   |  35 +-
 .../hbase/client/TestAsyncClientPushback.java      |  19 +-
 .../client/TestAsyncNonMetaRegionLocator.java      |  90 ++--
 ...stAsyncNonMetaRegionLocatorConcurrenyLimit.java |  29 +-
 .../hbase/client/TestAsyncRegionLocator.java       |  31 +-
 .../hbase/client/TestAsyncResultScannerCursor.java |  21 +-
 .../TestAsyncSingleRequestRpcRetryingCaller.java   |  27 +-
 .../apache/hadoop/hbase/client/TestAsyncTable.java | 146 ++++---
 .../hbase/client/TestAsyncTableAdminApi.java       |  10 +-
 .../hbase/client/TestAsyncTableAdminApi2.java      |  43 +-
 .../hadoop/hbase/client/TestAsyncTableBatch.java   |  84 ++--
 .../TestAsyncTableBatchRetryImmediately.java       |  25 +-
 .../client/TestAsyncTableGetMultiThreaded.java     |  26 +-
 ...ncTableGetMultiThreadedWithBasicCompaction.java |  19 +-
 ...ncTableGetMultiThreadedWithEagerCompaction.java |  19 +-
 .../hbase/client/TestAsyncTableLocatePrefetch.java |  27 +-
 .../TestAsyncTableLocateRegionForDeletedTable.java |  25 +-
 .../hbase/client/TestAsyncTableNoncedRetry.java    |  41 +-
 .../hbase/client/TestAsyncTableQueryMetrics.java   |  58 ++-
 .../hbase/client/TestAsyncTableRSCrashPublish.java |  23 +-
 .../hbase/client/TestAsyncTableRegionLocator.java  |  19 +-
 .../client/TestAsyncTableRegionReplicasGet.java    |  25 +-
 .../client/TestAsyncTableRegionReplicasScan.java   |  29 +-
 .../hbase/client/TestAsyncTableScanException.java  |  49 +--
 ...AsyncTableScanMetricsWithScannerSuspending.java |  31 +-
 .../hbase/client/TestAsyncTableScanRenewLease.java |  23 +-
 .../TestAsyncTableScannerCloseWhileSuspending.java |  23 +-
 .../client/TestAsyncTableUseMetaReplicas.java      |  34 +-
 .../TestAvoidCellReferencesIntoShippedBlocks.java  |  55 ++-
 .../hbase/client/TestBatchScanResultCache.java     |  25 +-
 .../hbase/client/TestBlockEvictionFromClient.java  | 152 ++++---
 .../hbase/client/TestBootstrapNodeUpdate.java      |  25 +-
 .../hadoop/hbase/client/TestBufferedMutator.java   |  35 +-
 .../hbase/client/TestCIDeleteOperationTimeout.java |  11 +-
 .../hbase/client/TestCIDeleteRpcTimeout.java       |  11 +-
 .../hbase/client/TestCIGetOperationTimeout.java    |  11 +-
 .../hadoop/hbase/client/TestCIGetRpcTimeout.java   |  11 +-
 .../hbase/client/TestCIIncrementRpcTimeout.java    |  11 +-
 .../hbase/client/TestCIPutOperationTimeout.java    |  11 +-
 .../hadoop/hbase/client/TestCIPutRpcTimeout.java   |  11 +-
 .../apache/hadoop/hbase/client/TestCISleep.java    |  21 +-
 ...estCatalogReplicaLoadBalanceSimpleSelector.java |  25 +-
 .../hadoop/hbase/client/TestCheckAndMutate.java    |  86 ++--
 .../client/TestCheckAndMutateWithByteBuff.java     |  44 +-
 .../hbase/client/TestCleanupMetaReplica.java       |  19 +-
 .../TestCleanupMetaReplicaThroughConfig.java       |  19 +-
 .../hbase/client/TestClientOperationInterrupt.java |  33 +-
 .../hbase/client/TestClientScannerTimeouts.java    | 104 +++--
 .../hbase/client/TestClientSideRegionScanner.java  | 164 ++++----
 .../hbase/client/TestClientTableMetrics.java       |  32 +-
 .../hadoop/hbase/client/TestClientTimeouts.java    |  25 +-
 .../client/TestCompleteResultScanResultCache.java  |  25 +-
 .../apache/hadoop/hbase/client/TestConnection.java |  88 ++--
 .../hbase/client/TestConnectionAttributes.java     |  23 +-
 .../hadoop/hbase/client/TestConnectionUtils.java   |  15 +-
 .../hbase/client/TestDropTimeoutRequest.java       |  37 +-
 .../hadoop/hbase/client/TestEnableTable.java       |  35 +-
 .../client/TestFailedMetaReplicaAssigment.java     |  27 +-
 .../hbase/client/TestFallbackToUseReplay.java      |  23 +-
 .../hadoop/hbase/client/TestFlushFromClient.java   |  48 +--
 ...tFlushFromClientWithDisabledFlushProcedure.java |  43 +-
 .../hbase/client/TestGetProcedureResult.java       |  23 +-
 .../TestGetScanColumnsWithNewVersionBehavior.java  |  23 +-
 .../hbase/client/TestGetScanPartialResult.java     |  25 +-
 .../org/apache/hadoop/hbase/client/TestHbck.java   |  86 ++--
 .../hbase/client/TestIllegalTableDescriptor.java   |  47 +--
 .../TestIncreaseMetaReplicaThroughConfig.java      |  19 +-
 ...TestIncrementFromClientSideWithCoprocessor.java |  16 +-
 .../hbase/client/TestIncrementsFromClientSide.java | 105 ++---
 .../hbase/client/TestIntraRowPagination.java       |  13 +-
 .../TestInvalidMutationDurabilityException.java    |  50 +--
 .../hbase/client/TestLimitedScanWithFilter.java    |  29 +-
 .../hbase/client/TestMalformedCellFromClient.java  |  42 +-
 .../hadoop/hbase/client/TestMasterRegistry.java    |  26 +-
 .../apache/hadoop/hbase/client/TestMetaCache.java  |  41 +-
 .../hbase/client/TestMetaRegionLocationCache.java  |  27 +-
 .../client/TestMetaReplicasAddressChange.java      |  21 +-
 .../client/TestMetaTableAccessorNoCluster.java     |  27 +-
 .../hbase/client/TestMetaWithReplicasBasic.java    |  23 +-
 .../TestMetaWithReplicasShutdownHandling.java      |  21 +-
 .../client/TestMobSnapshotCloneIndependence.java   |  24 +-
 .../hbase/client/TestMobSnapshotFromClient.java    |  24 +-
 .../client/TestMultiActionMetricsFromClient.java   |  23 +-
 .../hadoop/hbase/client/TestMultiParallel.java     |  61 ++-
 .../hbase/client/TestMultiRespectsLimits.java      |  39 +-
 .../hbase/client/TestMultipleTimestamps.java       | 450 ++++++++++----------
 .../hbase/client/TestMutationGetCellBuilder.java   |  43 +-
 .../hbase/client/TestMvccConsistentScanner.java    |  42 +-
 .../hbase/client/TestPreadReversedScanner.java     |  43 +-
 .../client/TestPutDeleteEtcCellIteration.java      |  38 +-
 .../hadoop/hbase/client/TestPutWithDelete.java     |  76 ++--
 .../hbase/client/TestRawAsyncScanCursor.java       |  31 +-
 .../TestRawAsyncTableLimitedScanWithFilter.java    |  27 +-
 .../hbase/client/TestRawAsyncTablePartialScan.java |  23 +-
 .../hbase/client/TestRegionLocationCaching.java    |  33 +-
 .../hadoop/hbase/client/TestRegionLocator.java     |  19 +-
 .../hbase/client/TestReplicaWithCluster.java       |  58 ++-
 .../hadoop/hbase/client/TestReplicasClient.java    | 121 +++---
 .../hadoop/hbase/client/TestRequestAttributes.java |  21 +-
 .../hbase/client/TestRequestTooBigException.java   |  23 +-
 .../org/apache/hadoop/hbase/client/TestResult.java |  46 +--
 .../hbase/client/TestResultFromCoprocessor.java    |  23 +-
 .../hbase/client/TestResultScannerCursor.java      |  21 +-
 .../hbase/client/TestResultSizeEstimation.java     |  41 +-
 .../hbase/client/TestRpcConnectionRegistry.java    |  33 +-
 .../hadoop/hbase/client/TestScanAttributes.java    |  28 +-
 .../hbase/client/TestScanWithoutFetchingData.java  |  25 +-
 .../hadoop/hbase/client/TestScannerTimeout.java    |  27 +-
 .../hbase/client/TestScannersFromClientSide2.java  |  78 ++--
 .../hbase/client/TestSeparateClientZKCluster.java  |  37 +-
 .../hbase/client/TestServerBusyException.java      |  35 +-
 .../hbase/client/TestServerLoadDurability.java     |  59 ++-
 .../client/TestShutdownOfMetaReplicaHolder.java    |  17 +-
 .../hadoop/hbase/client/TestSizeFailures.java      |  22 +-
 .../client/TestSnapshotCloneIndependence.java      | 366 +----------------
 .../client/TestSnapshotDFSTemporaryDirectory.java  |  22 +-
 .../hbase/client/TestSnapshotFromClient.java       | 455 +--------------------
 .../TestSnapshotFromClientWithRegionReplicas.java  |  29 +-
 .../hadoop/hbase/client/TestSnapshotMetadata.java  |  37 +-
 .../client/TestSnapshotTemporaryDirectory.java     | 447 +-------------------
 ...apshotTemporaryDirectoryWithRegionReplicas.java |  28 +-
 .../hadoop/hbase/client/TestSnapshotWithAcl.java   |  11 +-
 .../client/TestSnapshotWithAclAsyncAdmin.java      |  11 +-
 .../client/TestSnapshotWithTTLFromClient.java      |  37 +-
 .../hbase/client/TestSplitOrMergeAtTableLevel.java |  53 ++-
 .../hbase/client/TestSplitOrMergeStatus.java       |  56 ++-
 .../hadoop/hbase/client/TestTableFavoredNodes.java | 120 +++---
 .../hbase/client/TestTableOperationException.java  |  74 ++--
 .../hbase/client/TestTableSnapshotScanner.java     |  90 ++--
 .../client/TestTableSnapshotScannerWithSFT.java    |  11 +-
 .../hadoop/hbase/client/TestTimestampsFilter.java  | 148 ++++---
 .../hbase/client/TestUpdateConfiguration.java      |  38 +-
 .../hbase/client/TestZKConnectionRegistry.java     |  47 +--
 .../hbase/client/locking/TestEntityLocks.java      |  23 +-
 .../client/replication/TestBadReplicationPeer.java |  25 +-
 .../TestReplicationAdminForSyncReplication.java    |  25 +-
 165 files changed, 3035 insertions(+), 5040 deletions(-)

diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.java
index 229045af93c..0333a8359ea 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestAsyncTableRegionReplicasRead.java
@@ -17,10 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
@@ -28,6 +27,7 @@ import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
@@ -38,12 +38,9 @@ import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
-import org.junit.AfterClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TestName;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
@@ -65,25 +62,24 @@ public abstract class AbstractTestAsyncTableRegionReplicasRead {
 
   protected static AsyncConnection ASYNC_CONN;
 
-  @Rule
-  public TestName testName = new TestName();
+  protected Supplier<AsyncTable<?>> getTable;
 
-  @Parameter
-  public Supplier<AsyncTable<?>> getTable;
+  public static Stream<Arguments> parameters() {
+    return Stream.of(
+      Arguments.of((Supplier<AsyncTable<?>>) AbstractTestAsyncTableRegionReplicasRead::getRawTable),
+      Arguments.of((Supplier<AsyncTable<?>>) AbstractTestAsyncTableRegionReplicasRead::getTable));
+  }
 
-  private static AsyncTable<?> getRawTable() {
-    return ASYNC_CONN.getTable(TABLE_NAME);
+  protected AbstractTestAsyncTableRegionReplicasRead(Supplier<AsyncTable<?>> getTable) {
+    this.getTable = getTable;
   }
 
-  private static AsyncTable<?> getTable() {
-    return ASYNC_CONN.getTable(TABLE_NAME, ForkJoinPool.commonPool());
+  protected static AsyncTable<?> getRawTable() {
+    return ASYNC_CONN.getTable(TABLE_NAME);
   }
 
-  @Parameters
-  public static List<Object[]> params() {
-    return Arrays.asList(
-      new Supplier<?>[] { AbstractTestAsyncTableRegionReplicasRead::getRawTable },
-      new Supplier<?>[] { AbstractTestAsyncTableRegionReplicasRead::getTable });
+  protected static AsyncTable<?> getTable() {
+    return ASYNC_CONN.getTable(TABLE_NAME, ForkJoinPool.commonPool());
   }
 
   protected static volatile boolean FAIL_PRIMARY_GET = false;
@@ -151,7 +147,7 @@ public abstract class AbstractTestAsyncTableRegionReplicasRead {
     TEST_UTIL.waitFor(30000, () -> allReplicasHaveRow(row));
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     TEST_UTIL.shutdownMiniCluster();
@@ -171,7 +167,7 @@ public abstract class AbstractTestAsyncTableRegionReplicasRead {
   // replicaId = -1 means do not set replica
   protected abstract void readAndCheck(AsyncTable<?> table, int replicaId) throws Exception;
 
-  @Test
+  @TestTemplate
   public void testNoReplicaRead() throws Exception {
     FAIL_PRIMARY_GET = false;
     REPLICA_ID_TO_COUNT.clear();
@@ -183,7 +179,7 @@ public abstract class AbstractTestAsyncTableRegionReplicasRead {
     assertEquals(0, getSecondaryGetCount());
   }
 
-  @Test
+  @TestTemplate
   public void testReplicaRead() throws Exception {
     // fail the primary get request
     FAIL_PRIMARY_GET = true;
@@ -198,7 +194,7 @@ public abstract class AbstractTestAsyncTableRegionReplicasRead {
     assertEquals(count, getPrimaryGetCount());
   }
 
-  @Test
+  @TestTemplate
   public void testReadSpecificReplica() throws Exception {
     FAIL_PRIMARY_GET = false;
     REPLICA_ID_TO_COUNT.clear();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIOperationTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIOperationTimeout.java
index 4f449e2e0cf..8facdedf212 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIOperationTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIOperationTimeout.java
@@ -17,13 +17,13 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.net.SocketTimeoutException;
 import org.apache.hadoop.hbase.TableName;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,9 +36,9 @@ public abstract class AbstractTestCIOperationTimeout extends AbstractTestCITimeo
 
   private TableName tableName;
 
-  @Before
+  @BeforeEach
   public void setUp() throws IOException {
-    tableName = TableName.valueOf(name.getMethodName());
+    tableName = name.getTableName();
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
       .setCoprocessor(SleepAndFailFirstTime.class.getName())
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAM_NAM)).build();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIRpcTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIRpcTimeout.java
index 0fef02aca88..21674199b38 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIRpcTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCIRpcTimeout.java
@@ -17,14 +17,14 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -37,9 +37,9 @@ public abstract class AbstractTestCIRpcTimeout extends AbstractTestCITimeout {
 
   private TableName tableName;
 
-  @Before
+  @BeforeEach
   public void setUp() throws IOException {
-    tableName = TableName.valueOf(name.getMethodName());
+    tableName = name.getTableName();
     TableDescriptor htd =
       TableDescriptorBuilder.newBuilder(tableName).setCoprocessor(SleepCoprocessor.class.getName())
         .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAM_NAM)).build();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCITimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCITimeout.java
index b9cbd36f584..d28992fe8df 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCITimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestCITimeout.java
@@ -25,6 +25,7 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.TableNameTestExtension;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
@@ -32,10 +33,9 @@ import org.apache.hadoop.hbase.coprocessor.RegionObserver;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
 import org.apache.hadoop.hbase.wal.WALEdit;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
 /**
  * Based class for testing timeout logic.
@@ -46,8 +46,8 @@ public abstract class AbstractTestCITimeout {
 
   protected static final byte[] FAM_NAM = Bytes.toBytes("f");
 
-  @Rule
-  public final TestName name = new TestName();
+  @RegisterExtension
+  protected final TableNameTestExtension name = new TableNameTestExtension();
 
   /**
    * This copro sleeps 20 second. The first call it fails. The second time, it works.
@@ -146,7 +146,7 @@ public abstract class AbstractTestCITimeout {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true);
     // Up the handlers; this test needs more than usual.
@@ -157,7 +157,7 @@ public abstract class AbstractTestCITimeout {
 
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestRegionLocator.java
index 031dff736c8..b234071f3b3 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestRegionLocator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestRegionLocator.java
@@ -17,8 +17,8 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -32,8 +32,8 @@ import org.apache.hadoop.hbase.regionserver.Region;
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Pair;
-import org.junit.After;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
 
 public abstract class AbstractTestRegionLocator {
 
@@ -66,7 +66,7 @@ public abstract class AbstractTestRegionLocator {
     UTIL.getAdmin().balancerSwitch(false, true);
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() throws IOException {
     clearCache(TABLE_NAME);
     clearCache(TableName.META_TABLE_NAME);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestResultScannerCursor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestResultScannerCursor.java
index 4b713ccd7af..b345a769e3a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestResultScannerCursor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestResultScannerCursor.java
@@ -17,12 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
 public abstract class AbstractTestResultScannerCursor extends AbstractTestScanCursor {
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestScanCursor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestScanCursor.java
index 7facb426422..aab71a5ed04 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestScanCursor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/AbstractTestScanCursor.java
@@ -33,8 +33,6 @@ import org.apache.hadoop.hbase.filter.FilterBase;
 import org.apache.hadoop.hbase.regionserver.StoreScanner;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 
 public abstract class AbstractTestScanCursor {
 
@@ -62,8 +60,7 @@ public abstract class AbstractTestScanCursor {
 
   protected static final int TIMEOUT = 4000;
 
-  @BeforeClass
-  public static void setUpBeforeClass() throws Exception {
+  protected static void startCluster() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
 
     conf.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, TIMEOUT);
@@ -97,8 +94,7 @@ public abstract class AbstractTestScanCursor {
     return puts;
   }
 
-  @AfterClass
-  public static void tearDownAfterClass() throws Exception {
+  protected static void stopCluster() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/BasicReadWriteWithDifferentConnectionRegistriesTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/BasicReadWriteWithDifferentConnectionRegistriesTestBase.java
index 86cc1a0cb96..123490816de 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/BasicReadWriteWithDifferentConnectionRegistriesTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/BasicReadWriteWithDifferentConnectionRegistriesTestBase.java
@@ -17,8 +17,8 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 
 import java.io.IOException;
 import java.net.URI;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/ClientPushbackTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/ClientPushbackTestBase.java
index 8ea36bed036..1c300e687d2 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/ClientPushbackTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/ClientPushbackTestBase.java
@@ -18,10 +18,10 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.client.MetricsConnection.CLIENT_SIDE_METRICS_ENABLED_KEY;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
@@ -39,9 +39,9 @@ import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.regionserver.Region;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -58,7 +58,7 @@ public abstract class ClientPushbackTestBase {
   private static final byte[] qualifier = Bytes.toBytes("q");
   private static final long flushSizeBytes = 512;
 
-  @BeforeClass
+  @BeforeAll
   public static void setupCluster() throws Exception {
     Configuration conf = UTIL.getConfiguration();
     // enable backpressure
@@ -77,7 +77,7 @@ public abstract class ClientPushbackTestBase {
     UTIL.createTable(tableName, family);
   }
 
-  @AfterClass
+  @AfterAll
   public static void cleanupCluster() throws Exception {
     UTIL.shutdownMiniCluster();
   }
@@ -112,11 +112,11 @@ public abstract class ClientPushbackTestBase {
 
     // get the stats for the region hosting our table
     ClientBackoffPolicy backoffPolicy = getBackoffPolicy();
-    assertTrue("Backoff policy is not correctly configured",
-      backoffPolicy instanceof ExponentialClientBackoffPolicy);
+    assertTrue(backoffPolicy instanceof ExponentialClientBackoffPolicy,
+      "Backoff policy is not correctly configured");
 
     ServerStatisticTracker stats = getStatisticsTracker();
-    assertNotNull("No stats configured for the client!", stats);
+    assertNotNull(stats, "No stats configured for the client!");
     // get the names so we can query the stats
     ServerName server = rs.getServerName();
     byte[] regionName = region.getRegionInfo().getRegionName();
@@ -124,11 +124,11 @@ public abstract class ClientPushbackTestBase {
     // check to see we found some load on the memstore
     ServerStatistics serverStats = stats.getStats(server);
     ServerStatistics.RegionStatistics regionStats = serverStats.getStatsForRegion(regionName);
-    assertEquals("We did not find some load on the memstore", load,
-      regionStats.getMemStoreLoadPercent());
+    assertEquals(load, regionStats.getMemStoreLoadPercent(),
+      "We did not find some load on the memstore");
     // check that the load reported produces a nonzero delay
     long backoffTime = backoffPolicy.getBackoffTime(server, regionName, serverStats);
-    assertNotEquals("Reported load does not produce a backoff", 0, backoffTime);
+    assertNotEquals(0, backoffTime, "Reported load does not produce a backoff");
     LOG.debug("Backoff calculated for " + region.getRegionInfo().getRegionNameAsString() + " @ "
       + server + " is " + backoffTime);
 
@@ -153,12 +153,12 @@ public abstract class ClientPushbackTestBase {
 
     assertEquals(1, runnerStats.delayRunners.getCount());
     assertEquals(1, runnerStats.normalRunners.getCount());
-    assertEquals("", runnerStats.delayIntevalHist.getSnapshot().getMean(), (double) backoffTime,
-      0.1);
+    assertEquals(runnerStats.delayIntevalHist.getSnapshot().getMean(), (double) backoffTime, 0.1,
+      "");
 
     latch.await(backoffTime * 2, TimeUnit.MILLISECONDS);
-    assertNotEquals("AsyncProcess did not submit the work time", 0, endTime.get());
-    assertTrue("AsyncProcess did not delay long enough", endTime.get() - startTime >= backoffTime);
+    assertNotEquals(0, endTime.get(), "AsyncProcess did not submit the work time");
+    assertTrue(endTime.get() - startTime >= backoffTime, "AsyncProcess did not delay long enough");
   }
 
   @Test
@@ -173,7 +173,7 @@ public abstract class ClientPushbackTestBase {
     mutateRow(mutations);
 
     ServerStatisticTracker stats = getStatisticsTracker();
-    assertNotNull("No stats configured for the client!", stats);
+    assertNotNull(stats, "No stats configured for the client!");
     // get the names so we can query the stats
     ServerName server = rs.getServerName();
     byte[] regionName = region.getRegionInfo().getRegionName();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTest4.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTest4.java
index e00d049bc6a..ed55b9c60d4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTest4.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTest4.java
@@ -870,7 +870,7 @@ public class FromClientSideTest4 extends FromClientSideTestBase {
       get.addFamily(FAMILY);
       Result r = table.get(get);
       assertFalse(r.isEmpty());
-      System.out.println("Row retrieved successfully");
+      LOG.info("Row retrieved successfully");
 
       byte[] missingrow = Bytes.toBytes("missingrow");
       get = new Get(missingrow);
@@ -916,7 +916,7 @@ public class FromClientSideTest4 extends FromClientSideTestBase {
       try (ResultScanner scanner = table.getScanner(scan)) {
         for (Result r : scanner) {
           for (Cell key : r.rawCells()) {
-            System.out.println(Bytes.toString(r.getRow()) + ": " + key.toString());
+            LOG.info(Bytes.toString(r.getRow()) + ": " + key.toString());
           }
         }
       }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTestBase.java
index a347a045e0f..8d81bcc47f0 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/FromClientSideTestBase.java
@@ -155,9 +155,9 @@ public class FromClientSideTestBase {
     int numberOfResults = 0;
     while (scanner.hasNext()) {
       Result result = scanner.next();
-      System.out.println("Got back key: " + Bytes.toString(result.getRow()));
+      LOG.info("Got back key: " + Bytes.toString(result.getRow()));
       for (Cell kv : result.rawCells()) {
-        System.out.println("kv=" + kv.toString() + ", " + Bytes.toString(CellUtil.cloneValue(kv)));
+        LOG.info("kv=" + kv.toString() + ", " + Bytes.toString(CellUtil.cloneValue(kv)));
       }
       numberOfResults++;
     }
@@ -192,7 +192,7 @@ public class FromClientSideTestBase {
   protected void putRows(Table ht, int numRows, String value, String key) throws IOException {
     for (int i = 0; i < numRows; i++) {
       String row = key + "_" + HBaseCommonTestingUtil.getRandomUUID().toString();
-      System.out.println(String.format("Saving row: %s, with value %s", row, value));
+      LOG.info(String.format("Saving row: %s, with value %s", row, value));
       Put put = new Put(Bytes.toBytes(row));
       put.setDurability(Durability.SKIP_WAL);
       put.addColumn(Bytes.toBytes("trans-blob"), null, Bytes.toBytes("value for blob"));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/MetaWithReplicasTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/MetaWithReplicasTestBase.java
index 2b6b3d017fc..bcc2db1c1b9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/MetaWithReplicasTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/MetaWithReplicasTestBase.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -27,19 +27,19 @@ import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.StartTestingClusterOption;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.TableNameTestRule;
+import org.apache.hadoop.hbase.TableNameTestExtension;
 import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
 import org.apache.hadoop.hbase.master.assignment.AssignmentTestingUtil;
 import org.apache.hadoop.hbase.regionserver.StorefileRefresherChore;
-import org.junit.AfterClass;
-import org.junit.Rule;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.extension.RegisterExtension;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Base class for testing the scenarios where replicas are enabled for the meta table.
  */
-public class MetaWithReplicasTestBase {
+public abstract class MetaWithReplicasTestBase {
 
   private static final Logger LOG = LoggerFactory.getLogger(MetaWithReplicasTestBase.class);
 
@@ -47,8 +47,8 @@ public class MetaWithReplicasTestBase {
 
   protected static final int REGIONSERVERS_COUNT = 3;
 
-  @Rule
-  public TableNameTestRule name = new TableNameTestRule();
+  @RegisterExtension
+  protected TableNameTestExtension name = new TableNameTestExtension();
 
   protected static void startCluster() throws Exception {
     TEST_UTIL.getConfiguration().setInt("zookeeper.session.timeout", 30000);
@@ -78,7 +78,7 @@ public class MetaWithReplicasTestBase {
     // to fail ... sometimes.
     if (sns.size() == 1) {
       int count = TEST_UTIL.getMiniHBaseCluster().getLiveRegionServerThreads().size();
-      assertTrue("count=" + count, count == REGIONSERVERS_COUNT);
+      assertEquals(count, REGIONSERVERS_COUNT, "count=" + count);
       LOG.warn("All hbase:meta replicas are on the one server; moving hbase:meta: " + sns);
       int metaServerIndex = TEST_UTIL.getHBaseCluster().getServerWithMeta();
       int newServerIndex = metaServerIndex;
@@ -99,7 +99,7 @@ public class MetaWithReplicasTestBase {
     LOG.debug("All meta replicas assigned");
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/RegionReplicaTestHelper.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/RegionReplicaTestHelper.java
index a98ae217e3c..ae8df5c0f1e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/RegionReplicaTestHelper.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/RegionReplicaTestHelper.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotCloneIndependenceTestBase.java
similarity index 82%
copy from hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java
copy to hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotCloneIndependenceTestBase.java
index 452fe5d514f..b58a2271313 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotCloneIndependence.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotCloneIndependenceTestBase.java
@@ -17,50 +17,38 @@
  */
 package org.apache.hadoop.hbase.client;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.util.List;
 import java.util.regex.Pattern;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
 import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy;
 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
-import org.apache.hadoop.hbase.testclassification.ClientTests;
-import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Test to verify that the cloned table is independent of the table from which it was cloned
  */
-@Category({ LargeTests.class, ClientTests.class })
-public class TestSnapshotCloneIndependence {
-
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestSnapshotCloneIndependence.class);
+public abstract class SnapshotCloneIndependenceTestBase {
 
-  private static final Logger LOG = LoggerFactory.getLogger(TestSnapshotCloneIndependence.class);
-
-  @Rule
-  public TestName testName = new TestName();
+  private static final Logger LOG =
+    LoggerFactory.getLogger(SnapshotCloneIndependenceTestBase.class);
 
   protected static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
@@ -79,16 +67,7 @@ public class TestSnapshotCloneIndependence {
   String snapshotNameAsString;
   String snapshotName;
 
-  /**
-   * Setup the config for the cluster and start it
-   */
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    setupConf(UTIL.getConfiguration());
-    UTIL.startMiniCluster(NUM_RS);
-  }
-
-  static void setupConf(Configuration conf) {
+  protected static void setupConf(Configuration conf) {
     // Up the handlers; this test needs more than usual.
     conf.setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 15);
     // enable snapshot support
@@ -115,13 +94,13 @@ public class TestSnapshotCloneIndependence {
     conf.setInt("hbase.master.hfilecleaner.ttl", CLEANER_INTERVAL);
   }
 
-  @Before
-  public void setup() throws Exception {
+  @BeforeEach
+  public void setup(TestInfo testInfo) throws Exception {
     fs = UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getFileSystem();
     rootDir = UTIL.getHBaseCluster().getMaster().getMasterFileSystem().getRootDir();
 
     admin = UTIL.getAdmin();
-    originalTableName = TableName.valueOf("test" + testName.getMethodName());
+    originalTableName = TableName.valueOf("test" + testInfo.getTestMethod().get().getName());
     cloneTableName = TableName.valueOf("test-clone-" + originalTableName);
     snapshotNameAsString = "snapshot_" + originalTableName;
     snapshotName = snapshotNameAsString;
@@ -129,10 +108,10 @@ public class TestSnapshotCloneIndependence {
     originalTable = createTable(originalTableName, TEST_FAM);
     loadData(originalTable, TEST_FAM);
     countOriginalTable = countRows(originalTable);
-    System.out.println("Original table has: " + countOriginalTable + " rows");
+    LOG.info("Original table has: " + countOriginalTable + " rows");
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     UTIL.deleteTable(originalTableName);
     UTIL.deleteTable(cloneTableName);
@@ -140,7 +119,7 @@ public class TestSnapshotCloneIndependence {
     SnapshotTestingUtils.deleteArchiveDirectory(UTIL);
   }
 
-  @AfterClass
+  @AfterAll
   public static void cleanupTest() throws Exception {
     try {
       UTIL.shutdownMiniCluster();
@@ -260,9 +239,8 @@ public class TestSnapshotCloneIndependence {
     try (Table clonedTable = UTIL.getConnection().getTable(cloneTableName)) {
       final int clonedTableRowCount = countRows(clonedTable);
 
-      Assert.assertEquals(
-        "The line counts of original and cloned tables do not match after clone. ",
-        countOriginalTable, clonedTableRowCount);
+      assertEquals(countOriginalTable, clonedTableRowCount,
+        "The line counts of original and cloned tables do not match after clone. ");
 
       // Attempt to add data to the test
       Put p = new Put(Bytes.toBytes("new-row-" + EnvironmentEdgeManager.currentTime()));
@@ -270,22 +248,20 @@ public class TestSnapshotCloneIndependence {
       originalTable.put(p);
 
       // Verify that the new row is not in the restored table
-      Assert.assertEquals("The row count of the original table was not modified by the put",
-        countOriginalTable + 1, countRows(originalTable));
-      Assert.assertEquals(
-        "The row count of the cloned table changed as a result of addition to the original",
-        clonedTableRowCount, countRows(clonedTable));
+      assertEquals(countOriginalTable + 1, countRows(originalTable),
+        "The row count of the original table was not modified by the put");
+      assertEquals(clonedTableRowCount, countRows(clonedTable),
+        "The row count of the cloned table changed as a result of addition to the original");
 
       Put p2 = new Put(Bytes.toBytes("new-row-" + EnvironmentEdgeManager.currentTime()));
       p2.addColumn(TEST_FAM, Bytes.toBytes("someQualifier"), Bytes.toBytes("someString"));
       clonedTable.put(p2);
 
       // Verify that the row is not added to the original table.
-      Assert.assertEquals(
-        "The row count of the original table was modified by the put to the clone",
-        countOriginalTable + 1, countRows(originalTable));
-      Assert.assertEquals("The row count of the cloned table was not modified by the put",
-        clonedTableRowCount + 1, countRows(clonedTable));
+      assertEquals(countOriginalTable + 1, countRows(originalTable),
+        "The row count of the original table was modified by the put to the clone");
+      assertEquals(clonedTableRowCount + 1, countRows(clonedTable),
+        "The row count of the cloned table was not modified by the put");
     }
   }
 
@@ -299,9 +275,8 @@ public class TestSnapshotCloneIndependence {
 
     final int originalRegionCount = originalTableHRegions.size();
     final int cloneTableRegionCount = admin.getRegions(cloneTableName).size();
-    Assert.assertEquals(
-      "The number of regions in the cloned table is different than in the original table.",
-      originalRegionCount, cloneTableRegionCount);
+    assertEquals(originalRegionCount, cloneTableRegionCount,
+      "The number of regions in the cloned table is different than in the original table.");
 
     // Split a region on the parent table
     admin.splitRegionAsync(originalTableHRegions.get(0).getRegionName()).get();
@@ -309,9 +284,8 @@ public class TestSnapshotCloneIndependence {
 
     // Verify that the cloned table region is not split
     final int cloneTableRegionCount2 = admin.getRegions(cloneTableName).size();
-    Assert.assertEquals(
-      "The number of regions in the cloned table changed though none of its regions were split.",
-      cloneTableRegionCount, cloneTableRegionCount2);
+    assertEquals(cloneTableRegionCount, cloneTableRegionCount2,
+      "The number of regions in the cloned table changed though none of its regions were split.");
   }
 
   /**
@@ -335,15 +309,15 @@ public class TestSnapshotCloneIndependence {
     TableDescriptor originalTableDescriptor = originalTable.getDescriptor();
     TableDescriptor clonedTableDescriptor = admin.getDescriptor(cloneTableName);
 
-    Assert.assertTrue("The original family was not found. There is something wrong. ",
-      originalTableDescriptor.hasColumnFamily(TEST_FAM));
-    Assert.assertTrue("The original family was not found in the clone. There is something wrong. ",
-      clonedTableDescriptor.hasColumnFamily(TEST_FAM));
+    assertTrue(originalTableDescriptor.hasColumnFamily(TEST_FAM),
+      "The original family was not found. There is something wrong. ");
+    assertTrue(clonedTableDescriptor.hasColumnFamily(TEST_FAM),
+      "The original family was not found in the clone. There is something wrong. ");
 
-    Assert.assertTrue("The new family was not found. ",
-      originalTableDescriptor.hasColumnFamily(TEST_FAM_2));
-    Assert.assertTrue("The new family was not found. ",
-      !clonedTableDescriptor.hasColumnFamily(TEST_FAM_2));
+    assertTrue(originalTableDescriptor.hasColumnFamily(TEST_FAM_2),
+      "The new family was not found. ");
+    assertTrue(!clonedTableDescriptor.hasColumnFamily(TEST_FAM_2),
+      "The new family was not found. ");
   }
 
   /**
@@ -367,7 +341,7 @@ public class TestSnapshotCloneIndependence {
         // Verify that all regions of both tables are readable
         final int origTableRowCount = countRows(original);
         final int clonedTableRowCount = countRows(clonedTable);
-        Assert.assertEquals(origTableRowCount, clonedTableRowCount);
+        assertEquals(origTableRowCount, clonedTableRowCount);
       }
     }
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotFromClientTestBase.java
similarity index 89%
copy from hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java
copy to hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotFromClientTestBase.java
index 8abb4d754a7..3c1ed7590ad 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotFromClient.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotFromClientTestBase.java
@@ -17,23 +17,23 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.TableNameTestRule;
+import org.apache.hadoop.hbase.TableNameTestExtension;
 import org.apache.hadoop.hbase.TableNotFoundException;
 import org.apache.hadoop.hbase.master.snapshot.SnapshotManager;
 import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy;
@@ -42,22 +42,14 @@ import org.apache.hadoop.hbase.snapshot.SnapshotCreationException;
 import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV1;
 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
-import org.apache.hadoop.hbase.testclassification.ClientTests;
-import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.params.provider.Arguments;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -70,15 +62,9 @@ import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
  * <p>
  * This is an end-to-end test for the snapshot utility
  */
-@RunWith(Parameterized.class)
-@Category({ LargeTests.class, ClientTests.class })
-public class TestSnapshotFromClient {
+public abstract class SnapshotFromClientTestBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestSnapshotFromClient.class);
-
-  private static final Logger LOG = LoggerFactory.getLogger(TestSnapshotFromClient.class);
+  private static final Logger LOG = LoggerFactory.getLogger(SnapshotFromClientTestBase.class);
 
   protected static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
   protected static final int NUM_RS = 2;
@@ -87,26 +73,18 @@ public class TestSnapshotFromClient {
   protected static final TableName TABLE_NAME = TableName.valueOf(STRING_TABLE_NAME);
   private static final Pattern MATCH_ALL = Pattern.compile(".*");
 
-  @Rule
-  public TableNameTestRule name = new TableNameTestRule();
+  @RegisterExtension
+  protected TableNameTestExtension name = new TableNameTestExtension();
 
-  @Parameter
-  public StoreFileTrackerFactory.Trackers trackerImpl;
+  protected final StoreFileTrackerFactory.Trackers trackerImpl;
 
-  @Parameters(name = "{index}: tracker={0}")
-  public static List<Object[]> params() {
-    return Arrays.asList(new Object[] { StoreFileTrackerFactory.Trackers.DEFAULT },
-      new Object[] { StoreFileTrackerFactory.Trackers.FILE });
+  public SnapshotFromClientTestBase(StoreFileTrackerFactory.Trackers trackerImpl) {
+    this.trackerImpl = trackerImpl;
   }
 
-  /**
-   * Setup the config for the cluster
-   * @throws Exception on failure
-   */
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    setupConf(UTIL.getConfiguration());
-    UTIL.startMiniCluster(NUM_RS);
+  public static Stream<Arguments> parameters() {
+    return Stream.of(Arguments.of(StoreFileTrackerFactory.Trackers.DEFAULT),
+      Arguments.of(StoreFileTrackerFactory.Trackers.FILE));
   }
 
   protected static void setupConf(Configuration conf) {
@@ -126,7 +104,7 @@ public class TestSnapshotFromClient {
       ConstantSizeRegionSplitPolicy.class.getName());
   }
 
-  @Before
+  @BeforeEach
   public void setup() throws Exception {
     createTable();
   }
@@ -142,14 +120,14 @@ public class TestSnapshotFromClient {
     return 1;
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     UTIL.deleteTable(TABLE_NAME);
     SnapshotTestingUtils.deleteAllSnapshots(UTIL.getAdmin());
     SnapshotTestingUtils.deleteArchiveDirectory(UTIL);
   }
 
-  @AfterClass
+  @AfterAll
   public static void cleanupTest() throws Exception {
     try {
       UTIL.shutdownMiniCluster();
@@ -161,15 +139,16 @@ public class TestSnapshotFromClient {
   /**
    * Test snapshotting not allowed hbase:meta and -ROOT-
    */
-  @Test(expected = IllegalArgumentException.class)
+  @TestTemplate
   public void testMetaTablesSnapshot() throws Exception {
-    UTIL.getAdmin().snapshot("metaSnapshot", TableName.META_TABLE_NAME);
+    assertThrows(IllegalArgumentException.class,
+      () -> UTIL.getAdmin().snapshot("metaSnapshot", TableName.META_TABLE_NAME));
   }
 
   /**
    * Test HBaseAdmin#deleteSnapshots(String) which deletes snapshots whose names match the parameter
    */
-  @Test
+  @TestTemplate
   public void testSnapshotDeletionWithRegex() throws Exception {
     Admin admin = UTIL.getAdmin();
     // make sure we don't fail on listing snapshots
@@ -205,7 +184,7 @@ public class TestSnapshotFromClient {
   /**
    * Test snapshotting a table that is offline
    */
-  @Test
+  @TestTemplate
   public void testOfflineTableSnapshot() throws Exception {
     Admin admin = UTIL.getAdmin();
     // make sure we don't fail on listing snapshots
@@ -253,7 +232,7 @@ public class TestSnapshotFromClient {
     SnapshotTestingUtils.assertNoSnapshots(admin);
   }
 
-  @Test
+  @TestTemplate
   public void testSnapshotFailsOnNonExistantTable() throws Exception {
     Admin admin = UTIL.getAdmin();
     // make sure we don't fail on listing snapshots
@@ -282,7 +261,7 @@ public class TestSnapshotFromClient {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testOfflineTableSnapshotWithEmptyRegions() throws Exception {
     // test with an empty table with one region
 
@@ -326,7 +305,7 @@ public class TestSnapshotFromClient {
     SnapshotTestingUtils.assertNoSnapshots(admin);
   }
 
-  @Test
+  @TestTemplate
   public void testListTableSnapshots() throws Exception {
     Admin admin = null;
     final TableName tableName = name.getTableName();
@@ -372,7 +351,7 @@ public class TestSnapshotFromClient {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testListTableSnapshotsWithRegex() throws Exception {
     Admin admin = null;
     try {
@@ -411,7 +390,7 @@ public class TestSnapshotFromClient {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testDeleteTableSnapshots() throws Exception {
     Admin admin = null;
     final TableName tableName = name.getTableName();
@@ -446,7 +425,7 @@ public class TestSnapshotFromClient {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testDeleteTableSnapshotsWithRegex() throws Exception {
     Admin admin = null;
     Pattern tableNamePattern = Pattern.compile("test.*");
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotTemporaryDirectory.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotTemporaryDirectoryTestBase.java
similarity index 92%
copy from hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotTemporaryDirectory.java
copy to hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotTemporaryDirectoryTestBase.java
index 8f8d0d55443..9dad3e4b0a7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestSnapshotTemporaryDirectory.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotTemporaryDirectoryTestBase.java
@@ -17,24 +17,23 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Paths;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.UUID;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import org.apache.commons.io.FileUtils;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -45,19 +44,14 @@ import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV1;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV2;
 import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils;
-import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,24 +65,21 @@ import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
  * <p>
  * This is an end-to-end test for the snapshot utility
  */
-@Category(LargeTests.class)
-@RunWith(Parameterized.class)
-public class TestSnapshotTemporaryDirectory {
-
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestSnapshotTemporaryDirectory.class);
-
-  @Parameterized.Parameters
-  public static Iterable<Integer> data() {
-    return Arrays.asList(SnapshotManifestV1.DESCRIPTOR_VERSION,
-      SnapshotManifestV2.DESCRIPTOR_VERSION);
+public abstract class SnapshotTemporaryDirectoryTestBase {
+
+  public static Stream<Arguments> parameters() {
+    return Stream.of(Arguments.of(SnapshotManifestV1.DESCRIPTOR_VERSION),
+      Arguments.of(SnapshotManifestV2.DESCRIPTOR_VERSION));
   }
 
-  @Parameterized.Parameter
-  public int manifestVersion;
+  private final int manifestVersion;
+
+  public SnapshotTemporaryDirectoryTestBase(int manifestVersion) {
+    this.manifestVersion = manifestVersion;
+  }
 
-  private static final Logger LOG = LoggerFactory.getLogger(TestSnapshotTemporaryDirectory.class);
+  private static final Logger LOG =
+    LoggerFactory.getLogger(SnapshotTemporaryDirectoryTestBase.class);
   protected static final int NUM_RS = 2;
   protected static String TEMP_DIR =
     Paths.get("").toAbsolutePath().toString() + Path.SEPARATOR + UUID.randomUUID().toString();
@@ -99,18 +90,7 @@ public class TestSnapshotTemporaryDirectory {
   protected static final byte[] TEST_FAM = Bytes.toBytes("fam");
   protected static final TableName TABLE_NAME = TableName.valueOf(STRING_TABLE_NAME);
 
-  /**
-   * Setup the config for the cluster
-   * @throws Exception on failure
-   */
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    setupConf(UTIL.getConfiguration());
-    UTIL.startMiniCluster(NUM_RS);
-    admin = UTIL.getAdmin();
-  }
-
-  private static void setupConf(Configuration conf) {
+  protected static void setupConf(Configuration conf) throws IOException {
     // disable the ui
     conf.setInt("hbase.regionsever.info.port", -1);
     // change the flush size to a small amount, regulating number of store files
@@ -129,7 +109,7 @@ public class TestSnapshotTemporaryDirectory {
       "file://" + new Path(TEMP_DIR, ".tmpDir").toUri());
   }
 
-  @Before
+  @BeforeEach
   public void setup() throws Exception {
     TableDescriptor htd =
       TableDescriptorBuilder.newBuilder(TABLE_NAME).setRegionReplication(getNumReplicas()).build();
@@ -140,14 +120,14 @@ public class TestSnapshotTemporaryDirectory {
     return 1;
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     UTIL.deleteTable(TABLE_NAME);
     SnapshotTestingUtils.deleteAllSnapshots(UTIL.getAdmin());
     SnapshotTestingUtils.deleteArchiveDirectory(UTIL);
   }
 
-  @AfterClass
+  @AfterAll
   public static void cleanupTest() {
     try {
       UTIL.shutdownMiniCluster();
@@ -157,7 +137,7 @@ public class TestSnapshotTemporaryDirectory {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testRestoreDisabledSnapshot() throws IOException, InterruptedException {
     long tid = EnvironmentEdgeManager.currentTime();
     TableName tableName = TableName.valueOf("testtb-" + tid);
@@ -223,7 +203,7 @@ public class TestSnapshotTemporaryDirectory {
     SnapshotTestingUtils.verifyReplicasCameOnline(tableName, admin, getNumReplicas());
   }
 
-  @Test
+  @TestTemplate
   public void testRestoreEnabledSnapshot() throws IOException, InterruptedException {
     long tid = EnvironmentEdgeManager.currentTime();
     TableName tableName = TableName.valueOf("testtb-" + tid);
@@ -289,7 +269,7 @@ public class TestSnapshotTemporaryDirectory {
    * Test snapshotting a table that is offline
    * @throws Exception if snapshot does not complete successfully
    */
-  @Test
+  @TestTemplate
   public void testOfflineTableSnapshot() throws Exception {
     Admin admin = UTIL.getAdmin();
     // make sure we don't fail on listing snapshots
@@ -340,7 +320,7 @@ public class TestSnapshotTemporaryDirectory {
    * contents of the original and cloned table match
    * @throws Exception if snapshot does not complete successfully
    */
-  @Test
+  @TestTemplate
   public void testSnapshotCloneContents() throws Exception {
     // make sure we don't fail on listing snapshots
     SnapshotTestingUtils.assertNoSnapshots(admin);
@@ -377,7 +357,7 @@ public class TestSnapshotTemporaryDirectory {
     admin.close();
   }
 
-  @Test
+  @TestTemplate
   public void testOfflineTableSnapshotWithEmptyRegion() throws Exception {
     // test with an empty table with one region
 
@@ -420,7 +400,7 @@ public class TestSnapshotTemporaryDirectory {
   }
 
   // Ensures that the snapshot is transferred to the proper completed snapshot directory
-  @Test
+  @TestTemplate
   public void testEnsureTemporaryDirectoryTransfer() throws Exception {
     Admin admin = UTIL.getAdmin();
     TableName tableName2 = TableName.valueOf("testListTableSnapshots");
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
index 72e0a1a265d..f6acefe2b76 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/SnapshotWithAclTestBase.java
@@ -17,11 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.List;
@@ -34,7 +35,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtil;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
-import org.apache.hadoop.hbase.TableNameTestRule;
+import org.apache.hadoop.hbase.TableNameTestExtension;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
 import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
 import org.apache.hadoop.hbase.security.User;
@@ -48,19 +49,18 @@ import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
 import org.apache.hadoop.hbase.snapshot.SnapshotDoesNotExistException;
 import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
 
 public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
 
-  @Rule
-  public TableNameTestRule name = new TableNameTestRule();
+  @RegisterExtension
+  protected TableNameTestExtension name = new TableNameTestExtension();
 
-  private TableName TEST_TABLE = TableName.valueOf(TEST_UTIL.getRandomUUID().toString());
+  private TableName TEST_TABLE = TableName.valueOf(HBaseTestingUtil.getRandomUUID().toString());
 
   private static final int ROW_COUNT = 30000;
 
@@ -118,7 +118,7 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setupBeforeClass() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     // Enable security
@@ -145,7 +145,7 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
     grantGlobal(TEST_UTIL, USER_OWNER.getShortName(), Permission.Action.CREATE);
   }
 
-  @Before
+  @BeforeEach
   public void setUp() throws Exception {
     TableDescriptor tableDescriptor =
       TableDescriptorBuilder.newBuilder(TEST_TABLE)
@@ -174,7 +174,7 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
     }
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
@@ -186,7 +186,7 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
       int rowCount = 0;
       while ((result = scanner.next()) != null) {
         byte[] value = result.getValue(TEST_FAMILY, TEST_QUALIFIER);
-        Assert.assertArrayEquals(value, Bytes.toBytes(rowCount++));
+        assertArrayEquals(value, Bytes.toBytes(rowCount++));
       }
       assertEquals(ROW_COUNT, rowCount);
     }
@@ -210,11 +210,11 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
     loadData();
     verifyRows(TEST_TABLE);
 
-    String snapshotName1 = TEST_UTIL.getRandomUUID().toString();
+    String snapshotName1 = HBaseTestingUtil.getRandomUUID().toString();
     snapshot(snapshotName1, TEST_TABLE);
 
     // clone snapshot with restoreAcl true.
-    TableName tableName1 = TableName.valueOf(TEST_UTIL.getRandomUUID().toString());
+    TableName tableName1 = TableName.valueOf(HBaseTestingUtil.getRandomUUID().toString());
     cloneSnapshot(snapshotName1, tableName1, true);
     verifyRows(tableName1);
     verifyAllowed(new AccessReadAction(tableName1), USER_OWNER, USER_RO, USER_RW);
@@ -223,7 +223,7 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
     verifyDenied(new AccessWriteAction(tableName1), USER_RO, USER_NONE);
 
     // clone snapshot with restoreAcl false.
-    TableName tableName2 = TableName.valueOf(TEST_UTIL.getRandomUUID().toString());
+    TableName tableName2 = TableName.valueOf(HBaseTestingUtil.getRandomUUID().toString());
     cloneSnapshot(snapshotName1, tableName2, false);
     verifyRows(tableName2);
     verifyDenied(new AccessReadAction(tableName2), USER_OWNER);
@@ -331,9 +331,9 @@ public abstract class SnapshotWithAclTestBase extends SecureTestUtil {
 
     try {
       // Create snapshot without creating table
-      assertThrows("Snapshot operation should fail, table doesn't exist",
-        SnapshotCreationException.class,
-        () -> TEST_UTIL.getAdmin().snapshot(snapshotName, tableName));
+      assertThrows(SnapshotCreationException.class,
+        () -> TEST_UTIL.getAdmin().snapshot(snapshotName, tableName),
+        "Snapshot operation should fail, table doesn't exist");
 
       // Create the table
       TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName).build();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
index 68a841b7d67..75ca0feafa3 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin.java
@@ -19,13 +19,13 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.HBaseTestingUtil.countRows;
 import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -33,7 +33,6 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.ServerName;
@@ -47,18 +46,15 @@ import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFac
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAdmin extends TestAdminBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestAdmin.class);
 
   @Test
@@ -75,23 +71,23 @@ public class TestAdmin extends TestAdminBase {
   public void testCreateTable() throws IOException {
     List<TableDescriptor> tables = ADMIN.listTableDescriptors();
     int numTables = tables.size();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
     tables = ADMIN.listTableDescriptors();
     assertEquals(numTables + 1, tables.size());
-    assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster()
-      .getTableStateManager().isTableState(tableName, TableState.State.ENABLED));
+    assertTrue(TEST_UTIL.getHBaseCluster().getMaster().getTableStateManager()
+      .isTableState(tableName, TableState.State.ENABLED), "Table must be enabled.");
     assertEquals(TableState.State.ENABLED, getStateFromMeta(tableName));
   }
 
   @Test
   public void testTruncateTable() throws IOException {
-    testTruncateTable(TableName.valueOf(name.getMethodName()), false);
+    testTruncateTable(TableName.valueOf(methodName), false);
   }
 
   @Test
   public void testTruncateTablePreservingSplits() throws IOException {
-    testTruncateTable(TableName.valueOf(name.getMethodName()), true);
+    testTruncateTable(TableName.valueOf(methodName), true);
   }
 
   private void testTruncateTable(final TableName tableName, boolean preserveSplits)
@@ -128,13 +124,13 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testCreateTableNumberOfRegions() throws IOException, InterruptedException {
-    TableName table = TableName.valueOf(name.getMethodName());
+    TableName table = TableName.valueOf(methodName);
     ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY);
     ADMIN.createTable(TableDescriptorBuilder.newBuilder(table).setColumnFamily(cfd).build());
     List<HRegionLocation> regions;
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table)) {
       regions = l.getAllRegionLocations();
-      assertEquals("Table should have only 1 region", 1, regions.size());
+      assertEquals(1, regions.size(), "Table should have only 1 region");
     }
 
     TableName table2 = TableName.valueOf(table.getNameAsString() + "_2");
@@ -142,7 +138,7 @@ public class TestAdmin extends TestAdminBase {
       new byte[][] { new byte[] { 42 } });
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table2)) {
       regions = l.getAllRegionLocations();
-      assertEquals("Table should have only 2 region", 2, regions.size());
+      assertEquals(2, regions.size(), "Table should have only 2 region");
     }
 
     TableName table3 = TableName.valueOf(table.getNameAsString() + "_3");
@@ -150,7 +146,7 @@ public class TestAdmin extends TestAdminBase {
       Bytes.toBytes("a"), Bytes.toBytes("z"), 3);
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table3)) {
       regions = l.getAllRegionLocations();
-      assertEquals("Table should have only 3 region", 3, regions.size());
+      assertEquals(3, regions.size(), "Table should have only 3 region");
     }
 
     TableName table4 = TableName.valueOf(table.getNameAsString() + "_4");
@@ -167,13 +163,13 @@ public class TestAdmin extends TestAdminBase {
       new byte[] { 1 }, new byte[] { 127 }, 16);
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table5)) {
       regions = l.getAllRegionLocations();
-      assertEquals("Table should have 16 region", 16, regions.size());
+      assertEquals(16, regions.size(), "Table should have 16 region");
     }
   }
 
   @Test
   public void testCreateTableWithRegions() throws IOException, InterruptedException {
-    TableName table = TableName.valueOf(name.getMethodName());
+    TableName table = TableName.valueOf(methodName);
     ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY);
     byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
       new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 },
@@ -184,7 +180,7 @@ public class TestAdmin extends TestAdminBase {
       splitKeys);
 
     boolean tableAvailable = ADMIN.isTableAvailable(table);
-    assertTrue("Table should be created with splitKyes + 1 rows in META", tableAvailable);
+    assertTrue(tableAvailable, "Table should be created with splitKyes + 1 rows in META");
 
     List<HRegionLocation> regions;
     Iterator<HRegionLocation> hris;
@@ -192,10 +188,9 @@ public class TestAdmin extends TestAdminBase {
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table)) {
       regions = l.getAllRegionLocations();
 
-      assertEquals(
-        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
-        expectedRegions, regions.size());
-      System.err.println("Found " + regions.size() + " regions");
+      assertEquals(expectedRegions, regions.size(),
+        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
+      LOG.info("Found " + regions.size() + " regions");
 
       hris = regions.iterator();
       hri = hris.next().getRegion();
@@ -249,10 +244,9 @@ public class TestAdmin extends TestAdminBase {
 
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table2)) {
       regions = l.getAllRegionLocations();
-      assertEquals(
-        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
-        expectedRegions, regions.size());
-      System.err.println("Found " + regions.size() + " regions");
+      assertEquals(expectedRegions, regions.size(),
+        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
+      LOG.info("Found " + regions.size() + " regions");
 
       hris = regions.iterator();
       hri = hris.next().getRegion();
@@ -302,10 +296,9 @@ public class TestAdmin extends TestAdminBase {
 
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(table3)) {
       regions = l.getAllRegionLocations();
-      assertEquals(
-        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
-        expectedRegions, regions.size());
-      System.err.println("Found " + regions.size() + " regions");
+      assertEquals(expectedRegions, regions.size(),
+        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
+      LOG.info("Found " + regions.size() + " regions");
 
       verifyRoundRobinDistribution(l, expectedRegions);
     }
@@ -318,8 +311,8 @@ public class TestAdmin extends TestAdminBase {
     try {
       ADMIN.createTable(TableDescriptorBuilder.newBuilder(table4).setColumnFamily(cfd).build(),
         splitKeys);
-      assertTrue("Should not be able to create this table because of " + "duplicate split keys",
-        false);
+      assertTrue(false,
+        "Should not be able to create this table because of " + "duplicate split keys");
     } catch (IllegalArgumentException iae) {
       // Expected
     }
@@ -327,7 +320,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testCreateTableWithOnlyEmptyStartRow() throws IOException {
-    final byte[] tableName = Bytes.toBytes(name.getMethodName());
+    final byte[] tableName = Bytes.toBytes(methodName);
     byte[][] splitKeys = new byte[1][];
     splitKeys[0] = HConstants.EMPTY_BYTE_ARRAY;
     TableDescriptor desc = TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName))
@@ -341,7 +334,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testCreateTableWithEmptyRowInTheSplitKeys() throws IOException {
-    final byte[] tableName = Bytes.toBytes(name.getMethodName());
+    final byte[] tableName = Bytes.toBytes(methodName);
     byte[][] splitKeys = new byte[3][];
     splitKeys[0] = Bytes.toBytes("region1");
     splitKeys[1] = HConstants.EMPTY_BYTE_ARRAY;
@@ -374,21 +367,21 @@ public class TestAdmin extends TestAdminBase {
     int min = (int) Math.floor(average);
     int max = (int) Math.ceil(average);
     for (List<RegionInfo> regionList : server2Regions.values()) {
-      assertTrue("numRS=" + numRS + ", min=" + min + ", max=" + max + ", size=" + regionList.size(),
-        regionList.size() == min || regionList.size() == max);
+      assertTrue(regionList.size() == min || regionList.size() == max,
+        "numRS=" + numRS + ", min=" + min + ", max=" + max + ", size=" + regionList.size());
     }
   }
 
   @Test
   public void testCloneTableSchema() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new");
     testCloneTableSchema(tableName, newTableName, false);
   }
 
   @Test
   public void testCloneTableSchemaPreservingSplits() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new");
     testCloneTableSchema(tableName, newTableName, true);
   }
@@ -415,8 +408,8 @@ public class TestAdmin extends TestAdminBase {
     ADMIN.createTable(tableDesc, splitKeys);
 
     assertEquals(NUM_REGIONS, TEST_UTIL.getHBaseCluster().getRegions(tableName).size());
-    assertTrue("Table should be created with splitKyes + 1 rows in META",
-      ADMIN.isTableAvailable(tableName));
+    assertTrue(ADMIN.isTableAvailable(tableName),
+      "Table should be created with splitKyes + 1 rows in META");
 
     // clone & Verify
     ADMIN.cloneTableSchema(tableName, newTableName, preserveSplits);
@@ -433,8 +426,8 @@ public class TestAdmin extends TestAdminBase {
 
     if (preserveSplits) {
       assertEquals(NUM_REGIONS, TEST_UTIL.getHBaseCluster().getRegions(newTableName).size());
-      assertTrue("New table should be created with splitKyes + 1 rows in META",
-        ADMIN.isTableAvailable(newTableName));
+      assertTrue(ADMIN.isTableAvailable(newTableName),
+        "New table should be created with splitKyes + 1 rows in META");
     } else {
       assertEquals(1, TEST_UTIL.getHBaseCluster().getRegions(newTableName).size());
     }
@@ -442,7 +435,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testCloneTableSchemaWithNonExistentSourceTable() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new");
     // test for non-existent source table
     try {
@@ -455,7 +448,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testCloneTableSchemaWithExistentDestinationTable() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new");
     byte[] FAMILY_0 = Bytes.toBytes("cf0");
     TEST_UTIL.createTable(tableName, FAMILY_0);
@@ -471,7 +464,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testModifyTableOnTableWithRegionReplicas() throws Exception {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(Bytes.toBytes("cf")))
       .setRegionReplication(5).build();
@@ -492,7 +485,7 @@ public class TestAdmin extends TestAdminBase {
    */
   @Test
   public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     List<TableDescriptor> tables = ADMIN.listTableDescriptors();
     int numTables = tables.size();
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
@@ -558,7 +551,7 @@ public class TestAdmin extends TestAdminBase {
 
   @Test
   public void testUnknownServers() throws Exception {
-    TableName table = TableName.valueOf(name.getMethodName());
+    TableName table = TableName.valueOf(methodName);
     ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY);
     ADMIN.createTable(TableDescriptorBuilder.newBuilder(table).setColumnFamily(cfd).build());
     final List<RegionInfo> regions = ADMIN.getRegions(table);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
index 2de0c7d03c5..a37abae10d0 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin1.java
@@ -17,12 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.MetaTableAccessor;
@@ -51,9 +50,8 @@ import org.apache.hadoop.hbase.util.CommonFSUtils;
 import org.apache.hadoop.hbase.util.FutureUtils;
 import org.apache.hadoop.hbase.util.Pair;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -64,17 +62,15 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.MergeTable
  * Class to test HBaseAdmin. Spins up the minicluster once at test start and then takes it down
  * afterward. Add any testing of HBaseAdmin functionality here.
  */
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAdmin1 extends TestAdminBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin1.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestAdmin1.class);
 
   @Test
   public void testSplitFlushCompactUnknownTable() throws InterruptedException {
-    final TableName unknowntable = TableName.valueOf(name.getMethodName());
+    final TableName unknowntable = TableName.valueOf(methodName);
     Exception exception = null;
     try {
       ADMIN.compact(unknowntable);
@@ -102,7 +98,7 @@ public class TestAdmin1 extends TestAdminBase {
 
   @Test
   public void testCompactATableWithSuperLongTableName() throws Exception {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();
     try {
@@ -120,7 +116,7 @@ public class TestAdmin1 extends TestAdminBase {
 
   @Test
   public void testCompactionTimestamps() throws Exception {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1")).build();
     ADMIN.createTable(htd);
@@ -171,14 +167,15 @@ public class TestAdmin1 extends TestAdminBase {
     table.close();
   }
 
-  @Test(expected = IllegalArgumentException.class)
+  @Test
   public void testColumnValidName() {
-    ColumnFamilyDescriptorBuilder.of("\\test\\abc");
+    assertThrows(IllegalArgumentException.class,
+      () -> ColumnFamilyDescriptorBuilder.of("\\test\\abc"));
   }
 
   @Test
   public void testTableExist() throws IOException {
-    final TableName table = TableName.valueOf(name.getMethodName());
+    final TableName table = TableName.valueOf(methodName);
     boolean exist;
     exist = ADMIN.tableExists(table);
     assertEquals(false, exist);
@@ -367,8 +364,8 @@ public class TestAdmin1 extends TestAdminBase {
           for (int index = 0; index < familyNames.length; index++) {
             int delta = Math.abs(rowCounts[index] / 2 - splitKey);
             if (delta < deltaForLargestFamily) {
-              assertTrue("Delta " + delta + " for family " + index + " should be at least "
-                + "deltaForLargestFamily " + deltaForLargestFamily, false);
+              assertTrue(false, "Delta " + delta + " for family " + index + " should be at least "
+                + "deltaForLargestFamily " + deltaForLargestFamily);
             }
           }
         }
@@ -383,7 +380,7 @@ public class TestAdmin1 extends TestAdminBase {
     // are not allowed. The test validates that. Then the test does a valid split/merge of allowed
     // regions.
     // Set up a table with 3 regions and replication set to 3
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     byte[] cf = Bytes.toBytes("f");
     TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName).setRegionReplication(3)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(cf)).build();
@@ -477,9 +474,10 @@ public class TestAdmin1 extends TestAdminBase {
     assertTrue(gotException);
   }
 
-  @Test(expected = IllegalArgumentException.class)
-  public void testInvalidColumnDescriptor() throws IOException {
-    ColumnFamilyDescriptorBuilder.of("/cfamily/name");
+  @Test
+  public void testInvalidColumnDescriptor() {
+    assertThrows(IllegalArgumentException.class,
+      () -> ColumnFamilyDescriptorBuilder.of("/cfamily/name"));
   }
 
   /**
@@ -488,7 +486,7 @@ public class TestAdmin1 extends TestAdminBase {
    */
   @Test
   public void testHFileReplication() throws Exception {
-    final TableName tableName = TableName.valueOf(this.name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     String fn1 = "rep1";
     String fn = "defaultRep";
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
@@ -516,16 +514,17 @@ public class TestAdmin1 extends TestAdminBase {
         HStore store = r.getStore(Bytes.toBytes(fn));
         for (HStoreFile sf : store.getStorefiles()) {
           assertTrue(sf.toString().contains(fn));
-          assertTrue("Column family " + fn + " should have 3 copies",
+          assertTrue(
             CommonFSUtils.getDefaultReplication(TEST_UTIL.getTestFileSystem(), sf.getPath())
-                == (sf.getFileInfo().getFileStatus().getReplication()));
+                == (sf.getFileInfo().getFileStatus().getReplication()),
+            "Column family " + fn + " should have 3 copies");
         }
 
         store = r.getStore(Bytes.toBytes(fn1));
         for (HStoreFile sf : store.getStorefiles()) {
           assertTrue(sf.toString().contains(fn1));
-          assertTrue("Column family " + fn1 + " should have only 1 copy",
-            1 == sf.getFileInfo().getFileStatus().getReplication());
+          assertTrue(1 == sf.getFileInfo().getFileStatus().getReplication(),
+            "Column family " + fn1 + " should have only 1 copy");
         }
       }
     } finally {
@@ -538,7 +537,7 @@ public class TestAdmin1 extends TestAdminBase {
 
   @Test
   public void testMergeRegions() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TableDescriptor td = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("d")).build();
     byte[][] splitRows = new byte[2][];
@@ -598,7 +597,7 @@ public class TestAdmin1 extends TestAdminBase {
   @Test
   public void testMergeRegionsInvalidRegionCount()
     throws IOException, InterruptedException, ExecutionException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TableDescriptor td = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("d")).build();
     byte[][] splitRows = new byte[2][];
@@ -632,7 +631,7 @@ public class TestAdmin1 extends TestAdminBase {
 
   @Test
   public void testSplitShouldNotHappenIfSplitIsDisabledForTable() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
       .setRegionSplitPolicyClassName(DisabledRegionSplitPolicy.class.getName())
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin2.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin2.java
index 2cf088fa6a8..8b2698108b7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin2.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin2.java
@@ -17,11 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -35,7 +36,6 @@ import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import org.apache.hadoop.hbase.ClusterMetrics.Option;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
@@ -58,10 +58,8 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.FutureUtils;
 import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
-import org.junit.Assert;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -72,12 +70,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
  * Class to test HBaseAdmin. Spins up the minicluster once at test start and then takes it down
  * afterward. Add any testing of HBaseAdmin functionality here.
  */
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAdmin2 extends TestAdminBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin2.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestAdmin2.class);
 
   @Test
@@ -88,13 +84,14 @@ public class TestAdmin2 extends TestAdminBase {
     } catch (TableExistsException e) {
       msg = e.toString();
     }
-    assertTrue("Unexcepted exception message " + msg,
+    assertTrue(
       msg != null && msg.startsWith(TableExistsException.class.getName())
-        && msg.contains(TableName.META_TABLE_NAME.getNameAsString()));
+        && msg.contains(TableName.META_TABLE_NAME.getNameAsString()),
+      "Unexcepted exception message " + msg);
 
     // Now try and do concurrent creation with a bunch of threads.
     TableDescriptor tableDescriptor =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName))
         .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
     int count = 10;
     Thread[] threads = new Thread[count];
@@ -139,12 +136,12 @@ public class TestAdmin2 extends TestAdminBase {
    */
   @Test
   public void testTableNameClash() throws Exception {
-    final String name = this.name.getMethodName();
     TableDescriptor tableDescriptor1 =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(name + "SOMEUPPERCASE"))
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName + "SOMEUPPERCASE"))
+        .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
+    TableDescriptor tableDescriptor2 =
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName))
         .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
-    TableDescriptor tableDescriptor2 = TableDescriptorBuilder.newBuilder(TableName.valueOf(name))
-      .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
     ADMIN.createTable(tableDescriptor1);
     ADMIN.createTable(tableDescriptor2);
     // Before fix, below would fail throwing a NoServerForRegionException.
@@ -158,7 +155,6 @@ public class TestAdmin2 extends TestAdminBase {
    */
   @Test
   public void testCreateTableRPCTimeOut() throws Exception {
-    final String name = this.name.getMethodName();
     int oldTimeout = TEST_UTIL.getConfiguration().getInt(HConstants.HBASE_RPC_TIMEOUT_KEY,
       HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
@@ -168,8 +164,9 @@ public class TestAdmin2 extends TestAdminBase {
       byte[] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
       byte[] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
       Admin hbaseadmin = TEST_UTIL.getAdmin();
-      TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(TableName.valueOf(name))
-        .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
+      TableDescriptor tableDescriptor =
+        TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName))
+          .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
       hbaseadmin.createTable(tableDescriptor, startKey, endKey, expectedRegions);
     } finally {
       TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
@@ -181,7 +178,7 @@ public class TestAdmin2 extends TestAdminBase {
    */
   @Test
   public void testReadOnlyTable() throws Exception {
-    final TableName name = TableName.valueOf(this.name.getMethodName());
+    final TableName name = TableName.valueOf(methodName);
     Table table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
     byte[] value = Bytes.toBytes("somedata");
     // This used to use an empty row... That must have been a bug
@@ -199,9 +196,8 @@ public class TestAdmin2 extends TestAdminBase {
   public void testTableNames() throws IOException {
     byte[][] illegalNames = new byte[][] { Bytes.toBytes("-bad"), Bytes.toBytes(".bad") };
     for (byte[] illegalName : illegalNames) {
-      assertThrows(
-        "Did not detect '" + Bytes.toString(illegalName) + "' as an illegal user table name",
-        IllegalArgumentException.class, () -> TableName.valueOf(illegalName));
+      assertThrows(IllegalArgumentException.class, () -> TableName.valueOf(illegalName),
+        "Did not detect '" + Bytes.toString(illegalName) + "' as an illegal user table name");
     }
     byte[] legalName = Bytes.toBytes("g-oo.d");
     try {
@@ -215,49 +211,50 @@ public class TestAdmin2 extends TestAdminBase {
   /**
    * For HADOOP-2579
    */
-  @Test(expected = TableExistsException.class)
+  @Test
   public void testTableExistsExceptionWithATable() throws IOException {
-    final TableName name = TableName.valueOf(this.name.getMethodName());
+    final TableName name = TableName.valueOf(methodName);
     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
-    TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
+    assertThrows(TableExistsException.class,
+      () -> TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY));
   }
 
   /**
    * Can't disable a table if the table isn't in enabled state
    */
-  @Test(expected = TableNotEnabledException.class)
+  @Test
   public void testTableNotEnabledExceptionWithATable() throws IOException {
-    final TableName name = TableName.valueOf(this.name.getMethodName());
+    final TableName name = TableName.valueOf(methodName);
     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
     ADMIN.disableTable(name);
-    ADMIN.disableTable(name);
+    assertThrows(TableNotEnabledException.class, () -> ADMIN.disableTable(name));
   }
 
   /**
    * Can't enable a table if the table isn't in disabled state
    */
-  @Test(expected = TableNotDisabledException.class)
+  @Test
   public void testTableNotDisabledExceptionWithATable() throws IOException {
-    final TableName name = TableName.valueOf(this.name.getMethodName());
+    final TableName name = TableName.valueOf(methodName);
     try (Table t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY)) {
-      ADMIN.enableTable(name);
+      assertThrows(TableNotDisabledException.class, () -> ADMIN.enableTable(name));
     }
   }
 
   /**
    * For HADOOP-2579
    */
-  @Test(expected = TableNotFoundException.class)
+  @Test
   public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
     TableName tableName = TableName.valueOf("testTableNotFoundExceptionWithoutAnyTables");
     try (Table ht = TEST_UTIL.getConnection().getTable(tableName)) {
-      ht.get(new Get(Bytes.toBytes("e")));
+      assertThrows(TableNotFoundException.class, () -> ht.get(new Get(Bytes.toBytes("e"))));
     }
   }
 
   @Test
   public void testShouldUnassignTheRegion() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     createTableWithDefaultConf(tableName);
 
     RegionInfo info = null;
@@ -276,13 +273,12 @@ public class TestAdmin2 extends TestAdminBase {
       isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
     }
 
-    assertFalse("The region should not be present in online regions list.", isInList);
+    assertFalse(isInList, "The region should not be present in online regions list.");
   }
 
   @Test
   public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
-    final String name = this.name.getMethodName();
-    byte[] tableName = Bytes.toBytes(name);
+    byte[] tableName = Bytes.toBytes(methodName);
     createTableWithDefaultConf(tableName);
 
     RegionInfo info = null;
@@ -290,7 +286,7 @@ public class TestAdmin2 extends TestAdminBase {
     List<RegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
     for (RegionInfo regionInfo : onlineRegions) {
       if (!regionInfo.isMetaRegion()) {
-        if (regionInfo.getRegionNameAsString().contains(name)) {
+        if (regionInfo.getRegionNameAsString().contains(methodName)) {
           info = regionInfo;
           assertThrows(UnknownRegionException.class, () -> ADMIN.unassign(
             Bytes.toBytes("test,,1358563771069.acc1ad1b7962564fc3a43e5907e8db33."), true));
@@ -298,13 +294,13 @@ public class TestAdmin2 extends TestAdminBase {
       }
     }
     onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
-    assertTrue("The region should be present in online regions list.",
-      onlineRegions.contains(info));
+    assertTrue(onlineRegions.contains(info),
+      "The region should be present in online regions list.");
   }
 
   @Test
   public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     createTableWithDefaultConf(tableName);
 
     RegionInfo info = null;
@@ -326,7 +322,7 @@ public class TestAdmin2 extends TestAdminBase {
       isInList = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices()).contains(info);
     }
 
-    assertFalse("The region should not be present in online regions list.", isInList);
+    assertFalse(isInList, "The region should not be present in online regions list.");
   }
 
   private Admin createTable(TableName tableName) throws IOException {
@@ -359,7 +355,7 @@ public class TestAdmin2 extends TestAdminBase {
    */
   @Test
   public void testGetTableRegions() throws IOException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
 
     int expectedRegions = 10;
 
@@ -373,24 +369,23 @@ public class TestAdmin2 extends TestAdminBase {
 
     List<RegionInfo> RegionInfos = ADMIN.getRegions(tableName);
 
-    assertEquals(
-      "Tried to create " + expectedRegions + " regions " + "but only found " + RegionInfos.size(),
-      expectedRegions, RegionInfos.size());
+    assertEquals(expectedRegions, RegionInfos.size(),
+      "Tried to create " + expectedRegions + " regions " + "but only found " + RegionInfos.size());
   }
 
   @Test
   public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException {
     SingleProcessHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
     HMaster master = cluster.getMaster();
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     Admin localAdmin = createTable(tableName);
     List<RegionInfo> tableRegions = localAdmin.getRegions(tableName);
     RegionInfo hri = tableRegions.get(0);
     AssignmentManager am = master.getAssignmentManager();
     ServerName server = am.getRegionStates().getRegionServerOfRegion(hri);
     localAdmin.move(hri.getEncodedNameAsBytes(), server);
-    assertEquals("Current region server and region server before move should be same.", server,
-      am.getRegionStates().getRegionServerOfRegion(hri));
+    assertEquals(server, am.getRegionStates().getRegionServerOfRegion(hri),
+      "Current region server and region server before move should be same.");
   }
 
   @Test
@@ -402,7 +397,7 @@ public class TestAdmin2 extends TestAdminBase {
       v.append(className);
     }
     byte[] value = Bytes.toBytes(v.toString());
-    HRegionServer regionServer = startAndWriteData(TableName.valueOf(name.getMethodName()), value);
+    HRegionServer regionServer = startAndWriteData(TableName.valueOf(methodName), value);
     LOG.info("after writing there are "
       + AbstractFSWALProvider.getNumRolledLogFiles(regionServer.getWAL(null)) + " log files");
 
@@ -462,25 +457,23 @@ public class TestAdmin2 extends TestAdminBase {
     TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
     ADMIN.createTable(tableDescriptor);
-    Table table = TEST_UTIL.getConnection().getTable(tableName);
-
-    HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(tableName);
-    for (int i = 1; i <= 256; i++) { // 256 writes should cause 8 log rolls
-      Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
-      put.addColumn(HConstants.CATALOG_FAMILY, null, value);
-      table.put(put);
-      if (i % 32 == 0) {
-        // After every 32 writes sleep to let the log roller run
-        try {
-          Thread.sleep(2000);
-        } catch (InterruptedException e) {
-          // continue
+    try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
+      HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(tableName);
+      for (int i = 1; i <= 256; i++) { // 256 writes should cause 8 log rolls
+        Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
+        put.addColumn(HConstants.CATALOG_FAMILY, null, value);
+        table.put(put);
+        if (i % 32 == 0) {
+          // After every 32 writes sleep to let the log roller run
+          try {
+            Thread.sleep(2000);
+          } catch (InterruptedException e) {
+            // continue
+          }
         }
       }
+      return regionServer;
     }
-
-    table.close();
-    return regionServer;
   }
 
   @Test
@@ -493,7 +486,7 @@ public class TestAdmin2 extends TestAdminBase {
     // Before the fix for HBASE-6146, the below table creation was failing as the hbase:meta table
     // actually getting disabled by the disableTable() call.
     TableDescriptor tableDescriptor =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(Bytes.toBytes(name.getMethodName())))
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(Bytes.toBytes(methodName)))
         .setColumnFamily(ColumnFamilyDescriptorBuilder.of(Bytes.toBytes("cf1"))).build();
     TEST_UTIL.getAdmin().createTable(tableDescriptor);
   }
@@ -501,13 +494,13 @@ public class TestAdmin2 extends TestAdminBase {
   @Test
   public void testIsEnabledOrDisabledOnUnknownTable() throws Exception {
     try {
-      ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()));
+      ADMIN.isTableEnabled(TableName.valueOf(methodName));
       fail("Test should fail if isTableEnabled called on unknown table.");
     } catch (IOException e) {
     }
 
     try {
-      ADMIN.isTableDisabled(TableName.valueOf(name.getMethodName()));
+      ADMIN.isTableDisabled(TableName.valueOf(methodName));
       fail("Test should fail if isTableDisabled called on unknown table.");
     } catch (IOException e) {
     }
@@ -581,7 +574,7 @@ public class TestAdmin2 extends TestAdminBase {
     List<ServerName> decommissionedRegionServers = ADMIN.listDecommissionedRegionServers();
     assertTrue(decommissionedRegionServers.isEmpty());
 
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createMultiRegionTable(tableName, Bytes.toBytes("f"), 6);
 
     ArrayList<ServerName> clusterRegionServers = new ArrayList<>(
@@ -640,7 +633,7 @@ public class TestAdmin2 extends TestAdminBase {
    */
   @Test
   public void testGetRegionInfo() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     Table table = TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
     for (int i = 0; i < 100; i++) {
       table.put(new Put(Bytes.toBytes(i)).addColumn(Bytes.toBytes("f"), Bytes.toBytes("q"),
@@ -650,24 +643,24 @@ public class TestAdmin2 extends TestAdminBase {
 
     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(table.getName());
     List<HRegion> regions = rs.getRegions(tableName);
-    Assert.assertEquals(1, regions.size());
+    assertEquals(1, regions.size());
 
     HRegion region = regions.get(0);
     byte[] regionName = region.getRegionInfo().getRegionName();
     HStore store = region.getStore(Bytes.toBytes("f"));
     long expectedStoreFilesSize = store.getStorefilesSize();
-    Assert.assertNotNull(store);
-    Assert.assertEquals(expectedStoreFilesSize, store.getSize());
+    assertNotNull(store);
+    assertEquals(expectedStoreFilesSize, store.getSize());
     for (int i = 0; i < 10; i++) {
       RegionInfo ri = ProtobufUtil
         .toRegionInfo(TEST_UTIL.getAsyncConnection().getRegionServerAdmin(rs.getServerName())
           .getRegionInfo(RequestConverter.buildGetRegionInfoRequest(regionName)).get()
           .getRegionInfo());
 
-      Assert.assertEquals(region.getRegionInfo(), ri);
+      assertEquals(region.getRegionInfo(), ri);
 
       // Make sure that the store size is still the actual file system's store size.
-      Assert.assertEquals(expectedStoreFilesSize, store.getSize());
+      assertEquals(expectedStoreFilesSize, store.getSize());
     }
 
     // Test querying using the encoded name only. When encoded name passed,
@@ -699,7 +692,7 @@ public class TestAdmin2 extends TestAdminBase {
 
   @Test
   public void testTableSplitFollowedByModify() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
 
     // get the original table region count
@@ -727,7 +720,7 @@ public class TestAdmin2 extends TestAdminBase {
   @SuppressWarnings("FutureReturnValueIgnored")
   @Test
   public void testTableMergeFollowedByModify() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, new byte[][] { Bytes.toBytes("f") },
       new byte[][] { Bytes.toBytes(3) });
 
@@ -797,22 +790,22 @@ public class TestAdmin2 extends TestAdminBase {
         ++countFailedClearSlowResponse;
       }
     }
-    Assert.assertEquals(countFailedClearSlowResponse, 0);
+    assertEquals(countFailedClearSlowResponse, 0);
 
     List<LogEntry> onlineLogRecords = ADMIN.getLogEntries(new HashSet<>(serverNames), "SLOW_LOG",
       ServerType.REGION_SERVER, 100, null);
     // after cleanup of slowlog responses, total count of slowlog payloads should be 0
-    Assert.assertEquals(onlineLogRecords.size(), 0);
+    assertEquals(onlineLogRecords.size(), 0);
     List<LogEntry> balancerDecisionRecords =
       ADMIN.getLogEntries(null, "BALANCER_DECISION", ServerType.MASTER, 100, null);
-    Assert.assertEquals(balancerDecisionRecords.size(), 0);
+    assertEquals(balancerDecisionRecords.size(), 0);
   }
 
   @Test
   public void testGetRegionServers() throws Exception {
     // get all live server names
     List<ServerName> serverNames = new ArrayList<>(ADMIN.getRegionServers(true));
-    Assert.assertEquals(3, serverNames.size());
+    assertEquals(3, serverNames.size());
 
     List<ServerName> serversToDecom = new ArrayList<>();
     ServerName serverToDecommission = serverNames.get(0);
@@ -821,14 +814,14 @@ public class TestAdmin2 extends TestAdminBase {
     ADMIN.decommissionRegionServers(serversToDecom, false);
     waitForServerCommissioned(serverToDecommission, true);
 
-    Assert.assertEquals(2, ADMIN.getRegionServers(true).size());
-    Assert.assertEquals(3, ADMIN.getRegionServers(false).size());
+    assertEquals(2, ADMIN.getRegionServers(true).size());
+    assertEquals(3, ADMIN.getRegionServers(false).size());
 
     ADMIN.recommissionRegionServer(serverToDecommission, Collections.emptyList());
     waitForServerCommissioned(null, false);
 
-    Assert.assertEquals(3, ADMIN.getRegionServers(true).size());
-    Assert.assertEquals(3, ADMIN.getRegionServers(false).size());
+    assertEquals(3, ADMIN.getRegionServers(true).size());
+    assertEquals(3, ADMIN.getRegionServers(false).size());
   }
 
   private static void waitForServerCommissioned(ServerName excludeServer,
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin3.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin3.java
index cc653e0b84c..8ed75529310 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin3.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin3.java
@@ -18,19 +18,18 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.List;
 import java.util.regex.Pattern;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
@@ -45,18 +44,15 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAdmin3 extends TestAdminBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin3.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestAdmin3.class);
 
   @Test
@@ -64,7 +60,7 @@ public class TestAdmin3 extends TestAdminBase {
     final byte[] row = Bytes.toBytes("row");
     final byte[] qualifier = Bytes.toBytes("qualifier");
     final byte[] value = Bytes.toBytes("value");
-    final TableName table = TableName.valueOf(name.getMethodName());
+    final TableName table = TableName.valueOf(methodName);
     Table ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
     Put put = new Put(row);
     put.addColumn(HConstants.CATALOG_FAMILY, qualifier, value);
@@ -74,8 +70,8 @@ public class TestAdmin3 extends TestAdminBase {
     ht.get(get);
 
     ADMIN.disableTable(ht.getName());
-    assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster().getMaster()
-      .getTableStateManager().isTableState(ht.getName(), TableState.State.DISABLED));
+    assertTrue(TEST_UTIL.getHBaseCluster().getMaster().getTableStateManager()
+      .isTableState(ht.getName(), TableState.State.DISABLED), "Table must be disabled.");
     assertEquals(TableState.State.DISABLED, getStateFromMeta(table));
 
     // Test that table is disabled
@@ -101,8 +97,8 @@ public class TestAdmin3 extends TestAdminBase {
     }
     assertTrue(ok);
     ADMIN.enableTable(table);
-    assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster()
-      .getTableStateManager().isTableState(ht.getName(), TableState.State.ENABLED));
+    assertTrue(TEST_UTIL.getHBaseCluster().getMaster().getTableStateManager()
+      .isTableState(ht.getName(), TableState.State.ENABLED), "Table must be enabled.");
     assertEquals(TableState.State.ENABLED, getStateFromMeta(table));
 
     // Test that table is enabled
@@ -120,8 +116,8 @@ public class TestAdmin3 extends TestAdminBase {
     final byte[] row = Bytes.toBytes("row");
     final byte[] qualifier = Bytes.toBytes("qualifier");
     final byte[] value = Bytes.toBytes("value");
-    final TableName table1 = TableName.valueOf(name.getMethodName() + "1");
-    final TableName table2 = TableName.valueOf(name.getMethodName() + "2");
+    final TableName table1 = TableName.valueOf(methodName + "1");
+    final TableName table2 = TableName.valueOf(methodName + "2");
     Table ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
     Table ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
     Put put = new Put(row);
@@ -182,7 +178,7 @@ public class TestAdmin3 extends TestAdminBase {
    */
   @Test
   public void testEnableTableRetainAssignment() throws IOException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
       new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 },
       new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 } };
@@ -194,9 +190,8 @@ public class TestAdmin3 extends TestAdminBase {
     try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
       List<HRegionLocation> regions = l.getAllRegionLocations();
 
-      assertEquals(
-        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
-        expectedRegions, regions.size());
+      assertEquals(expectedRegions, regions.size(),
+        "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
       // Disable table.
       ADMIN.disableTable(tableName);
       // Enable table, use retain assignment to assign regions.
@@ -211,9 +206,9 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testEnableDisableAddColumnDeleteColumn() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
-    while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
+    while (!ADMIN.isTableEnabled(TableName.valueOf(methodName))) {
       Thread.sleep(10);
     }
     ADMIN.disableTable(tableName);
@@ -236,7 +231,7 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testGetTableDescriptor() throws IOException {
-    TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
+    TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName))
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1"))
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam2"))
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam3")).build();
@@ -256,7 +251,7 @@ public class TestAdmin3 extends TestAdminBase {
    */
   @Test
   public void testReadOnlyTableModify() throws IOException, InterruptedException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
 
     // Make table read only
@@ -276,9 +271,9 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testDeleteLastColumnFamily() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
-    while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
+    while (!ADMIN.isTableEnabled(TableName.valueOf(methodName))) {
       Thread.sleep(10);
     }
 
@@ -370,7 +365,7 @@ public class TestAdmin3 extends TestAdminBase {
     // Now make it so at least the table exists and then do tests against a
     // nonexistent column family -- see if we get right exceptions.
     final TableName tableName =
-      TableName.valueOf(name.getMethodName() + EnvironmentEdgeManager.currentTime());
+      TableName.valueOf(methodName + EnvironmentEdgeManager.currentTime());
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build();
     ADMIN.createTable(htd);
@@ -381,8 +376,8 @@ public class TestAdmin3 extends TestAdminBase {
       } catch (IOException e) {
         exception = e;
       }
-      assertTrue("found=" + exception.getClass().getName(),
-        exception instanceof InvalidFamilyOperationException);
+      assertTrue(exception instanceof InvalidFamilyOperationException,
+        "found=" + exception.getClass().getName());
 
       exception = null;
       try {
@@ -390,8 +385,8 @@ public class TestAdmin3 extends TestAdminBase {
       } catch (IOException e) {
         exception = e;
       }
-      assertTrue("found=" + exception.getClass().getName(),
-        exception instanceof InvalidFamilyOperationException);
+      assertTrue(exception instanceof InvalidFamilyOperationException,
+        "found=" + exception.getClass().getName());
     } finally {
       ADMIN.disableTable(tableName);
       ADMIN.deleteTable(tableName);
@@ -416,7 +411,7 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testModifyTableStoreFileTracker() throws IOException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     byte[] family = Bytes.toBytes("info");
     byte[] qual = Bytes.toBytes("q");
     byte[] row = Bytes.toBytes(0);
@@ -472,7 +467,7 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testModifyColumnFamilyStoreFileTracker() throws IOException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     byte[] family = Bytes.toBytes("info");
     byte[] qual = Bytes.toBytes("q");
     byte[] row = Bytes.toBytes(0);
@@ -523,7 +518,7 @@ public class TestAdmin3 extends TestAdminBase {
 
   @Test
   public void testModifyStoreFileTrackerError() throws IOException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     byte[] family = Bytes.toBytes("info");
     TEST_UTIL.createTable(tableName, family).close();
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin4.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin4.java
index 61e028705f8..a30d4ce3b87 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin4.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdmin4.java
@@ -19,16 +19,15 @@ package org.apache.hadoop.hbase.client;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.replication.ReplicationPeerConfig;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
@@ -36,14 +35,12 @@ import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
 import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
 import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAdmin4 extends TestAdminBase {
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin4.class);
 
   // For HBASE-24208
   @Test
@@ -63,8 +60,9 @@ public class TestAdmin4 extends TestAdminBase {
     // Stop decommissioned region server and verify it is removed from draining znode
     ServerName serverName = serversToDecommission.get(0);
     ADMIN.stopRegionServer(serverName.getHostname() + ":" + serverName.getPort());
-    assertNotEquals("RS not removed from decommissioned list", -1,
-      TEST_UTIL.waitFor(10000, () -> ADMIN.listDecommissionedRegionServers().isEmpty()));
+    assertNotEquals(-1,
+      TEST_UTIL.waitFor(10000, () -> ADMIN.listDecommissionedRegionServers().isEmpty()),
+      "RS not removed from decommissioned list");
     ZKWatcher zkw = TEST_UTIL.getZooKeeperWatcher();
     assertEquals(-1, ZKUtil.checkExists(zkw,
       ZNodePaths.joinZNode(zkw.getZNodePaths().drainingZNode, serverName.getServerName())));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
index 7b61d1ebfc3..87f1e3ae47a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAdminBase.java
@@ -17,28 +17,32 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.io.IOException;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.MetaTableAccessor;
 import org.apache.hadoop.hbase.TableName;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestInfo;
 
 public class TestAdminBase {
 
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   protected static Admin ADMIN;
 
-  @Rule
-  public TestName name = new TestName();
+  protected String methodName;
 
-  @BeforeClass
+  @BeforeEach
+  public void setUpMethodName(TestInfo info) {
+    this.methodName = info.getTestMethod().get().getName();
+  }
+
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
     TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
@@ -51,12 +55,12 @@ public class TestAdminBase {
     ADMIN = TEST_UTIL.getAdmin();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     for (TableDescriptor htd : ADMIN.listTableDescriptors()) {
       TEST_UTIL.deleteTable(htd.getTableName());
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAllowPartialScanResultCache.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAllowPartialScanResultCache.java
index 21831a67b0f..731d49aaf61 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAllowPartialScanResultCache.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAllowPartialScanResultCache.java
@@ -18,39 +18,34 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.client.TestBatchScanResultCache.createCells;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
 
 import java.io.IOException;
 import java.util.Arrays;
 import org.apache.hadoop.hbase.ExtendedCell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ SmallTests.class, ClientTests.class })
+@Tag(SmallTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAllowPartialScanResultCache {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAllowPartialScanResultCache.class);
-
   private static byte[] CF = Bytes.toBytes("cf");
 
   private AllowPartialScanResultCache resultCache;
 
-  @Before
+  @BeforeEach
   public void setUp() {
     resultCache = new AllowPartialScanResultCache();
   }
 
-  @After
+  @AfterEach
   public void tearDown() {
     resultCache.clear();
     resultCache = null;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAlwaysSetScannerId.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAlwaysSetScannerId.java
index ac1bdb60389..66b1e2f0351 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAlwaysSetScannerId.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAlwaysSetScannerId.java
@@ -17,11 +17,10 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.ipc.BlockingRpcCallback;
@@ -29,11 +28,10 @@ import org.apache.hadoop.hbase.ipc.HBaseRpcControllerImpl;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
@@ -46,13 +44,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanRespon
 /**
  * Testcase to make sure that we always set scanner id in ScanResponse. See HBASE-18000.
  */
-@Category({ RegionServerTests.class, MediumTests.class })
+@Tag(RegionServerTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestAlwaysSetScannerId {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAlwaysSetScannerId.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static final TableName TABLE_NAME = TableName.valueOf("test");
@@ -69,7 +64,7 @@ public class TestAlwaysSetScannerId {
 
   private static ClientProtos.ClientService.Interface STUB;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.startMiniCluster(1);
     try (Table table = UTIL.createTable(TABLE_NAME, CF)) {
@@ -83,7 +78,7 @@ public class TestAlwaysSetScannerId {
     STUB = CONN.getRegionServerStub(UTIL.getHBaseCluster().getRegionServer(0).getServerName());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAppendFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAppendFromClientSide.java
index 6d8164dbde8..25e05ebb795 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAppendFromClientSide.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAppendFromClientSide.java
@@ -17,58 +17,49 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import java.io.IOException;
-import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.CellBuilderType;
 import org.apache.hadoop.hbase.ExtendedCellBuilderFactory;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 
 /**
  * Run Append tests that use the HBase clients;
  */
-@Category(MediumTests.class)
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAppendFromClientSide {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAppendFromClientSide.class);
-
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static byte[] ROW = Bytes.toBytes("testRow");
   private static byte[] FAMILY = Bytes.toBytes("testFamily");
   private static byte[] QUALIFIER = Bytes.toBytes("testQualifier");
-  @Rule
-  public TestName name = new TestName();
 
-  @BeforeClass
+  @BeforeAll
   public static void beforeClass() throws Exception {
-    Configuration conf = TEST_UTIL.getConfiguration();
     TEST_UTIL.startMiniCluster(3);
   }
 
-  @AfterClass
+  @AfterAll
   public static void afterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
   @Test
-  public void testAppendWithCustomTimestamp() throws IOException {
-    TableName TABLENAME = TableName.valueOf(name.getMethodName());
+  public void testAppendWithCustomTimestamp(TestInfo testInfo) throws IOException {
+    TableName TABLENAME = TableName.valueOf(testInfo.getTestMethod().get().getName());
     Table table = TEST_UTIL.createTable(TABLENAME, FAMILY);
     long timestamp = 999;
     Append append = new Append(ROW);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBuilder.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBuilder.java
index 06d9c0314da..fae2a599799 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBuilder.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncAdminBuilder.java
@@ -19,17 +19,16 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR;
 import static org.apache.hadoop.hbase.client.AsyncConnectionConfiguration.START_LOG_ERRORS_AFTER_COUNT_KEY;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Supplier;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import java.util.stream.Stream;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
@@ -40,34 +39,27 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@RunWith(Parameterized.class)
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate
 public class TestAsyncAdminBuilder {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncAdminBuilder.class);
-
-  private static final Logger LOG = LoggerFactory.getLogger(TestAsyncAdminBuilder.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static AsyncConnection ASYNC_CONN;
 
-  @Parameter
-  public Supplier<AsyncAdminBuilder> getAdminBuilder;
+  private final Supplier<AsyncAdminBuilder> getAdminBuilder;
+
+  public TestAsyncAdminBuilder(Supplier<AsyncAdminBuilder> getAdminBuilder) {
+    this.getAdminBuilder = getAdminBuilder;
+  }
 
   private static AsyncAdminBuilder getRawAsyncAdminBuilder() {
     return ASYNC_CONN.getAdminBuilder();
@@ -77,17 +69,17 @@ public class TestAsyncAdminBuilder {
     return ASYNC_CONN.getAdminBuilder(ForkJoinPool.commonPool());
   }
 
-  @Parameters
-  public static List<Object[]> params() {
-    return Arrays.asList(new Supplier<?>[] { TestAsyncAdminBuilder::getRawAsyncAdminBuilder },
-      new Supplier<?>[] { TestAsyncAdminBuilder::getAsyncAdminBuilder });
+  public static Stream<Arguments> parameters() {
+    return Stream.of(
+      Arguments.of((Supplier<AsyncAdminBuilder>) TestAsyncAdminBuilder::getRawAsyncAdminBuilder),
+      Arguments.of((Supplier<AsyncAdminBuilder>) TestAsyncAdminBuilder::getAsyncAdminBuilder));
   }
 
   private static final int DEFAULT_RPC_TIMEOUT = 10000;
   private static final int DEFAULT_OPERATION_TIMEOUT = 30000;
   private static final int DEFAULT_RETRIES_NUMBER = 2;
 
-  @Before
+  @BeforeEach
   public void setUp() throws Exception {
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, DEFAULT_RPC_TIMEOUT);
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT,
@@ -97,13 +89,13 @@ public class TestAsyncAdminBuilder {
     TEST_UTIL.getConfiguration().setInt(START_LOG_ERRORS_AFTER_COUNT_KEY, 0);
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Test
+  @TestTemplate
   public void testRpcTimeout() throws Exception {
     TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
       TestRpcTimeoutCoprocessor.class.getName());
@@ -126,7 +118,7 @@ public class TestAsyncAdminBuilder {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testOperationTimeout() throws Exception {
     // set retry number to 100 to make sure that this test only be affected by operation timeout
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 100);
@@ -153,7 +145,7 @@ public class TestAsyncAdminBuilder {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testMaxRetries() throws Exception {
     // set operation timeout to 300s to make sure that this test only be affected by retry number
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, 300000);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBufferMutator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBufferMutator.java
index a6a6333cd08..6030a4e3180 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBufferMutator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncBufferMutator.java
@@ -19,12 +19,12 @@ package org.apache.hadoop.hbase.client;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -35,28 +35,23 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.io.netty.util.HashedWheelTimer;
 import org.apache.hbase.thirdparty.io.netty.util.Timeout;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncBufferMutator {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncBufferMutator.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -73,7 +68,7 @@ public class TestAsyncBufferMutator {
 
   private static AsyncConnection CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.startMiniCluster(1);
     TEST_UTIL.createTable(TABLE_NAME, CF);
@@ -82,7 +77,7 @@ public class TestAsyncBufferMutator {
     Bytes.random(VALUE);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     CONN.close();
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForRpcThrottling.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForRpcThrottling.java
index 3455b397566..3fdf3353bce 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForRpcThrottling.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForRpcThrottling.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,7 +31,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.RegionTooBusyException;
@@ -42,11 +41,10 @@ import org.apache.hadoop.hbase.regionserver.RSRpcServices;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;
@@ -54,13 +52,10 @@ import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
 
 import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncClientPauseForRpcThrottling {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncClientPauseForRpcThrottling.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("RpcThrottling");
@@ -134,13 +129,12 @@ public class TestAsyncClientPauseForRpcThrottling {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
-    assertTrue(
+    assertTrue(MAX_MULTIPLIER_EXPECTATION < HConstants.RETRY_BACKOFF[RETRY_COUNT],
       "The MAX_MULTIPLIER_EXPECTATION must be less than HConstants.RETRY_BACKOFF[RETRY_COUNT] "
         + "in order for our tests to adequately verify that we aren't "
-        + "multiplying throttled pauses based on the retry count.",
-      MAX_MULTIPLIER_EXPECTATION < HConstants.RETRY_BACKOFF[RETRY_COUNT]);
+        + "multiplying throttled pauses based on the retry count.");
 
     UTIL.getConfiguration().setLong(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
     UTIL.startMiniCluster(1);
@@ -161,7 +155,7 @@ public class TestAsyncClientPauseForRpcThrottling {
     CONN = ConnectionFactory.createAsyncConnection(conf).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     UTIL.getAdmin().disableTable(TABLE_NAME);
     UTIL.getAdmin().deleteTable(TABLE_NAME);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForServerOverloaded.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForServerOverloaded.java
index 799395c6733..caba3627a78 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForServerOverloaded.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPauseForServerOverloaded.java
@@ -18,9 +18,9 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.client.AsyncConnectionConfiguration.HBASE_CLIENT_PAUSE_FOR_SERVER_OVERLOADED;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -33,7 +33,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Abortable;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -49,24 +48,20 @@ import org.apache.hadoop.hbase.regionserver.SimpleRpcSchedulerFactory;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncClientPauseForServerOverloaded {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncClientPauseForServerOverloaded.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("ServerOverloaded");
@@ -149,7 +144,7 @@ public class TestAsyncClientPauseForServerOverloaded {
 
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.getConfiguration().setLong(HConstants.HBASE_CLIENT_PAUSE, 10);
     UTIL.getConfiguration().set("hbase.ipc.server.callqueue.type", "pluggable");
@@ -164,13 +159,13 @@ public class TestAsyncClientPauseForServerOverloaded {
     CONN = ConnectionFactory.createAsyncConnection(conf).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUpBeforeTest() throws IOException {
     try (Table table = UTIL.createTable(TABLE_NAME, FAMILY)) {
       for (int i = 0; i < 100; i++) {
@@ -180,7 +175,7 @@ public class TestAsyncClientPauseForServerOverloaded {
     MODE = FailMode.CALL_QUEUE_TOO_BIG;
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() throws IOException {
     for (FailMode mode : FailMode.values()) {
       mode.invoked.clear();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPushback.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPushback.java
index 88b9431338b..72fd53da85b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPushback.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncClientPushback.java
@@ -21,38 +21,33 @@ import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicLong;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.client.backoff.ClientBackoffPolicy;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.FutureUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncClientPushback extends ClientPushbackTestBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncClientPushback.class);
-
   private AsyncConnectionImpl conn;
 
   private AsyncBufferedMutator mutator;
 
-  @Before
+  @BeforeEach
   public void setUp() throws Exception {
     conn =
       (AsyncConnectionImpl) ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get();
     mutator = conn.getBufferedMutator(tableName);
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws IOException {
     Closeables.close(mutator, true);
     Closeables.close(conn, true);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java
index 0bfbd18eb32..978204b116e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocator.java
@@ -23,23 +23,23 @@ import static org.apache.hadoop.hbase.HConstants.EMPTY_START_ROW;
 import static org.apache.hadoop.hbase.client.RegionReplicaTestHelper.testLocator;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.CatalogReplicaMode;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.MetaTableAccessor;
@@ -56,28 +56,22 @@ import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 
 import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
-@RunWith(Parameterized.class)
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate(name = "[{index}]: metaReplicaMode = {0}")
 public class TestAsyncNonMetaRegionLocator {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncNonMetaRegionLocator.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static final TableName TABLE_NAME = TableName.valueOf("async");
@@ -91,10 +85,13 @@ public class TestAsyncNonMetaRegionLocator {
   private AsyncConnectionImpl conn;
   private AsyncNonMetaRegionLocator locator;
 
-  @Parameter
-  public CatalogReplicaMode metaReplicaMode;
+  private final CatalogReplicaMode metaReplicaMode;
+
+  public TestAsyncNonMetaRegionLocator(CatalogReplicaMode metaReplicaMode) {
+    this.metaReplicaMode = metaReplicaMode;
+  }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     // Enable hbase:meta replication.
@@ -117,12 +114,12 @@ public class TestAsyncNonMetaRegionLocator {
     }
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUpBeforeTest() throws InterruptedException, ExecutionException, IOException {
     Configuration c = new Configuration(TEST_UTIL.getConfiguration());
     // Enable meta replica LoadBalance mode for this connection.
@@ -134,7 +131,7 @@ public class TestAsyncNonMetaRegionLocator {
     locator = new AsyncNonMetaRegionLocator(conn, AsyncConnectionImpl.RETRY_TIMER);
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() throws IOException {
     Admin admin = TEST_UTIL.getAdmin();
     if (admin.tableExists(TABLE_NAME)) {
@@ -146,10 +143,9 @@ public class TestAsyncNonMetaRegionLocator {
     Closeables.close(conn, true);
   }
 
-  @Parameterized.Parameters
-  public static Collection<Object[]> paramAbstractTestRegionLocatoreters() {
-    return Arrays
-      .asList(new Object[][] { { CatalogReplicaMode.NONE }, { CatalogReplicaMode.LOAD_BALANCE } });
+  public static Stream<Arguments> parameters() {
+    return Stream.of(Arguments.of(CatalogReplicaMode.NONE),
+      Arguments.of(CatalogReplicaMode.LOAD_BALANCE));
   }
 
   private void createSingleRegionTable() throws IOException, InterruptedException {
@@ -164,7 +160,7 @@ public class TestAsyncNonMetaRegionLocator {
       .thenApply(RegionLocations::getDefaultRegionLocation);
   }
 
-  @Test
+  @TestTemplate
   public void testNoTable() throws InterruptedException {
     for (RegionLocateType locateType : RegionLocateType.values()) {
       try {
@@ -175,7 +171,7 @@ public class TestAsyncNonMetaRegionLocator {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testDisableTable() throws IOException, InterruptedException {
     createSingleRegionTable();
     TEST_UTIL.getAdmin().disableTable(TABLE_NAME);
@@ -197,7 +193,7 @@ public class TestAsyncNonMetaRegionLocator {
     assertEquals(serverName, loc.getServerName());
   }
 
-  @Test
+  @TestTemplate
   public void testSingleRegionTable() throws IOException, InterruptedException, ExecutionException {
     createSingleRegionTable();
     ServerName serverName = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName();
@@ -243,7 +239,7 @@ public class TestAsyncNonMetaRegionLocator {
     return serverNames;
   }
 
-  @Test
+  @TestTemplate
   public void testMultiRegionTable() throws IOException, InterruptedException {
     createMultiRegionTable();
     byte[][] startKeys = getStartKeys();
@@ -283,7 +279,7 @@ public class TestAsyncNonMetaRegionLocator {
       }));
   }
 
-  @Test
+  @TestTemplate
   public void testRegionMove() throws IOException, InterruptedException, ExecutionException {
     createSingleRegionTable();
     ServerName serverName = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName();
@@ -314,7 +310,7 @@ public class TestAsyncNonMetaRegionLocator {
 
   // usually locate after will return the same result, so we add a test to make it return different
   // result.
-  @Test
+  @TestTemplate
   public void testLocateAfter() throws IOException, InterruptedException, ExecutionException {
     byte[] row = Bytes.toBytes("1");
     byte[] splitKey = Arrays.copyOf(row, 2);
@@ -339,7 +335,7 @@ public class TestAsyncNonMetaRegionLocator {
   }
 
   // For HBASE-17402
-  @Test
+  @TestTemplate
   public void testConcurrentLocate() throws IOException, InterruptedException, ExecutionException {
     createMultiRegionTable();
     byte[][] startKeys = getStartKeys();
@@ -358,7 +354,7 @@ public class TestAsyncNonMetaRegionLocator {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testReload() throws Exception {
     createSingleRegionTable();
     ServerName serverName = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME).getServerName();
@@ -416,7 +412,7 @@ public class TestAsyncNonMetaRegionLocator {
   }
 
   // Testcase for HBASE-20822
-  @Test
+  @TestTemplate
   public void testLocateBeforeLastRegion()
     throws IOException, InterruptedException, ExecutionException {
     createMultiRegionTable();
@@ -427,7 +423,7 @@ public class TestAsyncNonMetaRegionLocator {
     assertArrayEquals(loc.getRegion().getEndKey(), EMPTY_END_ROW);
   }
 
-  @Test
+  @TestTemplate
   public void testRegionReplicas() throws Exception {
     TEST_UTIL.getAdmin().createTable(TableDescriptorBuilder.newBuilder(TABLE_NAME)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)).setRegionReplication(3).build());
@@ -450,7 +446,7 @@ public class TestAsyncNonMetaRegionLocator {
   }
 
   // Testcase for HBASE-21961
-  @Test
+  @TestTemplate
   public void testLocateBeforeInOnlyRegion() throws IOException, InterruptedException {
     createSingleRegionTable();
     HRegionLocation loc =
@@ -460,7 +456,7 @@ public class TestAsyncNonMetaRegionLocator {
     assertArrayEquals(loc.getRegion().getEndKey(), EMPTY_END_ROW);
   }
 
-  @Test
+  @TestTemplate
   public void testConcurrentUpdateCachedLocationOnError() throws Exception {
     createSingleRegionTable();
     HRegionLocation loc =
@@ -469,7 +465,7 @@ public class TestAsyncNonMetaRegionLocator {
       .forEach(i -> locator.updateCachedLocationOnError(loc, new NotServingRegionException()));
   }
 
-  @Test
+  @TestTemplate
   public void testCacheLocationWhenGetAllLocations() throws Exception {
     createMultiRegionTable();
     AsyncConnectionImpl conn = (AsyncConnectionImpl) ConnectionFactory
@@ -481,7 +477,7 @@ public class TestAsyncNonMetaRegionLocator {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testDoNotCacheLocationWithNullServerNameWhenGetAllLocations() throws Exception {
     createMultiRegionTable();
     AsyncConnectionImpl conn = (AsyncConnectionImpl) ConnectionFactory
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
index 4529c07dfd1..a1412e00039 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncNonMetaRegionLocatorConcurrenyLimit.java
@@ -22,8 +22,8 @@ import static org.apache.hadoop.hbase.client.AsyncNonMetaRegionLocator.MAX_CONCU
 import static org.apache.hadoop.hbase.client.ConnectionUtils.isEmptyStartRow;
 import static org.apache.hadoop.hbase.client.ConnectionUtils.isEmptyStopRow;
 import static org.apache.hadoop.hbase.coprocessor.CoprocessorHost.REGION_COPROCESSOR_CONF_KEY;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.List;
@@ -33,7 +33,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.IntStream;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.RegionLocations;
@@ -48,21 +47,17 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncNonMetaRegionLocatorConcurrenyLimit.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -117,7 +112,7 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     conf.set(REGION_COPROCESSOR_CONF_KEY, CountingRegionObserver.class.getName());
@@ -135,7 +130,7 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
     TEST_UTIL.waitTableAvailable(TABLE_NAME);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
@@ -169,7 +164,7 @@ public class TestAsyncNonMetaRegionLocatorConcurrenyLimit {
               RegionReplicaUtil.DEFAULT_REPLICA_ID, RegionLocateType.CURRENT, false))
             .collect(toList());
     assertLocs(futures);
-    assertTrue("max allowed is " + MAX_ALLOWED + " but actual is " + MAX_CONCURRENCY.get(),
-      MAX_CONCURRENCY.get() <= MAX_ALLOWED);
+    assertTrue(MAX_CONCURRENCY.get() <= MAX_ALLOWED,
+      "max allowed is " + MAX_ALLOWED + " but actual is " + MAX_CONCURRENCY.get());
   }
 }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionLocator.java
index 5e858eb8d9d..3fa3cffcf5a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionLocator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncRegionLocator.java
@@ -22,9 +22,9 @@ import static org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_META_OPERATION_TIM
 import static org.apache.hadoop.hbase.coprocessor.CoprocessorHost.REGION_COPROCESSOR_CONF_KEY;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.Optional;
@@ -33,7 +33,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.TableName;
@@ -48,22 +47,18 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncRegionLocator {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncRegionLocator.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -91,7 +86,7 @@ public class TestAsyncRegionLocator {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     conf.set(REGION_COPROCESSOR_CONF_KEY, SleepRegionObserver.class.getName());
@@ -106,13 +101,13 @@ public class TestAsyncRegionLocator {
     LOCATOR = CONN.getLocator();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() {
     LOCATOR.clearCache();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncResultScannerCursor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncResultScannerCursor.java
index 3ac059fa847..5a9ba147480 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncResultScannerCursor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncResultScannerCursor.java
@@ -18,33 +18,30 @@
 package org.apache.hadoop.hbase.client;
 
 import java.util.concurrent.ForkJoinPool;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncResultScannerCursor extends AbstractTestResultScannerCursor {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncResultScannerCursor.class);
-
   private static AsyncConnection CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
-    AbstractTestScanCursor.setUpBeforeClass();
+    startCluster();
     CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
   }
 
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     if (CONN != null) {
       CONN.close();
     }
-    AbstractTestScanCursor.tearDownAfterClass();
+    stopCluster();
   }
 
   @Override
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSingleRequestRpcRetryingCaller.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSingleRequestRpcRetryingCaller.java
index baa4ee74ade..b3f9e17227a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSingleRequestRpcRetryingCaller.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncSingleRequestRpcRetryingCaller.java
@@ -19,9 +19,9 @@ package org.apache.hadoop.hbase.client;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
@@ -29,7 +29,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.TableName;
@@ -37,21 +36,17 @@ import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncSingleRequestRpcRetryingCaller {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncSingleRequestRpcRetryingCaller.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -66,7 +61,7 @@ public class TestAsyncSingleRequestRpcRetryingCaller {
 
   private static AsyncConnectionImpl CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(2);
     TEST_UTIL.getAdmin().balancerSwitch(false, true);
@@ -78,7 +73,7 @@ public class TestAsyncSingleRequestRpcRetryingCaller {
       registry.getClusterId().get(), null, User.getCurrent());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTable.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTable.java
index 3966da78b82..4c982629ffd 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTable.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTable.java
@@ -20,12 +20,13 @@ package org.apache.hadoop.hbase.client;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
@@ -42,8 +43,9 @@ import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 import org.apache.hadoop.hbase.CompareOperator;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.TableNotEnabledException;
@@ -59,29 +61,20 @@ import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.Pair;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@RunWith(Parameterized.class)
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate
 public class TestAsyncTable {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTable.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -96,13 +89,15 @@ public class TestAsyncTable {
 
   private static AsyncConnection ASYNC_CONN;
 
-  @Rule
-  public TestName testName = new TestName();
+  private static final AtomicInteger ROW_COUNTER = new AtomicInteger(0);
 
   private byte[] row;
 
-  @Parameter
-  public Supplier<AsyncTable<?>> getTable;
+  private final Supplier<AsyncTable<?>> getTable;
+
+  public TestAsyncTable(Supplier<AsyncTable<?>> getTable) {
+    this.getTable = getTable;
+  }
 
   private static AsyncTable<?> getRawTable() {
     return ASYNC_CONN.getTable(TABLE_NAME);
@@ -112,13 +107,12 @@ public class TestAsyncTable {
     return ASYNC_CONN.getTable(TABLE_NAME, ForkJoinPool.commonPool());
   }
 
-  @Parameters
-  public static List<Object[]> params() {
-    return Arrays.asList(new Supplier<?>[] { TestAsyncTable::getRawTable },
-      new Supplier<?>[] { TestAsyncTable::getTable });
+  public static Stream<Arguments> parameters() {
+    return Stream.of(Arguments.of((Supplier<AsyncTable<?>>) TestAsyncTable::getRawTable),
+      Arguments.of((Supplier<AsyncTable<?>>) TestAsyncTable::getTable));
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.getConfiguration().setInt(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY,
       MAX_KEY_VALUE_SIZE);
@@ -129,22 +123,22 @@ public class TestAsyncTable {
     assertFalse(ASYNC_CONN.isClosed());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     assertTrue(ASYNC_CONN.isClosed());
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUp() throws IOException, InterruptedException, ExecutionException {
-    row = Bytes.toBytes(testName.getMethodName().replaceAll("[^0-9A-Za-z]", "_"));
+    row = Bytes.toBytes("row" + ROW_COUNTER.getAndIncrement());
     if (ASYNC_CONN.getAdmin().isTableDisabled(TABLE_NAME).get()) {
       ASYNC_CONN.getAdmin().enableTable(TABLE_NAME).get();
     }
   }
 
-  @Test
+  @TestTemplate
   public void testSimple() throws Exception {
     AsyncTable<?> table = getTable.get();
     table.put(new Put(row).addColumn(FAMILY, QUALIFIER, VALUE)).get();
@@ -162,7 +156,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testSimpleMultiple() throws Exception {
     AsyncTable<?> table = getTable.get();
     int count = 100;
@@ -207,7 +201,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testIncrement() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
     int count = 100;
@@ -225,7 +219,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testAppend() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
     int count = 10;
@@ -249,7 +243,7 @@ public class TestAsyncTable {
     assertArrayEquals(IntStream.range(0, count).toArray(), actual);
   }
 
-  @Test
+  @TestTemplate
   public void testMutateRow() throws InterruptedException, ExecutionException, IOException {
     AsyncTable<?> table = getTable.get();
     RowMutations mutation = new RowMutations(row);
@@ -281,7 +275,7 @@ public class TestAsyncTable {
   // Tests for old checkAndMutate API
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndPutForOldApi() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
@@ -305,7 +299,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndDeleteForOldApi() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
@@ -344,7 +338,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateForOldApi() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
@@ -389,7 +383,7 @@ public class TestAsyncTable {
     });
   }
 
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithTimeRangeForOldApi() throws Exception {
     AsyncTable<?> table = getTable.get();
@@ -430,7 +424,7 @@ public class TestAsyncTable {
     assertTrue(ok);
   }
 
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithSingleFilterForOldApi() throws Throwable {
     AsyncTable<?> table = getTable.get();
@@ -490,7 +484,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).get());
   }
 
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithMultipleFiltersForOldApi() throws Throwable {
     AsyncTable<?> table = getTable.get();
@@ -562,7 +556,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).get());
   }
 
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithTimestampFilterForOldApi() throws Throwable {
     AsyncTable<?> table = getTable.get();
@@ -594,7 +588,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).get());
   }
 
-  @Test
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithFilterAndTimeRangeForOldApi() throws Throwable {
     AsyncTable<?> table = getTable.get();
@@ -626,17 +620,19 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).get());
   }
 
-  @Test(expected = NullPointerException.class)
+  @TestTemplate
   @Deprecated
   public void testCheckAndMutateWithoutConditionForOldApi() {
-    getTable.get().checkAndMutate(row, FAMILY)
-      .thenPut(new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));
+    assertThrows(NullPointerException.class, () -> {
+      getTable.get().checkAndMutate(row, FAMILY)
+        .thenPut(new Put(row).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));
+    });
   }
 
   // Tests for new CheckAndMutate API
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testCheckAndPut() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
     AtomicInteger successCount = new AtomicInteger(0);
@@ -661,7 +657,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testCheckAndDelete() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
     int count = 10;
@@ -701,7 +697,7 @@ public class TestAsyncTable {
   }
 
   @SuppressWarnings("FutureReturnValueIgnored")
-  @Test
+  @TestTemplate
   public void testCheckAndMutate() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = getTable.get();
     int count = 10;
@@ -749,7 +745,7 @@ public class TestAsyncTable {
     });
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateWithTimeRange() throws Exception {
     AsyncTable<?> table = getTable.get();
     final long ts = EnvironmentEdgeManager.currentTime() / 2;
@@ -797,7 +793,7 @@ public class TestAsyncTable {
     assertNull(result.getResult());
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateWithSingleFilter() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -859,7 +855,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).get());
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateWithMultipleFilters() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -932,7 +928,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("A"))).get());
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateWithTimestampFilter() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -965,7 +961,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).get());
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateWithFilterAndTimeRange() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -996,7 +992,7 @@ public class TestAsyncTable {
     assertFalse(table.exists(new Get(row).addColumn(FAMILY, Bytes.toBytes("C"))).get());
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndIncrement() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -1055,7 +1051,7 @@ public class TestAsyncTable {
     assertEquals(3, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("B"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndAppend() throws Throwable {
     AsyncTable<?> table = getTable.get();
 
@@ -1118,7 +1114,7 @@ public class TestAsyncTable {
     assertEquals("bbb", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndRowMutations() throws Throwable {
     final byte[] q1 = Bytes.toBytes("q1");
     final byte[] q2 = Bytes.toBytes("q2");
@@ -1172,7 +1168,7 @@ public class TestAsyncTable {
 
   // Tests for batch version of checkAndMutate
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateBatch() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1257,7 +1253,7 @@ public class TestAsyncTable {
     assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateBatch2() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1339,7 +1335,7 @@ public class TestAsyncTable {
     assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateBatchWithFilter() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1450,7 +1446,7 @@ public class TestAsyncTable {
     assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndMutateBatchWithFilterAndTimeRange() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1497,7 +1493,7 @@ public class TestAsyncTable {
     assertEquals("f", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("F"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndIncrementBatch() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1534,7 +1530,7 @@ public class TestAsyncTable {
     assertEquals(0, Bytes.toLong(result.getValue(FAMILY, Bytes.toBytes("D"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndAppendBatch() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1572,7 +1568,7 @@ public class TestAsyncTable {
     assertEquals("d", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("D"))));
   }
 
-  @Test
+  @TestTemplate
   public void testCheckAndRowMutationsBatch() throws Throwable {
     AsyncTable<?> table = getTable.get();
     byte[] row2 = Bytes.toBytes(Bytes.toString(row) + "2");
@@ -1628,7 +1624,7 @@ public class TestAsyncTable {
     assertEquals("h", Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("H"))));
   }
 
-  @Test
+  @TestTemplate
   public void testDisabled() throws InterruptedException, ExecutionException {
     ASYNC_CONN.getAdmin().disableTable(TABLE_NAME).get();
     try {
@@ -1641,7 +1637,7 @@ public class TestAsyncTable {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutation() throws Exception {
     Consumer<Mutation> executeMutation = mutation -> {
       if (mutation instanceof Put) {
@@ -1683,7 +1679,7 @@ public class TestAsyncTable {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutationInRowMutations() throws IOException {
     final byte[] row = Bytes.toBytes(0);
 
@@ -1716,7 +1712,7 @@ public class TestAsyncTable {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutationInRowMutationsInCheckAndMutate() throws IOException {
     final byte[] row = Bytes.toBytes(0);
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java
index ee01dde3a92..305025254aa 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi.java
@@ -44,6 +44,8 @@ import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.TestTemplate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Class to test asynchronous table admin operations.
@@ -56,6 +58,8 @@ import org.junit.jupiter.api.TestTemplate;
 @HBaseParameterizedTestTemplate(name = "{index}: policy = {0}")
 public class TestAsyncTableAdminApi extends TestAsyncAdminBase {
 
+  private static final Logger LOG = LoggerFactory.getLogger(TestAsyncTableAdminApi.class);
+
   public TestAsyncTableAdminApi(Supplier<AsyncAdmin> admin) {
     super(admin);
   }
@@ -146,7 +150,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase {
 
     assertEquals(expectedRegions, regions.size(),
       "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
-    System.err.println("Found " + regions.size() + " regions");
+    LOG.info("Found " + regions.size() + " regions");
 
     RegionInfo hri;
     hris = regions.iterator();
@@ -198,7 +202,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase {
     regions = ClientMetaTableAccessor.getTableHRegionLocations(metaTable, tableName2).get();
     assertEquals(expectedRegions, regions.size(),
       "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
-    System.err.println("Found " + regions.size() + " regions");
+    LOG.info("Found " + regions.size() + " regions");
 
     hris = regions.iterator();
     hri = hris.next().getRegion();
@@ -245,7 +249,7 @@ public class TestAsyncTableAdminApi extends TestAsyncAdminBase {
     regions = ClientMetaTableAccessor.getTableHRegionLocations(metaTable, tableName3).get();
     assertEquals(expectedRegions, regions.size(),
       "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size());
-    System.err.println("Found " + regions.size() + " regions");
+    LOG.info("Found " + regions.size() + " regions");
 
     // Try an invalid case where there are duplicate split keys
     splitKeys = new byte[][] { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 },
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi2.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi2.java
index 779b666c0f3..105909836b3 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi2.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableAdminApi2.java
@@ -19,8 +19,8 @@ package org.apache.hadoop.hbase.client;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
 
 import java.util.Optional;
 import java.util.Set;
@@ -35,7 +35,6 @@ import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.FSTableDescriptors;
-import org.junit.Assert;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Tag;
@@ -67,11 +66,8 @@ public class TestAsyncTableAdminApi2 extends TestAsyncAdminBase {
 
   @TestTemplate
   public void testDisableCatalogTable() throws Exception {
-    try {
-      this.admin.disableTable(TableName.META_TABLE_NAME).join();
-      fail("Expected to throw ConstraintException");
-    } catch (Exception e) {
-    }
+    assertThrows(Exception.class, () -> this.admin.disableTable(TableName.META_TABLE_NAME).join(),
+      "Expected to throw ConstraintException");
     // Before the fix for HBASE-6146, the below table creation was failing as the hbase:meta table
     // actually getting disabled by the disableTable() call.
     createTableWithDefaultConf(tableName);
@@ -106,13 +102,11 @@ public class TestAsyncTableAdminApi2 extends TestAsyncAdminBase {
     admin.addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of(FAMILY_1)).join();
     verifyTableDescriptor(tableName, FAMILY_0, FAMILY_1);
 
-    try {
-      // Add same column family again - expect failure
-      this.admin.addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of(FAMILY_1)).join();
-      Assert.fail("Delete a non-exist column family should fail");
-    } catch (Exception e) {
-      // Expected.
-    }
+    // Add same column family again - expect failure
+    assertThrows(
+      Exception.class, () -> this.admin
+        .addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of(FAMILY_1)).join(),
+      "Delete a non-exist column family should fail");
   }
 
   @TestTemplate
@@ -146,15 +140,12 @@ public class TestAsyncTableAdminApi2 extends TestAsyncAdminBase {
     verifyTableDescriptor(tableName, FAMILY_0);
 
     int newBlockSize = 2 * blockSize;
-    cfd = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY_1).setBlocksize(newBlockSize).build();
+    ColumnFamilyDescriptor cfd2 =
+      ColumnFamilyDescriptorBuilder.newBuilder(FAMILY_1).setBlocksize(newBlockSize).build();
 
     // Modify a column family that is not in the table.
-    try {
-      admin.modifyColumnFamily(tableName, cfd).join();
-      Assert.fail("Modify a non-exist column family should fail");
-    } catch (Exception e) {
-      // Expected.
-    }
+    assertThrows(Exception.class, () -> admin.modifyColumnFamily(tableName, cfd2).join(),
+      "Modify a non-exist column family should fail");
   }
 
   @TestTemplate
@@ -188,13 +179,9 @@ public class TestAsyncTableAdminApi2 extends TestAsyncAdminBase {
     admin.deleteColumnFamily(tableName, FAMILY_1).join();
     verifyTableDescriptor(tableName, FAMILY_0);
 
-    try {
-      // Delete again - expect failure
-      admin.deleteColumnFamily(tableName, FAMILY_1).join();
-      Assert.fail("Delete a non-exist column family should fail");
-    } catch (Exception e) {
-      // Expected.
-    }
+    // Delete again - expect failure
+    assertThrows(Exception.class, () -> admin.deleteColumnFamily(tableName, FAMILY_1).join(),
+      "Delete a non-exist column family should fail");
   }
 
   private void verifyTableDescriptor(final TableName tableName, final byte[]... families)
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatch.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatch.java
index 86c39153f60..075d664d251 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatch.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatch.java
@@ -20,12 +20,12 @@ package org.apache.hadoop.hbase.client;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.io.UncheckedIOException;
@@ -42,8 +42,9 @@ import java.util.concurrent.TimeoutException;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
@@ -54,26 +55,19 @@ import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-@Category({ LargeTests.class, ClientTests.class })
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
+
+@HBaseParameterizedTestTemplate(name = "{index}: type={0}")
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableBatch {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableBatch.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -91,11 +85,11 @@ public class TestAsyncTableBatch {
 
   private static int MAX_KEY_VALUE_SIZE = 64 * 1024;
 
-  @Parameter(0)
-  public String tableType;
+  private final Function<TableName, AsyncTable<?>> tableGetter;
 
-  @Parameter(1)
-  public Function<TableName, AsyncTable<?>> tableGetter;
+  public TestAsyncTableBatch(String tableType, Function<TableName, AsyncTable<?>> tableGetter) {
+    this.tableGetter = tableGetter;
+  }
 
   private static AsyncTable<?> getRawTable(TableName tableName) {
     return CONN.getTable(tableName);
@@ -105,15 +99,13 @@ public class TestAsyncTableBatch {
     return CONN.getTable(tableName, ForkJoinPool.commonPool());
   }
 
-  @Parameters(name = "{index}: type={0}")
-  public static List<Object[]> params() {
+  public static Stream<Arguments> parameters() {
     Function<TableName, AsyncTable<?>> rawTableGetter = TestAsyncTableBatch::getRawTable;
     Function<TableName, AsyncTable<?>> tableGetter = TestAsyncTableBatch::getTable;
-    return Arrays.asList(new Object[] { "raw", rawTableGetter },
-      new Object[] { "normal", tableGetter });
+    return Stream.of(Arguments.of("raw", rawTableGetter), Arguments.of("normal", tableGetter));
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.getConfiguration().setInt(ConnectionConfiguration.MAX_KEYVALUE_SIZE_KEY,
       MAX_KEY_VALUE_SIZE);
@@ -125,19 +117,19 @@ public class TestAsyncTableBatch {
     CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     CONN.close();
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUpBeforeTest() throws IOException, InterruptedException {
     TEST_UTIL.createTable(TABLE_NAME, FAMILY, SPLIT_KEYS);
     TEST_UTIL.waitTableAvailable(TABLE_NAME);
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() throws IOException {
     Admin admin = TEST_UTIL.getAdmin();
     if (admin.isTableEnabled(TABLE_NAME)) {
@@ -150,7 +142,7 @@ public class TestAsyncTableBatch {
     return Bytes.toBytes(String.format("%03d", i));
   }
 
-  @Test
+  @TestTemplate
   public void test()
     throws InterruptedException, ExecutionException, IOException, TimeoutException {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
@@ -193,7 +185,7 @@ public class TestAsyncTableBatch {
     results.forEach(r -> assertTrue(r.isEmpty()));
   }
 
-  @Test
+  @TestTemplate
   public void testWithRegionServerFailover() throws Exception {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
     table.putAll(IntStream.range(0, COUNT)
@@ -218,7 +210,7 @@ public class TestAsyncTableBatch {
     results.forEach(r -> assertTrue(r.isEmpty()));
   }
 
-  @Test
+  @TestTemplate
   public void testMixed() throws InterruptedException, ExecutionException, IOException {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
     table.putAll(IntStream.range(0, 7)
@@ -273,7 +265,7 @@ public class TestAsyncTableBatch {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testPartialSuccess() throws IOException, InterruptedException, ExecutionException {
     Admin admin = TEST_UTIL.getAdmin();
     TableDescriptor htd = TableDescriptorBuilder.newBuilder(admin.getDescriptor(TABLE_NAME))
@@ -295,7 +287,7 @@ public class TestAsyncTableBatch {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testPartialSuccessOnSameRegion() throws InterruptedException, ExecutionException {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
     List<CompletableFuture<Object>> futures = table.batch(Arrays.asList(
@@ -316,7 +308,7 @@ public class TestAsyncTableBatch {
       Bytes.toString(table.get(new Get(Bytes.toBytes("put"))).get().getValue(FAMILY, CQ)));
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutation() {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
 
@@ -350,7 +342,7 @@ public class TestAsyncTableBatch {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutationInRowMutations() throws IOException {
     final byte[] row = Bytes.toBytes(0);
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
@@ -385,7 +377,7 @@ public class TestAsyncTableBatch {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testInvalidMutationInRowMutationsInCheckAndMutate() throws IOException {
     final byte[] row = Bytes.toBytes(0);
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
@@ -421,7 +413,7 @@ public class TestAsyncTableBatch {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testWithCheckAndMutate() throws Exception {
     AsyncTable<?> table = tableGetter.apply(TABLE_NAME);
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatchRetryImmediately.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatchRetryImmediately.java
index 05ed7bf1bad..bf1e9d1c480 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatchRetryImmediately.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableBatchRetryImmediately.java
@@ -17,14 +17,13 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -32,19 +31,15 @@ import org.apache.hadoop.hbase.logging.Log4jUtils;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableBatchRetryImmediately {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableBatchRetryImmediately.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -61,7 +56,7 @@ public class TestAsyncTableBatchRetryImmediately {
 
   private static String LOG_LEVEL;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     // disable the debug log to avoid flooding the output
     LOG_LEVEL = Log4jUtils.getEffectiveLevel(AsyncRegionLocatorHelper.class.getName());
@@ -78,7 +73,7 @@ public class TestAsyncTableBatchRetryImmediately {
     CONN = ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     if (LOG_LEVEL != null) {
       Log4jUtils.setLogLevel(AsyncRegionLocatorHelper.class.getName(), LOG_LEVEL);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreaded.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreaded.java
index ff250fd8a35..25802267ddf 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreaded.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreaded.java
@@ -19,7 +19,7 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT;
 import static org.apache.hadoop.hbase.io.ByteBuffAllocator.MAX_BUFFER_COUNT_KEY;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -35,7 +35,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.MemoryCompactionPolicy;
 import org.apache.hadoop.hbase.ServerName;
@@ -48,12 +47,10 @@ import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.RetryCounter;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,13 +60,10 @@ import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFacto
 /**
  * Will split the table, and move region randomly when testing.
  */
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableGetMultiThreaded {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableGetMultiThreaded.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestAsyncTableGetMultiThreaded.class);
 
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
@@ -85,7 +79,7 @@ public class TestAsyncTableGetMultiThreaded {
 
   private static byte[][] SPLIT_KEYS;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     setUp(MemoryCompactionPolicy.NONE);
   }
@@ -113,7 +107,7 @@ public class TestAsyncTableGetMultiThreaded {
       .get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
@@ -212,7 +206,7 @@ public class TestAsyncTableGetMultiThreaded {
     }
     List<LogEntry> balancerDecisionRecords =
       admin.getLogEntries(null, "BALANCER_DECISION", ServerType.MASTER, 2, null);
-    Assert.assertEquals(balancerDecisionRecords.size(), 2);
+    assertEquals(balancerDecisionRecords.size(), 2);
     LOG.info("====== Read test finished, shutdown thread pool ======");
     stop.set(true);
     executor.shutdown();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithBasicCompaction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithBasicCompaction.java
index 29bb4c76af7..dfc1bf2c387 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithBasicCompaction.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithBasicCompaction.java
@@ -17,25 +17,20 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.MemoryCompactionPolicy;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
 
-@Ignore // Can't move hbase:meta off master server in AMv2. TODO.
-@Category({ LargeTests.class, ClientTests.class })
+@Disabled // Can't move hbase:meta off master server in AMv2. TODO.
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableGetMultiThreadedWithBasicCompaction
   extends TestAsyncTableGetMultiThreaded {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableGetMultiThreadedWithBasicCompaction.class);
-
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     setUp(MemoryCompactionPolicy.BASIC);
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithEagerCompaction.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithEagerCompaction.java
index da70b199111..67b0d696353 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithEagerCompaction.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableGetMultiThreadedWithEagerCompaction.java
@@ -17,25 +17,20 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.MemoryCompactionPolicy;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Tag;
 
-@Ignore // Can't move hbase:meta off master server in AMv2. TODO.
-@Category({ LargeTests.class, ClientTests.class })
+@Disabled // Can't move hbase:meta off master server in AMv2. TODO.
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableGetMultiThreadedWithEagerCompaction
   extends TestAsyncTableGetMultiThreaded {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableGetMultiThreadedWithEagerCompaction.class);
-
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     setUp(MemoryCompactionPolicy.EAGER);
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocatePrefetch.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocatePrefetch.java
index a9f9a276294..ae1815ba344 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocatePrefetch.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocatePrefetch.java
@@ -17,30 +17,25 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.concurrent.ExecutionException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableLocatePrefetch {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableLocatePrefetch.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -51,7 +46,7 @@ public class TestAsyncTableLocatePrefetch {
 
   private static AsyncNonMetaRegionLocator LOCATOR;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.getConfiguration().setInt(AsyncNonMetaRegionLocator.LOCATE_PREFETCH_LIMIT, 100);
     TEST_UTIL.startMiniCluster(3);
@@ -62,7 +57,7 @@ public class TestAsyncTableLocatePrefetch {
       new AsyncNonMetaRegionLocator((AsyncConnectionImpl) CONN, AsyncConnectionImpl.RETRY_TIMER);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
@@ -77,8 +72,8 @@ public class TestAsyncTableLocatePrefetch {
     // confirm that the locations of all the regions have been cached.
     assertNotNull(LOCATOR.getRegionLocationInCache(TABLE_NAME, Bytes.toBytes("aaa")));
     for (byte[] row : HBaseTestingUtil.KEYS_FOR_HBA_CREATE_TABLE) {
-      assertNotNull("Expected location to not be null for " + Bytes.toStringBinary(row),
-        LOCATOR.getRegionLocationInCache(TABLE_NAME, row));
+      assertNotNull(LOCATOR.getRegionLocationInCache(TABLE_NAME, row),
+        "Expected location to not be null for " + Bytes.toStringBinary(row));
     }
   }
 }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocateRegionForDeletedTable.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocateRegionForDeletedTable.java
index c43498682ac..29e8517357f 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocateRegionForDeletedTable.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableLocateRegionForDeletedTable.java
@@ -17,21 +17,19 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
@@ -39,13 +37,10 @@ import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
  * Fix an infinite loop in {@link AsyncNonMetaRegionLocator}, see the comments on HBASE-21943 for
  * more details.
  */
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableLocateRegionForDeletedTable {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableLocateRegionForDeletedTable.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -58,7 +53,7 @@ public class TestAsyncTableLocateRegionForDeletedTable {
 
   private static AsyncConnection ASYNC_CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(3);
     TEST_UTIL.createTable(TABLE_NAME, FAMILY);
@@ -68,7 +63,7 @@ public class TestAsyncTableLocateRegionForDeletedTable {
     assertFalse(ASYNC_CONN.isClosed());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     assertTrue(ASYNC_CONN.isClosed());
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableNoncedRetry.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableNoncedRetry.java
index b3889880c5e..1e8410f402e 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableNoncedRetry.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableNoncedRetry.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -28,7 +28,6 @@ import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
@@ -40,24 +39,19 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableNoncedRetry {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableNoncedRetry.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static final TableName TABLE_NAME = TableName.valueOf("async");
@@ -74,9 +68,6 @@ public class TestAsyncTableNoncedRetry {
 
   private static AsyncConnection ASYNC_CONN;
 
-  @Rule
-  public TestName testName = new TestName();
-
   private byte[] row;
 
   private static final AtomicInteger CALLED = new AtomicInteger();
@@ -105,7 +96,7 @@ public class TestAsyncTableNoncedRetry {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(1);
     TEST_UTIL.getAdmin()
@@ -116,15 +107,15 @@ public class TestAsyncTableNoncedRetry {
     ASYNC_CONN = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
-  public void setUp() throws IOException, InterruptedException {
-    row = Bytes.toBytes(testName.getMethodName().replaceAll("[^0-9A-Za-z]", "_"));
+  @BeforeEach
+  public void setUp(TestInfo info) throws IOException, InterruptedException {
+    row = Bytes.toBytes(info.getTestMethod().get().getName().replaceAll("[^0-9A-Za-z]", "_"));
     CALLED.set(0);
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableQueryMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableQueryMetrics.java
index 56f36896c2c..72591c19d79 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableQueryMetrics.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableQueryMetrics.java
@@ -17,11 +17,14 @@
  */
 package org.apache.hadoop.hbase.client;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.regionserver.MetricsRegionServer;
@@ -31,22 +34,17 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.JVMClusterUtil;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableQueryMetrics {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableQueryMetrics.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static final TableName TABLE_NAME = TableName.valueOf("ResultMetrics");
@@ -63,7 +61,7 @@ public class TestAsyncTableQueryMetrics {
 
   private static AsyncConnection CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.startMiniCluster(3);
     // Create 3 rows in the table, with rowkeys starting with "zzz*" so that
@@ -76,7 +74,7 @@ public class TestAsyncTableQueryMetrics {
     CONN.getAdmin().flush(TABLE_NAME).join();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
@@ -91,8 +89,8 @@ public class TestAsyncTableQueryMetrics {
     long bbs = getClusterBlockBytesScanned();
     Result result = CONN.getTable(TABLE_NAME).get(g1).get();
     bbs += result.getMetrics().getBlockBytesScanned();
-    Assert.assertNotNull(result.getMetrics());
-    Assert.assertEquals(getClusterBlockBytesScanned(), bbs);
+    assertNotNull(result.getMetrics());
+    assertEquals(getClusterBlockBytesScanned(), bbs);
 
     // Test multigets
     Get g2 = new Get(ROW_2);
@@ -105,11 +103,11 @@ public class TestAsyncTableQueryMetrics {
 
     for (CompletableFuture<Result> future : futures) {
       result = future.join();
-      Assert.assertNotNull(result.getMetrics());
+      assertNotNull(result.getMetrics());
       bbs += result.getMetrics().getBlockBytesScanned();
     }
 
-    Assert.assertEquals(getClusterBlockBytesScanned(), bbs);
+    assertEquals(getClusterBlockBytesScanned(), bbs);
   }
 
   @Test
@@ -118,13 +116,13 @@ public class TestAsyncTableQueryMetrics {
     Get g1 = new Get(ROW_1);
 
     Result result = CONN.getTable(TABLE_NAME).get(g1).get();
-    Assert.assertNull(result.getMetrics());
+    assertNull(result.getMetrics());
 
     // Test multigets
     Get g2 = new Get(ROW_2);
     Get g3 = new Get(ROW_3);
     List<CompletableFuture<Result>> futures = CONN.getTable(TABLE_NAME).get(List.of(g1, g2, g3));
-    futures.forEach(f -> Assert.assertNull(f.join().getMetrics()));
+    futures.forEach(f -> assertNull(f.join().getMetrics()));
 
   }
 
@@ -136,9 +134,9 @@ public class TestAsyncTableQueryMetrics {
     long bbs = getClusterBlockBytesScanned();
     try (ResultScanner scanner = CONN.getTable(TABLE_NAME).getScanner(scan)) {
       for (Result result : scanner) {
-        Assert.assertNotNull(result.getMetrics());
+        assertNotNull(result.getMetrics());
         bbs += result.getMetrics().getBlockBytesScanned();
-        Assert.assertEquals(getClusterBlockBytesScanned(), bbs);
+        assertEquals(getClusterBlockBytesScanned(), bbs);
       }
     }
   }
@@ -149,7 +147,7 @@ public class TestAsyncTableQueryMetrics {
 
     try (ResultScanner scanner = CONN.getTable(TABLE_NAME).getScanner(scan)) {
       for (Result result : scanner) {
-        Assert.assertNull(result.getMetrics());
+        assertNull(result.getMetrics());
       }
     }
   }
@@ -163,8 +161,8 @@ public class TestAsyncTableQueryMetrics {
     CheckAndMutateResult result = CONN.getTable(TABLE_NAME).checkAndMutate(cam).join();
     QueryMetrics metrics = result.getMetrics();
 
-    Assert.assertNotNull(metrics);
-    Assert.assertEquals(getClusterBlockBytesScanned(), bbs + metrics.getBlockBytesScanned());
+    assertNotNull(metrics);
+    assertEquals(getClusterBlockBytesScanned(), bbs + metrics.getBlockBytesScanned());
 
     bbs = getClusterBlockBytesScanned();
     List<CheckAndMutate> batch = new ArrayList<>();
@@ -177,7 +175,7 @@ public class TestAsyncTableQueryMetrics {
     List<Object> res = CONN.getTable(TABLE_NAME).batchAll(batch).join();
     long totalBbs = res.stream()
       .mapToLong(r -> ((CheckAndMutateResult) r).getMetrics().getBlockBytesScanned()).sum();
-    Assert.assertEquals(getClusterBlockBytesScanned(), bbs + totalBbs);
+    assertEquals(getClusterBlockBytesScanned(), bbs + totalBbs);
 
     bbs = getClusterBlockBytesScanned();
 
@@ -187,7 +185,7 @@ public class TestAsyncTableQueryMetrics {
 
     totalBbs = futures.stream().map(CompletableFuture::join)
       .mapToLong(r -> ((CheckAndMutateResult) r).getMetrics().getBlockBytesScanned()).sum();
-    Assert.assertEquals(getClusterBlockBytesScanned(), bbs + totalBbs);
+    assertEquals(getClusterBlockBytesScanned(), bbs + totalBbs);
   }
 
   @Test
@@ -198,7 +196,7 @@ public class TestAsyncTableQueryMetrics {
     CheckAndMutateResult result = CONN.getTable(TABLE_NAME).checkAndMutate(cam).join();
     QueryMetrics metrics = result.getMetrics();
 
-    Assert.assertNull(metrics);
+    assertNull(metrics);
 
     List<CheckAndMutate> batch = new ArrayList<>();
     batch.add(cam);
@@ -209,7 +207,7 @@ public class TestAsyncTableQueryMetrics {
 
     List<Object> res = CONN.getTable(TABLE_NAME).batchAll(batch).join();
     for (Object r : res) {
-      Assert.assertNull(((CheckAndMutateResult) r).getMetrics());
+      assertNull(((CheckAndMutateResult) r).getMetrics());
     }
 
     // flush to force fetch from disk
@@ -218,7 +216,7 @@ public class TestAsyncTableQueryMetrics {
 
     for (CompletableFuture<Object> future : futures) {
       Object r = future.join();
-      Assert.assertNull(((CheckAndMutateResult) r).getMetrics());
+      assertNull(((CheckAndMutateResult) r).getMetrics());
     }
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRSCrashPublish.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRSCrashPublish.java
index c98c13deb66..f6be32d8ec5 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRSCrashPublish.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRSCrashPublish.java
@@ -17,12 +17,11 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import java.io.IOException;
 import java.util.concurrent.ExecutionException;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.ServerName;
@@ -30,29 +29,25 @@ import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 // Categorized as a large test so not run as part of general 'test' suite (which is small
 // and mediums). This test fails if networking is odd -- say if you are connected to a
 // VPN... See HBASE-23850
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableRSCrashPublish {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableRSCrashPublish.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("Publish");
 
   private static byte[] FAMILY = Bytes.toBytes("family");
 
-  @BeforeClass
+  @BeforeAll
   public static void beforeClass() throws Exception {
     UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true);
     /*
@@ -72,7 +67,7 @@ public class TestAsyncTableRSCrashPublish {
     UTIL.waitTableAvailable(TABLE_NAME);
   }
 
-  @AfterClass
+  @AfterAll
   public static void afterClass() throws Exception {
     UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionLocator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionLocator.java
index 2b65473380f..7f29fa5f665 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionLocator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionLocator.java
@@ -21,35 +21,30 @@ import static org.apache.hadoop.hbase.util.FutureUtils.get;
 
 import java.io.IOException;
 import java.util.List;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Pair;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableRegionLocator extends AbstractTestRegionLocator {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableRegionLocator.class);
-
   private static AsyncConnection CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     startClusterAndCreateTable();
     CONN = ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasGet.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasGet.java
index 910e6bbcbb1..497594e47fa 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasGet.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasGet.java
@@ -17,26 +17,25 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import java.util.function.Supplier;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
 
-@RunWith(Parameterized.class)
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate
 public class TestAsyncTableRegionReplicasGet extends AbstractTestAsyncTableRegionReplicasRead {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableRegionReplicasGet.class);
+  public TestAsyncTableRegionReplicasGet(Supplier<AsyncTable<?>> getTable) {
+    super(getTable);
+  }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     startClusterAndCreateTable();
     AsyncTable<?> table = ASYNC_CONN.getTable(TABLE_NAME);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasScan.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasScan.java
index b38fc4b9b6e..6e4a7ece9a3 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasScan.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableRegionReplicasScan.java
@@ -17,30 +17,29 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import java.util.function.Supplier;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
 
-@RunWith(Parameterized.class)
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate
 public class TestAsyncTableRegionReplicasScan extends AbstractTestAsyncTableRegionReplicasRead {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableRegionReplicasScan.class);
-
   private static int ROW_COUNT = 1000;
 
+  public TestAsyncTableRegionReplicasScan(Supplier<AsyncTable<?>> getTable) {
+    super(getTable);
+  }
+
   private static byte[] getRow(int i) {
     return Bytes.toBytes(String.format("%s-%03d", Bytes.toString(ROW), i));
   }
@@ -49,7 +48,7 @@ public class TestAsyncTableRegionReplicasScan extends AbstractTestAsyncTableRegi
     return Bytes.toBytes(String.format("%s-%03d", Bytes.toString(VALUE), i));
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     startClusterAndCreateTable();
     AsyncTable<?> table = ASYNC_CONN.getTable(TABLE_NAME);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanException.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanException.java
index 3729296a922..a5408ab06a1 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanException.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanException.java
@@ -17,18 +17,17 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.io.IOException;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
@@ -40,22 +39,18 @@ import org.apache.hadoop.hbase.regionserver.InternalScanner;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableScanException {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableScanException.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("scan");
@@ -99,7 +94,7 @@ public class TestAsyncTableScanException {
 
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.startMiniCluster(1);
     UTIL.getAdmin()
@@ -114,13 +109,13 @@ public class TestAsyncTableScanException {
     CONN = ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUpBeforeTest() {
     REQ_COUNT.set(0);
     ERROR_AT = 0;
@@ -128,12 +123,12 @@ public class TestAsyncTableScanException {
     DO_NOT_RETRY = false;
   }
 
-  @Test(expected = DoNotRetryIOException.class)
+  @Test
   public void testDoNotRetryIOException() throws IOException {
     ERROR_AT = 1;
     DO_NOT_RETRY = true;
     try (ResultScanner scanner = CONN.getTable(TABLE_NAME).getScanner(FAMILY)) {
-      scanner.next();
+      assertThrows(DoNotRetryIOException.class, () -> scanner.next());
     }
   }
 
@@ -142,13 +137,11 @@ public class TestAsyncTableScanException {
     ERROR = true;
     try (ResultScanner scanner =
       CONN.getTableBuilder(TABLE_NAME).setMaxAttempts(3).build().getScanner(FAMILY)) {
-      scanner.next();
-      fail();
-    } catch (RetriesExhaustedException e) {
-      // expected
+      RetriesExhaustedException e =
+        assertThrows(RetriesExhaustedException.class, () -> scanner.next());
       assertThat(e.getCause(), instanceOf(ScannerResetException.class));
     }
-    assertTrue(REQ_COUNT.get() >= 3);
+    assertThat(REQ_COUNT.get(), greaterThanOrEqualTo(3));
   }
 
   private void count() throws IOException {
@@ -167,7 +160,7 @@ public class TestAsyncTableScanException {
     count();
     // we should at least request 1 time otherwise the error will not be triggered, and then we
     // need at least one more request to get the remaining results.
-    assertTrue(REQ_COUNT.get() >= 2);
+    assertThat(REQ_COUNT.get(), greaterThanOrEqualTo(2));
   }
 
   @Test
@@ -176,6 +169,6 @@ public class TestAsyncTableScanException {
     count();
     // we should at least request 2 times otherwise the error will not be triggered, and then we
     // need at least one more request to get the remaining results.
-    assertTrue(REQ_COUNT.get() >= 3);
+    assertThat(REQ_COUNT.get(), greaterThanOrEqualTo(3));
   }
 }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanMetricsWithScannerSuspending.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanMetricsWithScannerSuspending.java
index 6a355b08365..be15bf1a43d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanMetricsWithScannerSuspending.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanMetricsWithScannerSuspending.java
@@ -22,9 +22,10 @@ import static org.apache.hadoop.hbase.client.metrics.ScanMetrics.BYTES_IN_RESULT
 import static org.apache.hadoop.hbase.client.metrics.ScanMetrics.REGIONS_SCANNED_METRIC_NAME;
 import static org.apache.hadoop.hbase.client.metrics.ScanMetrics.RPC_CALLS_METRIC_NAME;
 import static org.apache.hadoop.hbase.client.metrics.ServerSideScanMetrics.COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -32,7 +33,6 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.Waiter;
@@ -41,22 +41,17 @@ import org.apache.hadoop.hbase.client.metrics.ScanMetricsRegionInfo;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableScanMetricsWithScannerSuspending {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableScanMetricsWithScannerSuspending.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static final TableName TABLE_NAME =
@@ -70,7 +65,7 @@ public class TestAsyncTableScanMetricsWithScannerSuspending {
 
   private static AsyncConnection CONN;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.startMiniCluster(1);
     // Create 3 rows in the table, with rowkeys starting with "xxx*", "yyy*" and "zzz*" so that
@@ -83,7 +78,7 @@ public class TestAsyncTableScanMetricsWithScannerSuspending {
     CONN = ConnectionFactory.createAsyncConnection(UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     UTIL.shutdownMiniCluster();
@@ -131,7 +126,7 @@ public class TestAsyncTableScanMetricsWithScannerSuspending {
       assertEquals(i, rowsReadCounter.get());
       results.add(scanner.next());
     }
-    Assert.assertNull(scanner.next());
+    assertNull(scanner.next());
 
     // Assert on overall scan metrics and scan metrics by region
     ScanMetrics scanMetrics = scanner.getScanMetrics();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanRenewLease.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanRenewLease.java
index 04e500fc8e3..ceeb0f90ad9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanRenewLease.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScanRenewLease.java
@@ -17,13 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -31,19 +30,15 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableScanRenewLease {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableScanRenewLease.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -58,7 +53,7 @@ public class TestAsyncTableScanRenewLease {
 
   private static int SCANNER_LEASE_TIMEOUT_PERIOD_MS = 5000;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD,
       SCANNER_LEASE_TIMEOUT_PERIOD_MS);
@@ -71,7 +66,7 @@ public class TestAsyncTableScanRenewLease {
       .collect(Collectors.toList())).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     CONN.close();
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScannerCloseWhileSuspending.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScannerCloseWhileSuspending.java
index 4f52e6c8c13..e02a41c64c9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScannerCloseWhileSuspending.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableScannerCloseWhileSuspending.java
@@ -17,33 +17,28 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ForkJoinPool;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.Waiter.ExplainingPredicate;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAsyncTableScannerCloseWhileSuspending {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableScannerCloseWhileSuspending.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("async");
@@ -56,7 +51,7 @@ public class TestAsyncTableScannerCloseWhileSuspending {
 
   private static AsyncTable<?> TABLE;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.startMiniCluster(1);
     TEST_UTIL.createTable(TABLE_NAME, FAMILY);
@@ -67,7 +62,7 @@ public class TestAsyncTableScannerCloseWhileSuspending {
       .collect(Collectors.toList())).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     CONN.close();
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableUseMetaReplicas.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableUseMetaReplicas.java
index 18c53a49de7..8cd96291991 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableUseMetaReplicas.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAsyncTableUseMetaReplicas.java
@@ -17,14 +17,14 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -39,20 +39,16 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FutureUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Category({ ClientTests.class, MediumTests.class })
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestAsyncTableUseMetaReplicas {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAsyncTableUseMetaReplicas.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("Replica");
@@ -87,7 +83,7 @@ public class TestAsyncTableUseMetaReplicas {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     Configuration conf = UTIL.getConfiguration();
     conf.setInt(StorefileRefresherChore.REGIONSERVER_STOREFILE_REFRESH_PERIOD, 1000);
@@ -107,12 +103,12 @@ public class TestAsyncTableUseMetaReplicas {
     Thread.sleep(2000);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     UTIL.shutdownMiniCluster();
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() {
     // make sure we do not mess up cleanup code.
     FAIL_PRIMARY_SCAN = false;
@@ -131,10 +127,10 @@ public class TestAsyncTableUseMetaReplicas {
     }
   }
 
-  @Test(expected = RetriesExhaustedException.class)
+  @Test
   public void testNotUseMetaReplicas()
     throws IOException, InterruptedException, ExecutionException {
-    testRead(false);
+    assertThrows(RetriesExhaustedException.class, () -> testRead(false));
   }
 
   @Test
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAvoidCellReferencesIntoShippedBlocks.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAvoidCellReferencesIntoShippedBlocks.java
index e1f21502d90..31ce704bf1b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAvoidCellReferencesIntoShippedBlocks.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestAvoidCellReferencesIntoShippedBlocks.java
@@ -17,8 +17,8 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -31,7 +31,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparatorImpl;
 import org.apache.hadoop.hbase.ExtendedCell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -59,23 +58,19 @@ import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 
 import org.apache.hbase.thirdparty.com.google.common.collect.Iterables;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestAvoidCellReferencesIntoShippedBlocks {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestAvoidCellReferencesIntoShippedBlocks.class);
-
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   static byte[][] ROWS = new byte[2][];
   private static byte[] ROW = Bytes.toBytes("testRow");
@@ -93,14 +88,14 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
   private CountDownLatch latch = new CountDownLatch(1);
   private static CountDownLatch compactReadLatch = new CountDownLatch(1);
   private static AtomicBoolean doScan = new AtomicBoolean(false);
+  private String methodName;
 
-  @Rule
-  public TestName name = new TestName();
+  @BeforeEach
+  public void setUp(TestInfo testInfo) throws Exception {
+    this.methodName = testInfo.getTestMethod().get().getName();
+  }
 
-  /**
-   * @throws java.lang.Exception
-   */
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     ROWS[0] = ROW;
     ROWS[1] = ROW1;
@@ -123,14 +118,14 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
   @Test
   public void testHBase16372InCompactionWritePath() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     // Create a table with block size as 1024
     final Table table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
       CompactorRegionObserver.class.getName());
@@ -197,7 +192,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
       try (ResultScanner scanner = table.getScanner(s)) {
         count = Iterables.size(scanner);
       }
-      assertEquals("Count all the rows ", 6, count);
+      assertEquals(6, count, "Count all the rows ");
       // all the cache is loaded
       // trigger a major compaction
       ScannerThread scannerThread = new ScannerThread(table, cache);
@@ -208,7 +203,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
       try (ResultScanner scanner = table.getScanner(s)) {
         count = Iterables.size(scanner);
       }
-      assertEquals("Count all the rows ", 6, count);
+      assertEquals(6, count, "Count all the rows ");
     } finally {
       table.close();
     }
@@ -297,7 +292,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
 
   @Test
   public void testHBASE16372InReadPath() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     // Create a table with block size as 1024
     try (Table table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024, null)) {
       // get the block cache and region
@@ -356,7 +351,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
       try (ResultScanner scanner = table.getScanner(s)) {
         count = Iterables.size(scanner);
       }
-      assertEquals("Count all the rows ", 6, count);
+      assertEquals(6, count, "Count all the rows ");
 
       // Scan from cache
       s = new Scan();
@@ -394,7 +389,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
               iterator.next();
               refBlockCount++;
             }
-            assertEquals("One block should be there ", 1, refBlockCount);
+            assertEquals(1, refBlockCount, "One block should be there ");
             // Rescan to prepopulate the data
             // cache this row.
             Scan s1 = new Scan();
@@ -406,7 +401,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
 
             try (ResultScanner scanner = table.getScanner(s1)) {
               int count = Iterables.size(scanner);
-              assertEquals("Count the rows", 2, count);
+              assertEquals(2, count, "Count the rows");
               int newBlockRefCount = 0;
               List<BlockCacheKey> newCacheList = new ArrayList<>();
               while (true) {
@@ -441,7 +436,7 @@ public class TestAvoidCellReferencesIntoShippedBlocks {
           }
         }
       }
-      assertEquals("Count should give all rows ", 10, count);
+      assertEquals(10, count, "Count should give all rows ");
     }
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBatchScanResultCache.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBatchScanResultCache.java
index dd0074ae691..e555fbdb6ee 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBatchScanResultCache.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBatchScanResultCache.java
@@ -17,40 +17,35 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
 
 import java.io.IOException;
 import java.util.Arrays;
 import org.apache.hadoop.hbase.ExtendedCell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ SmallTests.class, ClientTests.class })
+@Tag(SmallTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestBatchScanResultCache {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestBatchScanResultCache.class);
-
   private static byte[] CF = Bytes.toBytes("cf");
 
   private BatchScanResultCache resultCache;
 
-  @Before
+  @BeforeEach
   public void setUp() {
     resultCache = new BatchScanResultCache(4);
   }
 
-  @After
+  @AfterEach
   public void tearDown() {
     resultCache.clear();
     resultCache = null;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBlockEvictionFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBlockEvictionFromClient.java
index 1f9bbd3aa7a..ddc97902fc4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBlockEvictionFromClient.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBlockEvictionFromClient.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -36,7 +36,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.ExtendedCell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.ServerName;
@@ -63,28 +62,22 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.hbase.thirdparty.com.google.common.collect.Iterables;
 
-@Category({ LargeTests.class, ClientTests.class })
-@SuppressWarnings("deprecation")
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestBlockEvictionFromClient {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestBlockEvictionFromClient.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestBlockEvictionFromClient.class);
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   static byte[][] ROWS = new byte[2][];
@@ -104,14 +97,17 @@ public class TestBlockEvictionFromClient {
   private static CountDownLatch getLatch;
   private static CountDownLatch compactionLatch;
   private static CountDownLatch exceptionLatch;
+  private String methodName;
 
-  @Rule
-  public TestName name = new TestName();
+  @BeforeEach
+  public void setUp(TestInfo testInfo) throws Exception {
+    this.methodName = testInfo.getTestMethod().get().getName();
+    CustomInnerRegionObserver.waitForGets.set(false);
+    CustomInnerRegionObserver.countOfNext.set(0);
+    CustomInnerRegionObserver.countOfGets.set(0);
+  }
 
-  /**
-   * @throws java.lang.Exception
-   */
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     ROWS[0] = ROW;
     ROWS[1] = ROW1;
@@ -132,7 +128,7 @@ public class TestBlockEvictionFromClient {
   /**
    * @throws java.lang.Exception
    */
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
@@ -140,17 +136,7 @@ public class TestBlockEvictionFromClient {
   /**
    * @throws java.lang.Exception
    */
-  @Before
-  public void setUp() throws Exception {
-    CustomInnerRegionObserver.waitForGets.set(false);
-    CustomInnerRegionObserver.countOfNext.set(0);
-    CustomInnerRegionObserver.countOfGets.set(0);
-  }
-
-  /**
-   * @throws java.lang.Exception
-   */
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     if (latch != null) {
       while (latch.getCount() > 0) {
@@ -186,7 +172,7 @@ public class TestBlockEvictionFromClient {
     Table table = null;
     try {
       latch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
         CustomInnerRegionObserver.class.getName());
@@ -240,12 +226,12 @@ public class TestBlockEvictionFromClient {
       iterator = cache.iterator();
       iterateBlockCache(cache, iterator);
       // flush, one new block
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       region.flush(true);
       iterator = cache.iterator();
       iterateBlockCache(cache, iterator);
       // compact, net minus two blocks, two hits, no misses
-      System.out.println("Compacting");
+      LOG.info("Compacting");
       assertEquals(2, store.getStorefilesCount());
       store.triggerMajorCompaction();
       region.compact(true);
@@ -274,7 +260,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(2);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -291,7 +277,7 @@ public class TestBlockEvictionFromClient {
 
       insertData(table);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       region.flush(true);
       // Create three sets of scan
@@ -313,7 +299,7 @@ public class TestBlockEvictionFromClient {
       for (ScanThread thread : scanThreads) {
         thread.join();
       }
-      System.out.println("Scans should have returned the bloks");
+      LOG.info("Scans should have returned the bloks");
       // Check with either true or false
       CustomInnerRegionObserver.waitForGets.set(false);
       // The scan should also have released the blocks by now
@@ -332,7 +318,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(1);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -361,7 +347,7 @@ public class TestBlockEvictionFromClient {
       table.put(put);
       region.flush(true);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       CustomInnerRegionObserver.waitForGets.set(true);
       // Create three sets of gets
@@ -376,7 +362,7 @@ public class TestBlockEvictionFromClient {
       // giving some time for the block to be decremented
       checkForBlockEviction(cache, true, false);
       getLatch.countDown();
-      System.out.println("Gets should have returned the bloks");
+      LOG.info("Gets should have returned the bloks");
     } finally {
       if (table != null) {
         table.close();
@@ -393,7 +379,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(1);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -425,7 +411,7 @@ public class TestBlockEvictionFromClient {
       table.put(put);
       region.flush(true);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       CustomInnerRegionObserver.waitForGets.set(true);
       // Create three sets of gets
@@ -447,7 +433,7 @@ public class TestBlockEvictionFromClient {
         }
         if (refCount != 0) {
           // Blocks will be with count 3
-          System.out.println("The refCount is " + refCount);
+          LOG.info("The refCount is " + refCount);
           assertEquals(NO_OF_THREADS, refCount);
           usedBlocksFound = true;
           noOfBlocksWithRef++;
@@ -465,7 +451,7 @@ public class TestBlockEvictionFromClient {
       // giving some time for the block to be decremented
       checkForBlockEviction(cache, true, false);
       getLatch.countDown();
-      System.out.println("Gets should have returned the bloks");
+      LOG.info("Gets should have returned the bloks");
     } finally {
       if (table != null) {
         table.close();
@@ -480,7 +466,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(1);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       byte[][] fams = new byte[10][];
@@ -519,7 +505,7 @@ public class TestBlockEvictionFromClient {
       table.put(put);
       region.flush(true);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       CustomInnerRegionObserver.waitForGets.set(true);
       // Create three sets of gets
@@ -541,7 +527,7 @@ public class TestBlockEvictionFromClient {
         }
         if (refCount != 0) {
           // Blocks will be with count 3
-          System.out.println("The refCount is " + refCount);
+          LOG.info("The refCount is " + refCount);
           assertEquals(NO_OF_THREADS, refCount);
           usedBlocksFound = true;
           noOfBlocksWithRef++;
@@ -559,7 +545,7 @@ public class TestBlockEvictionFromClient {
       // giving some time for the block to be decremented
       checkForBlockEviction(cache, true, false);
       getLatch.countDown();
-      System.out.println("Gets should have returned the bloks");
+      LOG.info("Gets should have returned the bloks");
     } finally {
       if (table != null) {
         table.close();
@@ -571,7 +557,7 @@ public class TestBlockEvictionFromClient {
   public void testBlockRefCountAfterSplits() throws IOException, InterruptedException {
     Table table = null;
     try {
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       TableDescriptor desc = TEST_UTIL.createTableDescriptor(tableName);
       // This test expects rpc refcount of cached data blocks to be 0 after split. After split,
       // two daughter regions are opened and a compaction is scheduled to get rid of reference
@@ -638,7 +624,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(2);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -667,7 +653,7 @@ public class TestBlockEvictionFromClient {
       table.put(put);
       region.flush(true);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       CustomInnerRegionObserver.waitForGets.set(true);
       // Create three sets of gets
@@ -691,7 +677,7 @@ public class TestBlockEvictionFromClient {
           foundNonZeroBlock = true;
         }
       }
-      assertTrue("Should have found nonzero ref count block", foundNonZeroBlock);
+      assertTrue(foundNonZeroBlock, "Should have found nonzero ref count block");
       CustomInnerRegionObserver.getCdl().get().countDown();
       CustomInnerRegionObserver.getCdl().get().countDown();
       for (MultiGetThread thread : getThreads) {
@@ -702,7 +688,7 @@ public class TestBlockEvictionFromClient {
       // giving some time for the block to be decremented
       iterateBlockCache(cache, iterator);
       getLatch.countDown();
-      System.out.println("Gets should have returned the bloks");
+      LOG.info("Gets should have returned the bloks");
     } finally {
       if (table != null) {
         table.close();
@@ -716,7 +702,7 @@ public class TestBlockEvictionFromClient {
     try {
       latch = new CountDownLatch(1);
       // Check if get() returns blocks on its close() itself
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       byte[][] fams = new byte[10][];
@@ -755,7 +741,7 @@ public class TestBlockEvictionFromClient {
       table.put(put);
       region.flush(true);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       // Create three sets of gets
       ScanThread[] scanThreads = initiateScan(table, true);
@@ -776,7 +762,7 @@ public class TestBlockEvictionFromClient {
         }
         if (refCount != 0) {
           // Blocks will be with count 3
-          System.out.println("The refCount is " + refCount);
+          LOG.info("The refCount is " + refCount);
           assertEquals(NO_OF_THREADS, refCount);
           usedBlocksFound = true;
           noOfBlocksWithRef++;
@@ -820,7 +806,7 @@ public class TestBlockEvictionFromClient {
       latch = new CountDownLatch(2);
       // Check if get() returns blocks on its close() itself
       getLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -838,7 +824,7 @@ public class TestBlockEvictionFromClient {
       // insert data. 2 Rows are added
       insertData(table);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       region.flush(true);
       // CustomInnerRegionObserver.sleepTime.set(5000);
@@ -872,12 +858,12 @@ public class TestBlockEvictionFromClient {
 
   @Test
   public void testScanWithCompaction() throws IOException, InterruptedException {
-    testScanWithCompactionInternals(name.getMethodName(), false);
+    testScanWithCompactionInternals(methodName, false);
   }
 
   @Test
   public void testReverseScanWithCompaction() throws IOException, InterruptedException {
-    testScanWithCompactionInternals(name.getMethodName(), true);
+    testScanWithCompactionInternals(methodName, true);
   }
 
   private void testScanWithCompactionInternals(String tableNameStr, boolean reversed)
@@ -920,7 +906,7 @@ public class TestBlockEvictionFromClient {
       put.addColumn(FAMILY, QUALIFIER2, data2);
       table.put(put);
       // flush, one new block
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       region.flush(true);
       Iterator<CachedBlock> iterator = cache.iterator();
       iterateBlockCache(cache, iterator);
@@ -945,9 +931,9 @@ public class TestBlockEvictionFromClient {
           usedBlocksFound = true;
         }
       }
-      assertTrue("Blocks with non zero ref count should be found ", usedBlocksFound);
+      assertTrue(usedBlocksFound, "Blocks with non zero ref count should be found ");
       usedBlocksFound = false;
-      System.out.println("Compacting");
+      LOG.info("Compacting");
       assertEquals(2, store.getStorefilesCount());
       store.triggerMajorCompaction();
       region.compact(true);
@@ -972,7 +958,7 @@ public class TestBlockEvictionFromClient {
           usedBlocksFound = true;
         }
       }
-      assertTrue("Blocks with non zero ref count should be found ", usedBlocksFound);
+      assertTrue(usedBlocksFound, "Blocks with non zero ref count should be found ");
       // Should not throw exception
       compactionLatch.countDown();
       latch.countDown();
@@ -1003,7 +989,7 @@ public class TestBlockEvictionFromClient {
     try {
       latch = new CountDownLatch(1);
       compactionLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
         CustomInnerRegionObserverWrapper.class.getName());
@@ -1037,7 +1023,7 @@ public class TestBlockEvictionFromClient {
       put.addColumn(FAMILY, QUALIFIER2, data2);
       table.put(put);
       // flush, one new block
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       region.flush(true);
       Iterator<CachedBlock> iterator = cache.iterator();
       iterateBlockCache(cache, iterator);
@@ -1069,11 +1055,11 @@ public class TestBlockEvictionFromClient {
       put.addColumn(FAMILY, QUALIFIER2, data2);
       table.put(put);
       // flush, one new block
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       region.flush(true);
-      assertTrue("Blocks with non zero ref count should be found ", usedBlocksFound);
+      assertTrue(usedBlocksFound, "Blocks with non zero ref count should be found ");
       usedBlocksFound = false;
-      System.out.println("Compacting");
+      LOG.info("Compacting");
       assertEquals(3, store.getStorefilesCount());
       store.triggerMajorCompaction();
       region.compact(true);
@@ -1098,7 +1084,7 @@ public class TestBlockEvictionFromClient {
           usedBlocksFound = true;
         }
       }
-      assertTrue("Blocks with non zero ref count should be found ", usedBlocksFound);
+      assertTrue(usedBlocksFound, "Blocks with non zero ref count should be found ");
       // Should not throw exception
       compactionLatch.countDown();
       latch.countDown();
@@ -1130,7 +1116,7 @@ public class TestBlockEvictionFromClient {
     try {
       latch = new CountDownLatch(1);
       exceptionLatch = new CountDownLatch(1);
-      final TableName tableName = TableName.valueOf(name.getMethodName());
+      final TableName tableName = TableName.valueOf(methodName);
       // Create KV that will give you two blocks
       // Create a table with block size as 1024
       table = TEST_UTIL.createTable(tableName, FAMILIES_1, 1, 1024,
@@ -1147,7 +1133,7 @@ public class TestBlockEvictionFromClient {
       // insert data. 2 Rows are added
       insertData(table);
       // flush the data
-      System.out.println("Flushing cache");
+      LOG.info("Flushing cache");
       // Should create one Hfile with 2 blocks
       region.flush(true);
       // CustomInnerRegionObserver.sleepTime.set(5000);
@@ -1305,7 +1291,7 @@ public class TestBlockEvictionFromClient {
       } else {
         continue;
       }
-      System.out.println(" the refcount is " + refCount + " block is " + cacheKey);
+      LOG.info(" the refcount is " + refCount + " block is " + cacheKey);
       if (CustomInnerRegionObserver.waitForGets.get()) {
         if (expectOnlyZero) {
           assertTrue(refCount == 0);
@@ -1403,7 +1389,7 @@ public class TestBlockEvictionFromClient {
       }
       CustomInnerRegionObserver.getCdl().set(latch);
       Result r = table.get(get);
-      System.out.println(r);
+      LOG.info("" + r);
       if (!tracker) {
         assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER), data));
         assertTrue(Bytes.equals(r.getValue(FAMILY, QUALIFIER2), data2));
@@ -1456,7 +1442,7 @@ public class TestBlockEvictionFromClient {
       boolean resultFound = false;
       for (Result result : resScanner) {
         resultFound = true;
-        System.out.println(result);
+        LOG.info("" + result);
         if (!reverse) {
           assertTrue(Bytes.equals(result.getRow(), ROWS[i]));
           i++;
@@ -1477,7 +1463,7 @@ public class TestBlockEvictionFromClient {
     ) {
       Thread.sleep(100);
     }
-    System.out.println("start=" + start + ", now=" + EnvironmentEdgeManager.currentTime() + ", cur="
+    LOG.info("start=" + start + ", now=" + EnvironmentEdgeManager.currentTime() + ", cur="
       + store.getStorefilesCount());
     assertEquals(count, store.getStorefilesCount());
   }
@@ -1618,7 +1604,7 @@ public class TestBlockEvictionFromClient {
       boolean isGet) {
       CountDownLatch latch = getCdl().get();
       try {
-        System.out.println(latch.getCount() + " is the count " + isGet);
+        LOG.info(latch.getCount() + " is the count " + isGet);
         if (latch.getCount() > 0) {
           if (isGet) {
             countOfGets.incrementAndGet();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBootstrapNodeUpdate.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBootstrapNodeUpdate.java
index 549575f4f40..97d87e76901 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBootstrapNodeUpdate.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBootstrapNodeUpdate.java
@@ -19,12 +19,11 @@ package org.apache.hadoop.hbase.client;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasItem;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.Set;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseRpcServicesBase;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.ServerName;
@@ -32,11 +31,10 @@ import org.apache.hadoop.hbase.regionserver.BootstrapNodeManager;
 import org.apache.hadoop.hbase.security.UserProvider;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
@@ -44,18 +42,15 @@ import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
  * Make sure that we can update the bootstrap server from master to region server, and region server
  * could also contact each other to update the bootstrap nodes.
  */
-@Category({ RegionServerTests.class, MediumTests.class })
+@Tag(RegionServerTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestBootstrapNodeUpdate {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestBootstrapNodeUpdate.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   private static RpcConnectionRegistry REGISTRY;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     Configuration conf = UTIL.getConfiguration();
     conf.setLong(BootstrapNodeManager.REQUEST_MASTER_INTERVAL_SECS, 5);
@@ -69,7 +64,7 @@ public class TestBootstrapNodeUpdate {
     REGISTRY = new RpcConnectionRegistry(conf, UserProvider.instantiate(conf).getCurrent());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(REGISTRY, true);
     UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBufferedMutator.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBufferedMutator.java
index 8ec1403a483..dd8a35a2515 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBufferedMutator.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestBufferedMutator.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.concurrent.ExecutorService;
@@ -28,29 +28,24 @@ import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.util.concurrent.ThreadFactoryBuilder;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestBufferedMutator {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestBufferedMutator.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static TableName TABLE_NAME = TableName.valueOf("test");
@@ -61,23 +56,23 @@ public class TestBufferedMutator {
 
   private static byte[] VALUE = new byte[1024];
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.startMiniCluster(1);
     ThreadLocalRandom.current().nextBytes(VALUE);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUpBeforeTest() throws IOException {
     TEST_UTIL.createTable(TABLE_NAME, CF);
   }
 
-  @After
+  @AfterEach
   public void tearDownAfterTest() throws IOException {
     TEST_UTIL.deleteTable(TABLE_NAME);
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteOperationTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteOperationTimeout.java
index e550c65daaa..8286db24248 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteOperationTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteOperationTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, LargeTests.class })
+@Tag(ClientTests.TAG)
+@Tag(LargeTests.TAG)
 public class TestCIDeleteOperationTimeout extends AbstractTestCIOperationTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIDeleteOperationTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.delete(new Delete(FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteRpcTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteRpcTimeout.java
index 5495db7db56..02ddb8a2d7a 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteRpcTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIDeleteRpcTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCIDeleteRpcTimeout extends AbstractTestCIRpcTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIDeleteRpcTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.delete(new Delete(FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetOperationTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetOperationTimeout.java
index 84dd1b86028..f8c96293459 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetOperationTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetOperationTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, LargeTests.class })
+@Tag(ClientTests.TAG)
+@Tag(LargeTests.TAG)
 public class TestCIGetOperationTimeout extends AbstractTestCIOperationTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIGetOperationTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.get(new Get(FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetRpcTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetRpcTimeout.java
index 3ce7d462237..801f4ce312d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetRpcTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIGetRpcTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCIGetRpcTimeout extends AbstractTestCIRpcTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIGetRpcTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.get(new Get(FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIIncrementRpcTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIIncrementRpcTimeout.java
index efc202cc1f9..e6d52b7cc73 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIIncrementRpcTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIIncrementRpcTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCIIncrementRpcTimeout extends AbstractTestCIRpcTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIIncrementRpcTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.increment(new Increment(FAM_NAM).addColumn(FAM_NAM, FAM_NAM, 1));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutOperationTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutOperationTimeout.java
index 08c44e42f2a..855125e9983 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutOperationTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutOperationTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, LargeTests.class })
+@Tag(ClientTests.TAG)
+@Tag(LargeTests.TAG)
 public class TestCIPutOperationTimeout extends AbstractTestCIOperationTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIPutOperationTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.put(new Put(FAM_NAM).addColumn(FAM_NAM, FAM_NAM, FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutRpcTimeout.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutRpcTimeout.java
index 8d9f9c134f9..fbe235d7944 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutRpcTimeout.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCIPutRpcTimeout.java
@@ -18,19 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCIPutRpcTimeout extends AbstractTestCIRpcTimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCIPutRpcTimeout.class);
-
   @Override
   protected void execute(Table table) throws IOException {
     table.put(new Put(FAM_NAM).addColumn(FAM_NAM, FAM_NAM, FAM_NAM));
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCISleep.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCISleep.java
index 32c81de648d..badca41fb5b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCISleep.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCISleep.java
@@ -17,35 +17,30 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCISleep extends AbstractTestCITimeout {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCISleep.class);
-
   private static Logger LOG = LoggerFactory.getLogger(TestCISleep.class);
 
   private TableName tableName;
 
-  @Before
+  @BeforeEach
   public void setUp() {
-    tableName = TableName.valueOf(name.getMethodName());
+    tableName = name.getTableName();
   }
 
   /**
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCatalogReplicaLoadBalanceSimpleSelector.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCatalogReplicaLoadBalanceSimpleSelector.java
index 184b4ba0d3c..26bec655ee8 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCatalogReplicaLoadBalanceSimpleSelector.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCatalogReplicaLoadBalanceSimpleSelector.java
@@ -19,37 +19,32 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.HConstants.EMPTY_START_ROW;
 import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
 
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.RegionLocations;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestCatalogReplicaLoadBalanceSimpleSelector {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCatalogReplicaLoadBalanceSimpleSelector.class);
-
   private static final Logger LOG =
     LoggerFactory.getLogger(TestCatalogReplicaLoadBalanceSimpleSelector.class);
 
@@ -63,7 +58,7 @@ public class TestCatalogReplicaLoadBalanceSimpleSelector {
   private static ConnectionRegistry registry;
   private static Admin admin;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
 
@@ -82,7 +77,7 @@ public class TestCatalogReplicaLoadBalanceSimpleSelector {
       User.getCurrent());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     Closeables.close(CONN, true);
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutate.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutate.java
index 84e21dcf910..fd4e6484232 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutate.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutate.java
@@ -19,18 +19,18 @@ package org.apache.hadoop.hbase.client;
 
 import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import org.apache.hadoop.hbase.CompareOperator;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.filter.BinaryComparator;
@@ -41,45 +41,45 @@ import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
 import org.apache.hadoop.hbase.filter.TimestampsFilter;
 import org.apache.hadoop.hbase.io.TimeRange;
 import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-
-@Category(MediumTests.class)
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestCheckAndMutate {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCheckAndMutate.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final byte[] ROWKEY = Bytes.toBytes("12345");
   private static final byte[] ROWKEY2 = Bytes.toBytes("67890");
   private static final byte[] ROWKEY3 = Bytes.toBytes("abcde");
   private static final byte[] ROWKEY4 = Bytes.toBytes("fghij");
   private static final byte[] FAMILY = Bytes.toBytes("cf");
+  private String methodName;
 
-  @Rule
-  public TestName name = new TestName();
-
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
+  @BeforeEach
+  public void setUp(TestInfo testInfo) {
+    this.methodName = testInfo.getTestMethod().get().getName();
+  }
+
   private Table createTable() throws IOException, InterruptedException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     Table table = TEST_UTIL.createTable(tableName, FAMILY);
     TEST_UTIL.waitTableAvailable(tableName.getName(), 5000);
     return table;
@@ -96,22 +96,22 @@ public class TestCheckAndMutate {
   private void getOneRowAndAssertAllExist(final Table table) throws IOException {
     Get get = new Get(ROWKEY);
     Result result = table.get(get);
-    assertTrue("Column A value should be a",
-      Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"));
-    assertTrue("Column B value should be b",
-      Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"));
-    assertTrue("Column C value should be c",
-      Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C"))).equals("c"));
+    assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"),
+      "Column A value should be a");
+    assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"),
+      "Column B value should be b");
+    assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("C"))).equals("c"),
+      "Column C value should be c");
   }
 
   private void getOneRowAndAssertAllButCExist(final Table table) throws IOException {
     Get get = new Get(ROWKEY);
     Result result = table.get(get);
-    assertTrue("Column A value should be a",
-      Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"));
-    assertTrue("Column B value should be b",
-      Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"));
-    assertTrue("Column C should not exist", result.getValue(FAMILY, Bytes.toBytes("C")) == null);
+    assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("A"))).equals("a"),
+      "Column A value should be a");
+    assertTrue(Bytes.toString(result.getValue(FAMILY, Bytes.toBytes("B"))).equals("b"),
+      "Column B value should be b");
+    assertTrue(result.getValue(FAMILY, Bytes.toBytes("C")) == null, "Column C should not exist");
   }
 
   private RowMutations makeRowMutationsWithColumnCDeleted() throws IOException {
@@ -359,12 +359,12 @@ public class TestCheckAndMutate {
     }
   }
 
-  @Test(expected = NullPointerException.class)
+  @Test
   @Deprecated
   public void testCheckAndMutateWithoutConditionForOldApi() throws Throwable {
     try (Table table = createTable()) {
-      table.checkAndMutate(ROWKEY, FAMILY)
-        .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));
+      assertThrows(NullPointerException.class, () -> table.checkAndMutate(ROWKEY, FAMILY)
+        .thenPut(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d"))));
     }
   }
 
@@ -590,10 +590,12 @@ public class TestCheckAndMutate {
     }
   }
 
-  @Test(expected = IllegalStateException.class)
+  @Test
   public void testCheckAndMutateBuilderWithoutCondition() {
-    CheckAndMutate.newBuilder(ROWKEY)
-      .build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));
+    CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(ROWKEY);
+    assertThrows(IllegalStateException.class, () -> {
+      builder.build(new Put(ROWKEY).addColumn(FAMILY, Bytes.toBytes("D"), Bytes.toBytes("d")));
+    });
   }
 
   @Test
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutateWithByteBuff.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutateWithByteBuff.java
index 8c7452cec0b..8a50c68b770 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutateWithByteBuff.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCheckAndMutateWithByteBuff.java
@@ -18,7 +18,7 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.util.Threads.sleep;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.List;
@@ -26,7 +26,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -37,36 +36,26 @@ import org.apache.hadoop.hbase.io.hfile.BlockCacheFactory;
 import org.apache.hadoop.hbase.regionserver.HRegion;
 import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.wal.WAL;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Category(LargeTests.class)
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestCheckAndMutateWithByteBuff {
-  private static final Logger LOG = LoggerFactory.getLogger(TestCheckAndMutateWithByteBuff.class);
-
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCheckAndMutateWithByteBuff.class);
-
-  @Rule
-  public TestName name = new TestName();
 
   private static final byte[] CF = Bytes.toBytes("CF");
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final Configuration conf = TEST_UTIL.getConfiguration();
   private static Admin admin = null;
 
-  @BeforeClass
+  @BeforeAll
   public static void setupBeforeClass() throws Exception {
     conf.set(HConstants.REGION_IMPL, TestCheckAndMutateRegion.class.getName());
     conf.set(ByteBuffAllocator.BYTEBUFF_ALLOCATOR_CLASS,
@@ -82,22 +71,23 @@ public class TestCheckAndMutateWithByteBuff {
     admin = TEST_UTIL.getAdmin();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
   @Test
-  public void testCheckAndMutateWithByteBuffNoEncode() throws Exception {
-    testCheckAndMutateWithByteBuff(TableName.valueOf(name.getMethodName()), DataBlockEncoding.NONE);
+  public void testCheckAndMutateWithByteBuffNoEncode(TestInfo testInfo) throws Exception {
+    testCheckAndMutateWithByteBuff(TableName.valueOf(testInfo.getTestMethod().get().getName()),
+      DataBlockEncoding.NONE);
   }
 
   @Test
-  public void testCheckAndMutateWithByteBuffEncode() throws Exception {
+  public void testCheckAndMutateWithByteBuffEncode(TestInfo testInfo) throws Exception {
     // Tests for HBASE-26777.
     // As most HBase.getRegion() calls have been factored out from HBase, you'd need to revert
     // both HBASE-26777, and the HBase.get() replacements from HBASE-26036 for this test to fail
-    testCheckAndMutateWithByteBuff(TableName.valueOf(name.getMethodName()),
+    testCheckAndMutateWithByteBuff(TableName.valueOf(testInfo.getTestMethod().get().getName()),
       DataBlockEncoding.FAST_DIFF);
   }
 
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplica.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplica.java
index 912ded0a27b..506e71c4c5b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplica.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplica.java
@@ -17,28 +17,23 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.List;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
 import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ MiscTests.class, MediumTests.class })
+@Tag(MiscTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCleanupMetaReplica extends MetaWithReplicasTestBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCleanupMetaReplica.class);
-
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     startCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplicaThroughConfig.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplicaThroughConfig.java
index 681d6da7c2f..b9ef4472750 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplicaThroughConfig.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCleanupMetaReplicaThroughConfig.java
@@ -17,32 +17,27 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.List;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
 import org.apache.hadoop.hbase.util.JVMClusterUtil;
 import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 /**
  * Make sure we will honor the {@link HConstants#META_REPLICAS_NUM}.
  */
-@Category({ MiscTests.class, MediumTests.class })
+@Tag(MiscTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestCleanupMetaReplicaThroughConfig extends MetaWithReplicasTestBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCleanupMetaReplicaThroughConfig.class);
-
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     startCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientOperationInterrupt.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientOperationInterrupt.java
index dcb96b49871..ccb183d8d9d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientOperationInterrupt.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientOperationInterrupt.java
@@ -17,6 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.net.SocketTimeoutException;
@@ -26,7 +29,6 @@ import java.util.Optional;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
@@ -39,22 +41,17 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestClientOperationInterrupt {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestClientOperationInterrupt.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestClientOperationInterrupt.class);
 
   private static HBaseTestingUtil util;
@@ -77,7 +74,7 @@ public class TestClientOperationInterrupt {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     conf = HBaseConfiguration.create();
     conf.setStrings(CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY,
@@ -156,9 +153,9 @@ public class TestClientOperationInterrupt {
       Threads.sleep(10);
     }
 
-    Assert.assertFalse(Thread.currentThread().isInterrupted());
-    Assert.assertTrue(" noEx: " + noEx.get() + ", badEx=" + badEx.get() + ", noInt=" + noInt.get(),
-      noEx.get() == expectedNoExNum && badEx.get() == 0);
+    assertFalse(Thread.currentThread().isInterrupted());
+    assertTrue(noEx.get() == expectedNoExNum && badEx.get() == 0,
+      " noEx: " + noEx.get() + ", badEx=" + badEx.get() + ", noInt=" + noInt.get());
 
     // The problem here is that we need the server to free its handlers to handle all operations
     while (done.get() != nbThread) {
@@ -167,10 +164,10 @@ public class TestClientOperationInterrupt {
 
     Table ht = util.getConnection().getTable(tableName);
     Result r = ht.get(new Get(row1));
-    Assert.assertFalse(r.isEmpty());
+    assertFalse(r.isEmpty());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     util.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientScannerTimeouts.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientScannerTimeouts.java
index e5770894528..fafaf6b4cef 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientScannerTimeouts.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientScannerTimeouts.java
@@ -19,14 +19,13 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.client.ConnectionConfiguration.HBASE_CLIENT_META_READ_RPC_TIMEOUT_KEY;
 import static org.apache.hadoop.hbase.client.ConnectionConfiguration.HBASE_CLIENT_META_SCANNER_TIMEOUT;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.function.Supplier;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.NamespaceDescriptor;
@@ -39,13 +38,11 @@ import org.apache.hadoop.hbase.regionserver.RSRpcServices;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,13 +52,10 @@ import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanRequest;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ScanResponse;
 
-@Category({ ClientTests.class, LargeTests.class })
+@Tag(ClientTests.TAG)
+@Tag(LargeTests.TAG)
 public class TestClientScannerTimeouts {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestClientScannerTimeouts.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestClientScannerTimeouts.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
@@ -83,10 +77,7 @@ public class TestClientScannerTimeouts {
   private static Table table;
   private static AsyncTable<AdvancedScanResultConsumer> asyncTable;
 
-  @Rule
-  public TestName name = new TestName();
-
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     // Don't report so often so easier to see other rpcs
@@ -104,17 +95,17 @@ public class TestClientScannerTimeouts {
     CONN = ASYNC_CONN.toConnection();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     CONN.close();
     ASYNC_CONN.close();
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  public void setup(boolean isSystemTable) throws IOException {
+  public void setup(boolean isSystemTable, TestInfo testInfo) throws IOException {
     RSRpcServicesWithScanTimeout.reset();
 
-    String nameAsString = name.getMethodName();
+    String nameAsString = testInfo.getTestMethod().get().getName();
     if (isSystemTable) {
       nameAsString = NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR + ":" + nameAsString;
     }
@@ -136,14 +127,13 @@ public class TestClientScannerTimeouts {
   }
 
   private void expectRow(byte[] expected, Result result) {
-    assertTrue("Expected row: " + Bytes.toString(expected),
-      Bytes.equals(expected, result.getRow()));
+    assertTrue(Bytes.equals(expected, result.getRow()),
+      "Expected row: " + Bytes.toString(expected));
   }
 
   private void expectNumTries(int expected) {
-    assertEquals(
-      "Expected tryNumber=" + expected + ", actual=" + RSRpcServicesWithScanTimeout.tryNumber,
-      expected, RSRpcServicesWithScanTimeout.tryNumber);
+    assertEquals(expected, RSRpcServicesWithScanTimeout.tryNumber,
+      "Expected tryNumber=" + expected + ", actual=" + RSRpcServicesWithScanTimeout.tryNumber);
     // reset for next
     RSRpcServicesWithScanTimeout.tryNumber = 0;
   }
@@ -156,16 +146,16 @@ public class TestClientScannerTimeouts {
    * that we can test the retry logic appropriately.
    */
   @Test
-  public void testRetryOutOfOrderScannerNextException() throws IOException {
-    expectRetryOutOfOrderScannerNext(this::getScanner);
+  public void testRetryOutOfOrderScannerNextException(TestInfo testInfo) throws IOException {
+    expectRetryOutOfOrderScannerNext(this::getScanner, testInfo);
   }
 
   /**
    * AsyncTable version of above
    */
   @Test
-  public void testRetryOutOfOrderScannerNextExceptionAsync() throws IOException {
-    expectRetryOutOfOrderScannerNext(this::getAsyncScanner);
+  public void testRetryOutOfOrderScannerNextExceptionAsync(TestInfo testInfo) throws IOException {
+    expectRetryOutOfOrderScannerNext(this::getAsyncScanner, testInfo);
   }
 
   /**
@@ -173,8 +163,8 @@ public class TestClientScannerTimeouts {
    * scans.
    */
   @Test
-  public void testNormalScanTimeoutOnNext() throws IOException {
-    setup(false);
+  public void testNormalScanTimeoutOnNext(TestInfo testInfo) throws IOException {
+    setup(false, testInfo);
     expectTimeoutOnNext(scanTimeout, this::getScanner);
   }
 
@@ -182,8 +172,8 @@ public class TestClientScannerTimeouts {
    * AsyncTable version of above
    */
   @Test
-  public void testNormalScanTimeoutOnNextAsync() throws IOException {
-    setup(false);
+  public void testNormalScanTimeoutOnNextAsync(TestInfo testInfo) throws IOException {
+    setup(false, testInfo);
     expectTimeoutOnNext(scanTimeout, this::getAsyncScanner);
   }
 
@@ -192,8 +182,8 @@ public class TestClientScannerTimeouts {
    * meta scans
    */
   @Test
-  public void testNormalScanTimeoutOnOpenScanner() throws IOException {
-    setup(false);
+  public void testNormalScanTimeoutOnOpenScanner(TestInfo testInfo) throws IOException {
+    setup(false, testInfo);
     expectTimeoutOnOpenScanner(rpcTimeout, this::getScanner);
   }
 
@@ -201,8 +191,8 @@ public class TestClientScannerTimeouts {
    * AsyncTable version of above
    */
   @Test
-  public void testNormalScanTimeoutOnOpenScannerAsync() throws IOException {
-    setup(false);
+  public void testNormalScanTimeoutOnOpenScannerAsync(TestInfo testInfo) throws IOException {
+    setup(false, testInfo);
     expectTimeoutOnOpenScanner(rpcTimeout, this::getAsyncScanner);
   }
 
@@ -211,8 +201,8 @@ public class TestClientScannerTimeouts {
    * next() calls in meta scans
    */
   @Test
-  public void testMetaScanTimeoutOnNext() throws IOException {
-    setup(true);
+  public void testMetaScanTimeoutOnNext(TestInfo testInfo) throws IOException {
+    setup(true, testInfo);
     expectTimeoutOnNext(metaScanTimeout, this::getScanner);
   }
 
@@ -220,8 +210,8 @@ public class TestClientScannerTimeouts {
    * AsyncTable version of above
    */
   @Test
-  public void testMetaScanTimeoutOnNextAsync() throws IOException {
-    setup(true);
+  public void testMetaScanTimeoutOnNextAsync(TestInfo testInfo) throws IOException {
+    setup(true, testInfo);
     expectTimeoutOnNext(metaScanTimeout, this::getAsyncScanner);
   }
 
@@ -230,8 +220,8 @@ public class TestClientScannerTimeouts {
    * openScanner() calls for meta scans
    */
   @Test
-  public void testMetaScanTimeoutOnOpenScanner() throws IOException {
-    setup(true);
+  public void testMetaScanTimeoutOnOpenScanner(TestInfo testInfo) throws IOException {
+    setup(true, testInfo);
     expectTimeoutOnOpenScanner(metaScanTimeout, this::getScanner);
   }
 
@@ -239,14 +229,14 @@ public class TestClientScannerTimeouts {
    * AsyncTable version of above
    */
   @Test
-  public void testMetaScanTimeoutOnOpenScannerAsync() throws IOException {
-    setup(true);
+  public void testMetaScanTimeoutOnOpenScannerAsync(TestInfo testInfo) throws IOException {
+    setup(true, testInfo);
     expectTimeoutOnOpenScanner(metaScanTimeout, this::getAsyncScanner);
   }
 
-  private void expectRetryOutOfOrderScannerNext(Supplier<ResultScanner> scannerSupplier)
-    throws IOException {
-    setup(false);
+  private void expectRetryOutOfOrderScannerNext(Supplier<ResultScanner> scannerSupplier,
+    TestInfo testInfo) throws IOException {
+    setup(false, testInfo);
     RSRpcServicesWithScanTimeout.seqNoToThrowOn = 1;
 
     LOG.info(
@@ -297,8 +287,8 @@ public class TestClientScannerTimeouts {
 
     // ensure we verified all rows. this along with the expectRow check above
     // proves that we didn't miss any rows.
-    assertEquals("Expected to exhaust expectedResults array length=" + expectedResults.length
-      + ", actual index=" + i, expectedResults.length, i);
+    assertEquals(expectedResults.length, i, "Expected to exhaust expectedResults array length="
+      + expectedResults.length + ", actual index=" + i);
 
     // expect all but the first row (which came from initial openScanner) to have thrown an error
     expectNumTries(expectedResults.length - 1);
@@ -326,7 +316,7 @@ public class TestClientScannerTimeouts {
       scanner.next();
       fail("Expected CallTimeoutException");
     } catch (RetriesExhaustedException e) {
-      assertTrue("Expected CallTimeoutException", e.getCause() instanceof CallTimeoutException);
+      assertTrue(e.getCause() instanceof CallTimeoutException, "Expected CallTimeoutException");
     }
     expectTimeout(start, timeout);
   }
@@ -341,15 +331,15 @@ public class TestClientScannerTimeouts {
       scannerSupplier.get().next();
       fail("Expected CallTimeoutException");
     } catch (RetriesExhaustedException e) {
-      assertTrue("Expected CallTimeoutException, but was " + e.getCause(),
-        e.getCause() instanceof CallTimeoutException);
+      assertTrue(e.getCause() instanceof CallTimeoutException,
+        "Expected CallTimeoutException, but was " + e.getCause());
     }
     expectTimeout(start, timeout);
   }
 
   private void expectTimeout(long start, int timeout) {
     long duration = System.nanoTime() - start;
-    assertTrue("Expected duration >= " + timeout + ", but was " + duration, duration >= timeout);
+    assertTrue(duration >= timeout, "Expected duration >= " + timeout + ", but was " + duration);
   }
 
   private ResultScanner getScanner() {
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientSideRegionScanner.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientSideRegionScanner.java
index 375406e2d05..8a69508934b 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientSideRegionScanner.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientSideRegionScanner.java
@@ -18,11 +18,14 @@
 package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.client.metrics.ServerSideScanMetrics.COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.anyList;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -37,7 +40,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -53,22 +55,16 @@ import org.apache.hadoop.hbase.regionserver.StoreScanner;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-
-@Category({ SmallTests.class, ClientTests.class })
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+
+@Tag(SmallTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestClientSideRegionScanner {
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestClientSideRegionScanner.class);
-
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final TableName TABLE_NAME = TableName.valueOf("test");
   private static final byte[] FAM_NAME = Bytes.toBytes("f");
@@ -79,22 +75,21 @@ public class TestClientSideRegionScanner {
   private TableDescriptor htd;
   private RegionInfo hri;
   private Scan scan;
+  private String methodName;
 
-  @Rule
-  public TestName name = new TestName();
-
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(1);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
-  public void setup() throws IOException {
+  @BeforeEach
+  public void setup(TestInfo testInfo) throws IOException {
+    this.methodName = testInfo.getTestMethod().get().getName();
     conf = TEST_UTIL.getConfiguration();
     rootDir = TEST_UTIL.getDefaultRootDirPath();
     fs = TEST_UTIL.getTestFileSystem();
@@ -106,14 +101,14 @@ public class TestClientSideRegionScanner {
   @Test
   public void testDefaultBlockCache() throws IOException {
     Configuration copyConf = new Configuration(conf);
-    ClientSideRegionScanner clientSideRegionScanner =
-      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null);
-
-    BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
-    assertNotNull(blockCache);
-    assertTrue(blockCache instanceof IndexOnlyLruBlockCache);
-    assertTrue(HConstants.HBASE_CLIENT_SCANNER_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT
-        == blockCache.getMaxSize());
+    try (ClientSideRegionScanner clientSideRegionScanner =
+      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null)) {
+      BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
+      assertNotNull(blockCache);
+      assertThat(blockCache, instanceOf(IndexOnlyLruBlockCache.class));
+      assertEquals(HConstants.HBASE_CLIENT_SCANNER_ONHEAP_BLOCK_CACHE_FIXED_SIZE_DEFAULT,
+        blockCache.getMaxSize());
+    }
   }
 
   @Test
@@ -122,24 +117,24 @@ public class TestClientSideRegionScanner {
     // tiny 1MB fixed cache size
     long blockCacheFixedSize = 1024 * 1024L;
     copyConf.setLong(HConstants.HFILE_ONHEAP_BLOCK_CACHE_FIXED_SIZE_KEY, blockCacheFixedSize);
-    ClientSideRegionScanner clientSideRegionScanner =
-      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null);
-
-    BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
-    assertNotNull(blockCache);
-    assertTrue(blockCache instanceof IndexOnlyLruBlockCache);
-    assertTrue(blockCacheFixedSize == blockCache.getMaxSize());
+    try (ClientSideRegionScanner clientSideRegionScanner =
+      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null)) {
+      BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
+      assertNotNull(blockCache);
+      assertThat(blockCache, instanceOf(IndexOnlyLruBlockCache.class));
+      assertEquals(blockCacheFixedSize, blockCache.getMaxSize());
+    }
   }
 
   @Test
   public void testNoBlockCache() throws IOException {
     Configuration copyConf = new Configuration(conf);
     copyConf.setFloat(HConstants.HFILE_BLOCK_CACHE_SIZE_KEY, 0.0f);
-    ClientSideRegionScanner clientSideRegionScanner =
-      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null);
-
-    BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
-    assertNull(blockCache);
+    try (ClientSideRegionScanner clientSideRegionScanner =
+      new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null)) {
+      BlockCache blockCache = clientSideRegionScanner.getRegion().getBlockCache();
+      assertNull(blockCache);
+    }
   }
 
   @Test
@@ -169,27 +164,28 @@ public class TestClientSideRegionScanner {
       // Flush contents to disk so we can scan the fs
       TEST_UTIL.getAdmin().flush(TABLE_NAME);
 
-      ClientSideRegionScanner clientSideRegionScanner =
-        new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null);
-      RegionScanner scannerSpy = spy(clientSideRegionScanner.scanner);
-      clientSideRegionScanner.scanner = scannerSpy;
-      Result result = clientSideRegionScanner.next();
+      try (ClientSideRegionScanner clientSideRegionScanner =
+        new ClientSideRegionScanner(copyConf, fs, rootDir, htd, hri, scan, null)) {
+        RegionScanner scannerSpy = spy(clientSideRegionScanner.scanner);
+        clientSideRegionScanner.scanner = scannerSpy;
+        Result result = clientSideRegionScanner.next();
 
-      verify(scannerSpy, times(6)).nextRaw(anyList());
-      assertNotNull(result);
-      assertEquals(Bytes.toInt(result.getRow()), 5);
-      assertTrue(clientSideRegionScanner.hasMore);
+        verify(scannerSpy, times(6)).nextRaw(anyList());
+        assertNotNull(result);
+        assertEquals(Bytes.toInt(result.getRow()), 5);
+        assertTrue(clientSideRegionScanner.hasMore);
+
+        for (int i = 6; i < 10; ++i) {
+          result = clientSideRegionScanner.next();
+          verify(scannerSpy, times(i + 1)).nextRaw(anyList());
+          assertNotNull(result);
+          assertEquals(Bytes.toInt(result.getRow()), i);
+        }
 
-      for (int i = 6; i < 10; ++i) {
         result = clientSideRegionScanner.next();
-        verify(scannerSpy, times(i + 1)).nextRaw(anyList());
-        assertNotNull(result);
-        assertEquals(Bytes.toInt(result.getRow()), i);
+        assertNull(result);
+        assertFalse(clientSideRegionScanner.hasMore);
       }
-
-      result = clientSideRegionScanner.next();
-      assertNull(result);
-      assertFalse(clientSideRegionScanner.hasMore);
     }
   }
 
@@ -216,11 +212,11 @@ public class TestClientSideRegionScanner {
       ScanMetrics scanMetricsFromScanner = clientSideRegionScanner.getScanMetrics();
       assertNotNull(scanMetricsFromScanner);
       if (scanMetrics != null) {
-        Assert.assertSame(scanMetrics, scanMetricsFromScanner);
+        assertSame(scanMetrics, scanMetricsFromScanner);
       }
       Map<String, Long> metricsMap = scanMetricsFromScanner.getMetricsMap(false);
-      Assert.assertTrue(metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME) > 0);
-      Assert.assertTrue(scanMetricsFromScanner.collectMetricsByRegion(false).isEmpty());
+      assertTrue(metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME) > 0);
+      assertTrue(scanMetricsFromScanner.collectMetricsByRegion(false).isEmpty());
     }
   }
 
@@ -245,19 +241,19 @@ public class TestClientSideRegionScanner {
       ScanMetrics scanMetricsFromScanner = clientSideRegionScanner.getScanMetrics();
       assertNotNull(scanMetricsFromScanner);
       if (scanMetrics != null) {
-        Assert.assertSame(scanMetrics, scanMetricsFromScanner);
+        assertSame(scanMetrics, scanMetricsFromScanner);
       }
       Map<ScanMetricsRegionInfo, Map<String, Long>> scanMetricsByRegion =
         scanMetricsFromScanner.collectMetricsByRegion();
-      Assert.assertEquals(1, scanMetricsByRegion.size());
+      assertEquals(1, scanMetricsByRegion.size());
       for (Map.Entry<ScanMetricsRegionInfo, Map<String, Long>> entry : scanMetricsByRegion
         .entrySet()) {
         ScanMetricsRegionInfo scanMetricsRegionInfo = entry.getKey();
         Map<String, Long> metricsMap = entry.getValue();
-        Assert.assertEquals(hri.getEncodedName(), scanMetricsRegionInfo.getEncodedRegionName());
-        Assert.assertNull(scanMetricsRegionInfo.getServerName());
-        Assert.assertTrue(metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME) > 0);
-        Assert.assertEquals((long) metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME),
+        assertEquals(hri.getEncodedName(), scanMetricsRegionInfo.getEncodedRegionName());
+        assertNull(scanMetricsRegionInfo.getServerName());
+        assertTrue(metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME) > 0);
+        assertEquals((long) metricsMap.get(COUNT_OF_ROWS_SCANNED_KEY_METRIC_NAME),
           scanMetricsFromScanner.countOfRowsScanned.get());
       }
     }
@@ -276,7 +272,7 @@ public class TestClientSideRegionScanner {
   @Test
   public void testGetFilesRead() throws Exception {
     // Create a table and add some data
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     try (Table table = TEST_UTIL.createTable(tableName, new byte[][] { FAM_NAME })) {
       TableDescriptor tableHtd = TEST_UTIL.getAdmin().getDescriptor(tableName);
       RegionInfo tableHri = TEST_UTIL.getAdmin().getRegions(tableName).get(0);
@@ -307,24 +303,24 @@ public class TestClientSideRegionScanner {
         expectedFilePaths.add(qualifiedPath);
       }
       int expectedFileCount = expectedFilePaths.size();
-      assertTrue("Should have at least one store file after flush", expectedFileCount >= 1);
+      assertTrue(expectedFileCount >= 1, "Should have at least one store file after flush");
 
       // Before closing, should return empty set
       Set<Path> filesReadBeforeClose = clientSideRegionScanner.getFilesRead();
-      assertTrue("Should return empty set before closing", filesReadBeforeClose.isEmpty());
+      assertTrue(filesReadBeforeClose.isEmpty(), "Should return empty set before closing");
 
       // Scan through some results
       Result result;
       int count = 0;
       while ((result = clientSideRegionScanner.next()) != null && count < 3) {
-        assertNotNull("Result should not be null", result);
+        assertNotNull(result, "Result should not be null");
         count++;
       }
 
       // Still should return empty set before closing
       filesReadBeforeClose = clientSideRegionScanner.getFilesRead();
-      assertTrue("Should return empty set before closing even after scanning",
-        filesReadBeforeClose.isEmpty());
+      assertTrue(filesReadBeforeClose.isEmpty(),
+        "Should return empty set before closing even after scanning");
 
       // Close the scanner - this should collect files from the underlying scanner
       clientSideRegionScanner.close();
@@ -332,11 +328,11 @@ public class TestClientSideRegionScanner {
       // After closing, should return files from the underlying scanner
       Set<Path> filesReadAfterClose = clientSideRegionScanner.getFilesRead();
       // Verify exact file count
-      assertEquals("Should have exact file count after closing", expectedFileCount,
-        filesReadAfterClose.size());
+      assertEquals(expectedFileCount, filesReadAfterClose.size(),
+        "Should have exact file count after closing");
       // Verify exact file names match
-      assertEquals("Should contain all expected file paths", expectedFilePaths,
-        filesReadAfterClose);
+      assertEquals(expectedFilePaths, filesReadAfterClose,
+        "Should contain all expected file paths");
     } finally {
       TEST_UTIL.deleteTable(tableName);
     }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTableMetrics.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTableMetrics.java
index c0980c51256..81db169bfa8 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTableMetrics.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTableMetrics.java
@@ -17,34 +17,30 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import com.codahale.metrics.Timer;
 import java.io.IOException;
 import java.util.Arrays;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hadoop.hbase.shaded.protobuf.generated.ClientProtos.ClientService;
 
-@Category(MediumTests.class)
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestClientTableMetrics {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestClientTableMetrics.class);
-
   private static HBaseTestingUtil UTIL;
   private static Connection CONN;
   private static MetricsConnection METRICS;
@@ -52,7 +48,7 @@ public class TestClientTableMetrics {
   private static final TableName TABLE_1 = TableName.valueOf(tableName);
   private static final byte[] FAMILY = Bytes.toBytes("f");
 
-  @BeforeClass
+  @BeforeAll
   public static void beforeClass() throws Exception {
     Configuration conf = HBaseConfiguration.create();
     conf.setBoolean(MetricsConnection.CLIENT_SIDE_METRICS_ENABLED_KEY, true);
@@ -65,7 +61,7 @@ public class TestClientTableMetrics {
     METRICS = ((AsyncConnectionImpl) CONN.toAsyncConnection()).getConnectionMetrics().get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void afterClass() throws Exception {
     UTIL.deleteTableIfAny(TABLE_1);
     UTIL.shutdownMiniCluster();
@@ -141,8 +137,8 @@ public class TestClientTableMetrics {
     long numOps = timer.getCount();
     double p95 = timer.getSnapshot().get95thPercentile();
     double p99 = timer.getSnapshot().get99thPercentile();
-    assertEquals("metric: " + metricKey + numOpsSuffix + " val: " + numOps, expectedVal, numOps);
-    assertTrue("metric: " + metricKey + p95Suffix + " val: " + p95, p95 >= 0);
-    assertTrue("metric: " + metricKey + p99Suffix + " val: " + p99, p99 >= 0);
+    assertEquals(expectedVal, numOps, "metric: " + metricKey + numOpsSuffix + " val: " + numOps);
+    assertTrue(p95 >= 0, "metric: " + metricKey + p95Suffix + " val: " + p95);
+    assertTrue(p99 >= 0, "metric: " + metricKey + p99Suffix + " val: " + p99);
   }
 }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTimeouts.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTimeouts.java
index 9a92f4b1aa5..1d64a9caa55 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTimeouts.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestClientTimeouts.java
@@ -17,8 +17,8 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.net.SocketAddress;
@@ -27,7 +27,6 @@ import java.util.Map;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
@@ -40,11 +39,10 @@ import org.apache.hadoop.hbase.net.Address;
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.protobuf.BlockingRpcChannel;
 import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors.MethodDescriptor;
@@ -54,22 +52,19 @@ import org.apache.hbase.thirdparty.com.google.protobuf.RpcChannel;
 import org.apache.hbase.thirdparty.com.google.protobuf.RpcController;
 import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestClientTimeouts {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestClientTimeouts.class);
-
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   protected static int SLAVES = 1;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(SLAVES);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCompleteResultScanResultCache.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCompleteResultScanResultCache.java
index 4973c2c98a4..754ec3cd760 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCompleteResultScanResultCache.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestCompleteResultScanResultCache.java
@@ -17,30 +17,25 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
 
 import java.io.IOException;
 import java.util.Arrays;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ SmallTests.class, ClientTests.class })
+@Tag(SmallTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestCompleteResultScanResultCache {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestCompleteResultScanResultCache.class);
-
   private static byte[] CF = Bytes.toBytes("cf");
 
   private static byte[] CQ1 = Bytes.toBytes("cq1");
@@ -51,12 +46,12 @@ public class TestCompleteResultScanResultCache {
 
   private CompleteScanResultCache resultCache;
 
-  @Before
+  @BeforeEach
   public void setUp() {
     resultCache = new CompleteScanResultCache();
   }
 
-  @After
+  @AfterEach
   public void tearDown() {
     resultCache.clear();
     resultCache = null;
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnection.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnection.java
index 42d5a87a9ce..183cd4892d1 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnection.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnection.java
@@ -17,9 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.List;
@@ -31,7 +34,6 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.HRegionLocation;
@@ -41,23 +43,21 @@ import org.apache.hadoop.hbase.Waiter;
 import org.apache.hadoop.hbase.client.coprocessor.Batch;
 import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint;
 import org.apache.hadoop.hbase.ipc.RpcClient;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
 import org.apache.hbase.thirdparty.io.netty.util.ResourceLeakDetector;
 import org.apache.hbase.thirdparty.io.netty.util.ResourceLeakDetector.Level;
 
@@ -67,24 +67,19 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MultiRowMutationProtos.
 /**
  * This class is for testing {@link Connection}.
  */
-@Category({ LargeTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestConnection {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestConnection.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestConnection.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static final byte[] FAM_NAM = Bytes.toBytes("f");
   private static final byte[] ROW = Bytes.toBytes("bbb");
   private static final int RPC_RETRY = 5;
+  private String methodName;
 
-  @Rule
-  public TestName name = new TestName();
-
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     ResourceLeakDetector.setLevel(Level.PARANOID);
     TEST_UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true);
@@ -96,13 +91,18 @@ public class TestConnection {
 
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @After
-  public void tearDown() throws IOException {
+  @BeforeEach
+  public void setUp(TestInfo testInfo) {
+    this.methodName = testInfo.getTestMethod().get().getName();
+  }
+
+  @AfterEach
+  public void tearDown(TestInfo testInfo) throws IOException {
     TEST_UTIL.getAdmin().balancerSwitch(true, true);
   }
 
@@ -112,11 +112,11 @@ public class TestConnection {
    */
   @Test
   public void testAdminFactory() throws IOException {
-    Connection con1 = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
-    Admin admin = con1.getAdmin();
-    assertTrue(admin.getConnection() == con1);
-    assertTrue(admin.getConfiguration() == TEST_UTIL.getConfiguration());
-    con1.close();
+    try (Connection con1 = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
+      Admin admin = con1.getAdmin()) {
+      assertSame(admin.getConnection(), con1);
+      assertSame(admin.getConfiguration(), TEST_UTIL.getConfiguration());
+    }
   }
 
   /**
@@ -217,7 +217,7 @@ public class TestConnection {
     });
     table.close();
     connection.close();
-    Assert.assertTrue("Unexpected exception is " + failed.get(), failed.get() == null);
+    assertNull(failed.get(), "Unexpected exception is " + failed.get());
   }
 
   /**
@@ -225,7 +225,7 @@ public class TestConnection {
    */
   @Test
   public void testConnectionIdle() throws Exception {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, FAM_NAM).close();
     int idleTime = 20000;
     boolean previousBalance = TEST_UTIL.getAdmin().balancerSwitch(false, true);
@@ -334,7 +334,7 @@ public class TestConnection {
   public void testLocateRegionsWithRegionReplicas() throws IOException {
     int regionReplication = 3;
     byte[] family = Bytes.toBytes("cf");
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
 
     // Create a table with region replicas
     TableDescriptorBuilder builder =
@@ -361,10 +361,10 @@ public class TestConnection {
     }
   }
 
-  @Test(expected = DoNotRetryIOException.class)
-  public void testClosedConnection() throws ServiceException, Throwable {
+  @Test
+  public void testClosedConnection() throws Throwable {
     byte[] family = Bytes.toBytes("cf");
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName)
       .setCoprocessor(MultiRowMutationEndpoint.class.getName())
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(family));
@@ -377,17 +377,19 @@ public class TestConnection {
     } finally {
       conn.close();
     }
-    Batch.Call<MultiRowMutationService, MutateRowsResponse> callable = service -> {
-      throw new RuntimeException("Should not arrive here");
-    };
-    conn.getTable(tableName).coprocessorService(MultiRowMutationService.class,
-      HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, callable);
+    assertThrows(DoNotRetryIOException.class, () -> {
+      Batch.Call<MultiRowMutationService, MutateRowsResponse> callable = service -> {
+        throw new RuntimeException("Should not arrive here");
+      };
+      conn.getTable(tableName).coprocessorService(MultiRowMutationService.class,
+        HConstants.EMPTY_START_ROW, HConstants.EMPTY_END_ROW, callable);
+    });
   }
 
   // There is no assertion, but you need to confirm that there is no resource leak output from netty
   @Test
   public void testCancelConnectionMemoryLeak() throws IOException, InterruptedException {
-    TableName tableName = TableName.valueOf(name.getMethodName());
+    TableName tableName = TableName.valueOf(methodName);
     TEST_UTIL.createTable(tableName, FAM_NAM).close();
     TEST_UTIL.getAdmin().balancerSwitch(false, true);
     try (Connection connection = ConnectionFactory.createConnection(TEST_UTIL.getConfiguration());
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionAttributes.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionAttributes.java
index 5d437881374..7463f37e83d 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionAttributes.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionAttributes.java
@@ -17,7 +17,7 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -29,7 +29,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.AuthUtil;
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.SingleProcessHBaseCluster;
@@ -43,19 +42,15 @@ import org.apache.hadoop.hbase.ipc.RpcServer;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestConnectionAttributes {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestConnectionAttributes.class);
-
   private static final Map<String, byte[]> CONNECTION_ATTRIBUTES = new HashMap<>();
   static {
     CONNECTION_ATTRIBUTES.put("clientId", Bytes.toBytes("foo"));
@@ -66,7 +61,7 @@ public class TestConnectionAttributes {
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static SingleProcessHBaseCluster cluster;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     cluster = TEST_UTIL.startMiniCluster(1);
     Table table = TEST_UTIL.createTable(TABLE_NAME, new byte[][] { FAMILY }, 1,
@@ -74,7 +69,7 @@ public class TestConnectionAttributes {
     table.close();
   }
 
-  @AfterClass
+  @AfterAll
   public static void afterClass() throws Exception {
     cluster.close();
     TEST_UTIL.shutdownMiniCluster();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java
index 6ddded6168b..32ad6c3d6ea 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestConnectionUtils.java
@@ -17,25 +17,20 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.Set;
 import java.util.TreeSet;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ SmallTests.class, ClientTests.class })
+@Tag(SmallTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestConnectionUtils {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestConnectionUtils.class);
-
   @Test
   public void testRetryTimeJitter() {
     long[] retries = new long[200];
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestDropTimeoutRequest.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestDropTimeoutRequest.java
index 09689309d70..44c7aa62fec 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestDropTimeoutRequest.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestDropTimeoutRequest.java
@@ -22,7 +22,6 @@ import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicLong;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -30,34 +29,24 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
 import org.apache.hadoop.hbase.coprocessor.RegionObserver;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.Threads;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 
 /**
  * Test a drop timeout request. This test used to be in TestHCM but it has particulare requirements
  * -- i.e. one handler only -- so run it apart from the rest of TestHCM.
  */
-@Category({ MediumTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestDropTimeoutRequest {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestDropTimeoutRequest.class);
-
-  @Rule
-  public TestName name = new TestName();
-
-  private static final Logger LOG = LoggerFactory.getLogger(TestDropTimeoutRequest.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final byte[] FAM_NAM = Bytes.toBytes("f");
   private static final int RPC_RETRY = 5;
@@ -88,7 +77,7 @@ public class TestDropTimeoutRequest {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.getConfiguration().setBoolean(HConstants.STATUS_PUBLISHED, true);
     // Up the handlers; this test needs more than usual.
@@ -100,19 +89,19 @@ public class TestDropTimeoutRequest {
 
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
 
   @Test
-  public void testDropTimeoutRequest() throws Exception {
+  public void testDropTimeoutRequest(TestInfo testInfo) throws Exception {
     // Simulate the situation that the server is slow and client retries for several times because
     // of timeout. When a request can be handled after waiting in the queue, we will drop it if
     // it has been considered as timeout at client. If we don't drop it, the server will waste time
     // on handling timeout requests and finally all requests timeout and client throws exception.
-    TableDescriptorBuilder builder =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
+    TableDescriptorBuilder builder = TableDescriptorBuilder
+      .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName()));
     builder.setCoprocessor(SleepLongerAtFirstCoprocessor.class.getName());
     ColumnFamilyDescriptor cfd = ColumnFamilyDescriptorBuilder.newBuilder(FAM_NAM).build();
     builder.setColumnFamily(cfd);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestEnableTable.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestEnableTable.java
index 2384e02955d..85b204f2790 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestEnableTable.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestEnableTable.java
@@ -17,13 +17,12 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.MetaTableAccessor;
@@ -36,38 +35,30 @@ import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Category({ MasterTests.class, MediumTests.class })
+@Tag(MasterTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestEnableTable {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestEnableTable.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final Logger LOG = LoggerFactory.getLogger(TestEnableTable.class);
   private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
 
-  @Rule
-  public TestName name = new TestName();
-
-  @Before
+  @BeforeEach
   public void setUp() throws Exception {
     TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
       MasterSyncObserver.class.getName());
     TEST_UTIL.startMiniCluster(1);
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
@@ -78,9 +69,9 @@ public class TestEnableTable {
    * made with the same name. HBASE-12980
    */
   @Test
-  public void testDeleteForSureClearsAllTableRowsFromMeta()
+  public void testDeleteForSureClearsAllTableRowsFromMeta(TestInfo testInfo)
     throws IOException, InterruptedException {
-    final TableName tableName = TableName.valueOf(name.getMethodName());
+    final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());
     final Admin admin = TEST_UTIL.getAdmin();
     TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILYNAME)).build();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
index 5d2b2f684e1..e271f7472d9 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFailedMetaReplicaAssigment.java
@@ -17,16 +17,15 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.StartTestingClusterOption;
@@ -42,22 +41,18 @@ import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;
 import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
-@Category({ MiscTests.class, MediumTests.class })
+@Tag(MiscTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestFailedMetaReplicaAssigment {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestFailedMetaReplicaAssigment.class);
-
   private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     // using our rigged master, to force a failed meta replica assignment when start up master
     // this test can be removed once we remove the HConstants.META_REPLICAS_NUM config.
@@ -69,7 +64,7 @@ public class TestFailedMetaReplicaAssigment {
     TEST_UTIL.startMiniCluster(option);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws IOException {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFallbackToUseReplay.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFallbackToUseReplay.java
index 44c096f0b8a..950c49d79ad 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFallbackToUseReplay.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFallbackToUseReplay.java
@@ -17,7 +17,7 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
@@ -32,7 +32,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.HRegionLocation;
 import org.apache.hadoop.hbase.ServerName;
@@ -42,11 +41,10 @@ import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
 import org.apache.hadoop.hbase.testclassification.SmallTests;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;
@@ -58,13 +56,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminServic
  * Make sure we could fallback to use replay method if replicateToReplica method is not present,
  * i.e, we are connecting an old region server.
  */
-@Category({ RegionServerTests.class, SmallTests.class })
+@Tag(RegionServerTests.TAG)
+@Tag(SmallTests.TAG)
 public class TestFallbackToUseReplay {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestFallbackToUseReplay.class);
-
   private static Configuration CONF = HBaseConfiguration.create();
 
   private static AsyncClusterConnectionImpl CONN;
@@ -76,7 +71,7 @@ public class TestFallbackToUseReplay {
 
   private static AtomicBoolean REPLAY_CALLED = new AtomicBoolean(false);
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws IOException {
     CONF.setInt(AsyncConnectionConfiguration.START_LOG_ERRORS_AFTER_COUNT_KEY, 0);
     AsyncRegionLocator locator = mock(AsyncRegionLocator.class);
@@ -116,7 +111,7 @@ public class TestFallbackToUseReplay {
       Collections.emptyList());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws IOException {
     Closeables.close(CONN, true);
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClient.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClient.java
index ed41ce49fac..3d17f2d45d1 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClient.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClient.java
@@ -17,11 +17,11 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -30,7 +30,6 @@ import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.regionserver.HRegion;
@@ -41,27 +40,22 @@ import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FutureUtils;
 import org.apache.hadoop.hbase.util.JVMClusterUtil;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestFlushFromClient {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestFlushFromClient.class);
-
   private static final Logger LOG = LoggerFactory.getLogger(TestFlushFromClient.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static AsyncConnection asyncConn;
@@ -71,26 +65,24 @@ public class TestFlushFromClient {
   private static final byte[] FAMILY_1 = Bytes.toBytes("f1");
   private static final byte[] FAMILY_2 = Bytes.toBytes("f2");
   public static final byte[][] FAMILIES = { FAMILY_1, FAMILY_2 };
-  @Rule
-  public TestName name = new TestName();
 
   public TableName tableName;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(ROWS.size());
     asyncConn = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(asyncConn, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
-  public void setUp() throws Exception {
-    tableName = TableName.valueOf(name.getMethodName());
+  @BeforeEach
+  public void setUp(TestInfo testInfo) throws Exception {
+    tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());
     try (Table t = TEST_UTIL.createTable(tableName, FAMILIES, SPLITS)) {
       List<Put> puts = ROWS.stream().map(r -> new Put(r)).collect(Collectors.toList());
       for (int i = 0; i != 20; ++i) {
@@ -106,7 +98,7 @@ public class TestFlushFromClient {
     assertTrue(getRegionInfo().stream().allMatch(r -> r.getMemStoreDataSize() != 0));
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     for (TableDescriptor htd : TEST_UTIL.getAdmin().listTableDescriptors()) {
       LOG.info("Tear down, remove table=" + htd.getTableName());
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClientWithDisabledFlushProcedure.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClientWithDisabledFlushProcedure.java
index 732e1c53c54..fb71a1eccfa 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClientWithDisabledFlushProcedure.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestFlushFromClientWithDisabledFlushProcedure.java
@@ -17,14 +17,13 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.procedure.flush.MasterFlushTableProcedureManager;
@@ -34,27 +33,22 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.FutureUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
 
-@Category({ MediumTests.class, ClientTests.class })
+@Tag(MediumTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestFlushFromClientWithDisabledFlushProcedure {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestFlushFromClientWithDisabledFlushProcedure.class);
-
   private static final Logger LOG =
     LoggerFactory.getLogger(TestFlushFromClientWithDisabledFlushProcedure.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
@@ -62,12 +56,9 @@ public class TestFlushFromClientWithDisabledFlushProcedure {
   private static final byte[] FAMILY = Bytes.toBytes("info");
   private static final byte[] QUALIFIER = Bytes.toBytes("name");
 
-  @Rule
-  public TestName name = new TestName();
-
   private TableName tableName;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     Configuration configuration = TEST_UTIL.getConfiguration();
     configuration.setBoolean(MasterFlushTableProcedureManager.FLUSH_PROCEDURE_ENABLED, false);
@@ -75,15 +66,15 @@ public class TestFlushFromClientWithDisabledFlushProcedure {
     asyncConn = ConnectionFactory.createAsyncConnection(TEST_UTIL.getConfiguration()).get();
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(asyncConn, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
-  public void setUp() throws Exception {
-    tableName = TableName.valueOf(name.getMethodName());
+  @BeforeEach
+  public void setUp(TestInfo testInfo) throws Exception {
+    tableName = TableName.valueOf(testInfo.getTestMethod().get().getName());
     try (Table t = TEST_UTIL.createTable(tableName, FAMILY)) {
       List<Put> puts = new ArrayList<>();
       for (int i = 0; i <= 10; ++i) {
@@ -97,7 +88,7 @@ public class TestFlushFromClientWithDisabledFlushProcedure {
     assertFalse(regions.isEmpty());
   }
 
-  @After
+  @AfterEach
   public void tearDown() throws Exception {
     for (TableDescriptor htd : TEST_UTIL.getAdmin().listTableDescriptors()) {
       LOG.info("Tear down, remove table=" + htd.getTableName());
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetProcedureResult.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetProcedureResult.java
index baf2f1bf0a0..1820df79d67 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetProcedureResult.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetProcedureResult.java
@@ -17,11 +17,10 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.MasterNotRunningException;
 import org.apache.hadoop.hbase.TableName;
@@ -35,11 +34,10 @@ import org.apache.hadoop.hbase.procedure2.ProcedureSuspendedException;
 import org.apache.hadoop.hbase.procedure2.ProcedureYieldException;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 import org.apache.hbase.thirdparty.com.google.protobuf.ServiceException;
 
@@ -49,13 +47,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProtos.GetProcedu
 /**
  * Testcase for HBASE-19608.
  */
-@Category({ MasterTests.class, MediumTests.class })
+@Tag(MasterTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestGetProcedureResult {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestGetProcedureResult.class);
-
   private static final HBaseTestingUtil UTIL = new HBaseTestingUtil();
 
   public static final class DummyProcedure extends Procedure<MasterProcedureEnv>
@@ -102,12 +97,12 @@ public class TestGetProcedureResult {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     UTIL.startMiniCluster(1);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanColumnsWithNewVersionBehavior.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanColumnsWithNewVersionBehavior.java
index 51c47b8549c..92e9e410648 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanColumnsWithNewVersionBehavior.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanColumnsWithNewVersionBehavior.java
@@ -17,35 +17,30 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
 
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.hadoop.hbase.Cell;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 /**
  * Testcase for HBASE-21032, where use the wrong readType from a Scan instance which is actually a
  * get scan and cause returning only 1 cell per rpc call.
  */
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestGetScanColumnsWithNewVersionBehavior {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestGetScanColumnsWithNewVersionBehavior.class);
-
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final TableName TABLE = TableName.valueOf("table");
   private static final byte[] CF = { 'c', 'f' };
@@ -55,7 +50,7 @@ public class TestGetScanColumnsWithNewVersionBehavior {
   private static final byte[] COLC = { 'c' };
   private static final long TS = 42;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.startMiniCluster(1);
     ColumnFamilyDescriptor cd =
@@ -64,7 +59,7 @@ public class TestGetScanColumnsWithNewVersionBehavior {
       null);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanPartialResult.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanPartialResult.java
index b390ebfc509..bc245fb12bb 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanPartialResult.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestGetScanPartialResult.java
@@ -17,33 +17,28 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 /**
  * Testcase for HBASE-21032, where use the wrong readType from a Scan instance which is actually a
  * get scan and cause returning only 1 cell per rpc call.
  */
-@Category({ ClientTests.class, MediumTests.class })
+@Tag(ClientTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestGetScanPartialResult {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestGetScanPartialResult.class);
-
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static final TableName TABLE = TableName.valueOf("table");
   private static final byte[] CF = { 'c', 'f' };
@@ -51,13 +46,13 @@ public class TestGetScanPartialResult {
   private static final int VALUE_SIZE = 10000;
   private static final int NUM_COLUMNS = 300;
 
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     TEST_UTIL.startMiniCluster();
     TEST_UTIL.createTable(TABLE, CF);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDown() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
index 360641e64b7..1b4235496fc 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
@@ -17,10 +17,10 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.io.IOException;
 import java.time.Instant;
@@ -33,9 +33,10 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import org.apache.hadoop.hbase.Coprocessor;
 import org.apache.hadoop.hbase.CoprocessorEnvironment;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseParameterizedTestTemplate;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.ServerName;
 import org.apache.hadoop.hbase.TableName;
@@ -58,18 +59,12 @@ import org.apache.hadoop.hbase.regionserver.HRegionServer;
 import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-import org.junit.runners.Parameterized.Parameters;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.params.provider.Arguments;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -79,21 +74,15 @@ import org.apache.hbase.thirdparty.com.google.common.io.Closeables;
  * Class to test HBaseHbck. Spins up the minicluster once at test start and then takes it down
  * afterward. Add any testing of HBaseHbck functionality here.
  */
-@RunWith(Parameterized.class)
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
+@HBaseParameterizedTestTemplate(name = "{index}: async={0}")
 public class TestHbck {
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestHbck.class);
 
   private static final Logger LOG = LoggerFactory.getLogger(TestHbck.class);
   private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
-  @Rule
-  public TestName name = new TestName();
-
-  @SuppressWarnings("checkstyle:VisibilityModifier")
-  @Parameter
-  public boolean async;
+  private final boolean async;
 
   private static final TableName TABLE_NAME = TableName.valueOf(TestHbck.class.getSimpleName());
 
@@ -101,9 +90,12 @@ public class TestHbck {
 
   private static AsyncConnection ASYNC_CONN;
 
-  @Parameters(name = "{index}: async={0}")
-  public static List<Object[]> params() {
-    return Arrays.asList(new Object[] { false }, new Object[] { true });
+  public static Stream<Arguments> parameters() {
+    return Stream.of(Arguments.of(false), Arguments.of(true));
+  }
+
+  public TestHbck(boolean async) {
+    this.async = async;
   }
 
   private Hbck getHbck() throws Exception {
@@ -114,7 +106,7 @@ public class TestHbck {
     }
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     TEST_UTIL.startMiniCluster(3);
     TEST_UTIL.createMultiRegionTable(TABLE_NAME, 3, new byte[][] { Bytes.toBytes("family1") });
@@ -128,13 +120,13 @@ public class TestHbck {
       TEST_UTIL.getHBaseCluster().getMaster().getConfiguration());
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     Closeables.close(ASYNC_CONN, true);
     TEST_UTIL.shutdownMiniCluster();
   }
 
-  @Before
+  @BeforeEach
   public void setUp() throws IOException {
     TEST_UTIL.ensureSomeRegionServersAvailable(3);
   }
@@ -163,7 +155,7 @@ public class TestHbck {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testBypassProcedure() throws Exception {
     // SuspendProcedure
     final SuspendProcedure proc = new SuspendProcedure();
@@ -173,12 +165,12 @@ public class TestHbck {
     // bypass the procedure
     List<Long> pids = Arrays.<Long> asList(procId);
     List<Boolean> results = getHbck().bypassProcedure(pids, 30000, false, false);
-    assertTrue("Failed to by pass procedure!", results.get(0));
+    assertTrue(results.get(0), "Failed to by pass procedure!");
     TEST_UTIL.waitFor(5000, () -> proc.isSuccess() && proc.isBypass());
     LOG.info("{} finished", proc);
   }
 
-  @Test
+  @TestTemplate
   public void testSetTableStateInMeta() throws Exception {
     Hbck hbck = getHbck();
     // set table state to DISABLED
@@ -187,11 +179,11 @@ public class TestHbck {
     // will be DISABLED
     TableState prevState =
       hbck.setTableStateInMeta(new TableState(TABLE_NAME, TableState.State.ENABLED));
-    assertTrue("Incorrect previous state! expected=DISABLED, found=" + prevState.getState(),
-      prevState.isDisabled());
+    assertTrue(prevState.isDisabled(),
+      "Incorrect previous state! expected=DISABLED, found=" + prevState.getState());
   }
 
-  @Test
+  @TestTemplate
   public void testSetRegionStateInMeta() throws Exception {
     Hbck hbck = getHbck();
     Admin admin = TEST_UTIL.getAdmin();
@@ -213,14 +205,14 @@ public class TestHbck {
       Map<String, RegionState.State> result = hbck.setRegionStateInMeta(requestStates);
       result.forEach((k, v) -> {
         RegionState.State beforeState = beforeStates.get(k);
-        assertEquals("response state should match before state; " + k, beforeState, v);
+        assertEquals(beforeState, v, "response state should match before state; " + k);
       });
       regions.forEach(r -> {
         RegionState afterState = am.getRegionStates().getRegionState(r.getEncodedName());
         RegionState.State expectedState = requestStates.get(r.getEncodedName());
         LOG.debug("After test: {}, {}", r, afterState);
-        assertEquals("state in AM should match requested state ; " + r, expectedState,
-          afterState.getState());
+        assertEquals(expectedState, afterState.getState(),
+          "state in AM should match requested state ; " + r);
       });
       return null;
     };
@@ -229,7 +221,7 @@ public class TestHbck {
     hbck.setRegionStateInMeta(beforeStates);
   }
 
-  @Test
+  @TestTemplate
   public void testAssigns() throws Exception {
     Hbck hbck = getHbck();
     final AssignmentManager am = TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager();
@@ -274,7 +266,7 @@ public class TestHbck {
         RegionState rs = TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager()
           .getRegionStates().getRegionState(ri.getEncodedName());
         LOG.info("RS: {}", rs.toString());
-        assertTrue(rs.toString(), rs.isClosed());
+        assertTrue(rs.isClosed(), rs.toString());
       }
       pids =
         hbck.assigns(regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()));
@@ -290,7 +282,7 @@ public class TestHbck {
         RegionState rs = TEST_UTIL.getHBaseCluster().getMaster().getAssignmentManager()
           .getRegionStates().getRegionState(ri.getEncodedName());
         LOG.info("RS: {}", rs.toString());
-        assertTrue(rs.toString(), rs.isOpened());
+        assertTrue(rs.isOpened(), rs.toString());
       }
       // Rerun the assign with override. Should fail for all Regions since they already assigned
       pids = hbck.assigns(
@@ -307,7 +299,7 @@ public class TestHbck {
     }
   }
 
-  @Test
+  @TestTemplate
   public void testScheduleSCP() throws Exception {
     HRegionServer testRs = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME);
     try (final Table t = TEST_UTIL.getConnection().getTable(TABLE_NAME)) {
@@ -326,7 +318,7 @@ public class TestHbck {
     waitOnPids(pids);
   }
 
-  @Test
+  @TestTemplate
   public void testRunHbckChore() throws Exception {
     HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
     HbckChore hbckChore = master.getHbckChore();
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
index 9b314ba87c5..b025bdc26b6 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIllegalTableDescriptor.java
@@ -17,9 +17,9 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 import static org.mockito.ArgumentMatchers.contains;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -27,7 +27,6 @@ import static org.mockito.Mockito.verify;
 import java.io.IOException;
 import java.lang.reflect.Field;
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableName;
@@ -38,37 +37,33 @@ import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.TableDescriptorChecker;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 
-@Category({ LargeTests.class, ClientTests.class })
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestIllegalTableDescriptor {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestIllegalTableDescriptor.class);
-
   // NOTE: Increment tests were moved to their own class, TestIncrementsFromClientSide.
-  private static final Logger LOGGER;
+  private static final Logger LOGGER = mock(Logger.class);
 
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
 
   private static byte[] FAMILY = Bytes.toBytes("testFamily");
 
-  @Rule
-  public TestName name = new TestName();
+  private String methodName;
 
-  static {
-    LOGGER = mock(Logger.class);
+  @BeforeEach
+  public void setUp(TestInfo testInfo) {
+    methodName = testInfo.getTestMethod().get().getName();
   }
 
-  @BeforeClass
+  @BeforeAll
   public static void setUpBeforeClass() throws Exception {
     // replacing HMaster.LOG with our mock logger for verifying logging
     Field field = TableDescriptorChecker.class.getDeclaredField("LOG");
@@ -79,7 +74,7 @@ public class TestIllegalTableDescriptor {
     TEST_UTIL.startMiniCluster(1);
   }
 
-  @AfterClass
+  @AfterAll
   public static void tearDownAfterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
@@ -87,7 +82,7 @@ public class TestIllegalTableDescriptor {
   @Test
   public void testIllegalTableDescriptor() throws Exception {
     TableDescriptorBuilder builder =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName));
     ColumnFamilyDescriptorBuilder cfBuilder = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
 
     // create table with 0 families
@@ -194,7 +189,7 @@ public class TestIllegalTableDescriptor {
   public void testIllegalTableDescriptorWithDataTiering() throws IOException {
     // table level configuration changes
     TableDescriptorBuilder builder =
-      TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
+      TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName));
     ColumnFamilyDescriptorBuilder cfBuilder = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
     builder.setColumnFamily(cfBuilder.build());
 
@@ -214,7 +209,7 @@ public class TestIllegalTableDescriptor {
 
     // column family level configuration changes
     for (boolean viaSetValue : new boolean[] { false, true }) {
-      builder = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()));
+      builder = TableDescriptorBuilder.newBuilder(TableName.valueOf(methodName));
       cfBuilder = ColumnFamilyDescriptorBuilder.newBuilder(FAMILY);
 
       // First scenario: DataTieringType set to TIME_RANGE without DateTieredStoreEngine
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncreaseMetaReplicaThroughConfig.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncreaseMetaReplicaThroughConfig.java
index f93fc9d5bf5..4c5588b7598 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncreaseMetaReplicaThroughConfig.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncreaseMetaReplicaThroughConfig.java
@@ -17,31 +17,26 @@
  */
 package org.apache.hadoop.hbase.client;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.TableDescriptors;
 import org.apache.hadoop.hbase.TableName;
 import org.apache.hadoop.hbase.master.HMaster;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 
 /**
  * Make sure we will honor the {@link HConstants#META_REPLICAS_NUM}.And also test upgrading.
  */
-@Category({ MiscTests.class, MediumTests.class })
+@Tag(MiscTests.TAG)
+@Tag(MediumTests.TAG)
 public class TestIncreaseMetaReplicaThroughConfig extends MetaWithReplicasTestBase {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestIncreaseMetaReplicaThroughConfig.class);
-
-  @BeforeClass
+  @BeforeAll
   public static void setUp() throws Exception {
     startCluster();
   }
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementFromClientSideWithCoprocessor.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementFromClientSideWithCoprocessor.java
index c453e013ebc..7179b4554e4 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementFromClientSideWithCoprocessor.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementFromClientSideWithCoprocessor.java
@@ -18,28 +18,24 @@
 package org.apache.hadoop.hbase.client;
 
 import org.apache.hadoop.conf.Configuration;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
 import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint;
 import org.apache.hadoop.hbase.regionserver.NoOpScanPolicyObserver;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.experimental.categories.Category;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
 
 /**
  * Test all {@link Increment} client operations with a coprocessor that just implements the default
  * flush/compact/scan policy. This test takes a long time. The test it derives from is parameterized
  * so we run through both options of the test.
  */
-@Category(LargeTests.class)
+@Tag(LargeTests.TAG)
+@Tag(ClientTests.TAG)
 public class TestIncrementFromClientSideWithCoprocessor extends TestIncrementsFromClientSide {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestIncrementFromClientSideWithCoprocessor.class);
-
-  @Before
+  @BeforeEach
   public void before() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     conf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java
index 1e8cdb2f320..9893497ba42 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestIncrementsFromClientSide.java
@@ -19,11 +19,11 @@ package org.apache.hadoop.hbase.client;
 
 import static org.apache.hadoop.hbase.HConstants.RPC_CODEC_CONF_KEY;
 import static org.apache.hadoop.hbase.ipc.RpcClient.DEFAULT_CODEC_CLASS;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -37,7 +37,6 @@ import org.apache.hadoop.hbase.CellBuilderType;
 import org.apache.hadoop.hbase.DoNotRetryIOException;
 import org.apache.hadoop.hbase.ExtendedCell;
 import org.apache.hadoop.hbase.ExtendedCellBuilderFactory;
-import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.HBaseTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.KeyValue;
@@ -48,15 +47,14 @@ import org.apache.hadoop.hbase.TagType;
 import org.apache.hadoop.hbase.codec.KeyValueCodecWithTags;
 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
 import org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint;
+import org.apache.hadoop.hbase.testclassification.ClientTests;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.util.Bytes;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -67,13 +65,10 @@ import org.slf4j.LoggerFactory;
  * should be faster than starting/stopping a cluster per test. Test takes a long time because spin
  * up a cluster between each run -- ugh.
  */
-@Category(LargeTests.class)
+@org.junit.jupiter.api.Tag(LargeTests.TAG)
+@org.junit.jupiter.api.Tag(ClientTests.TAG)
 public class TestIncrementsFromClientSide {
 
-  @ClassRule
-  public static final HBaseClassTestRule CLASS_RULE =
-    HBaseClassTestRule.forClass(TestIncrementsFromClientSide.class);
-
   final Logger LOG = LoggerFactory.getLogger(getClass());
   protected final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil();
   private static byte[] ROW = Bytes.toBytes("testRow");
@@ -82,10 +77,14 @@ public class TestIncrementsFromClientSide {
   // This test depends on there being only one slave running at at a time. See the @Before
   // method where we do rolling restart.
   protected static int SLAVES = 1;
-  @Rule
-  public TestName name = new TestName();
+  private String methodName;
+
+  @BeforeEach
+  public void setUp(TestInfo testInfo) {
+    methodName = testInfo.getTestMethod().get().getName();
+  }
 
-  @BeforeClass
+  @BeforeAll
   public static void beforeClass() throws Exception {
     Configuration conf = TEST_UTIL.getConfiguration();
     conf.setStrings(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY,
@@ -94,10 +93,7 @@ public class TestIncrementsFromClientSide {
     TEST_UTIL.startMiniCluster(SLAVES);
   }
 
-  /**
-   * @throws java.lang.Exception
-   */
-  @AfterClass
+  @AfterAll
   public static void afterClass() throws Exception {
     TEST_UTIL.shutdownMiniCluster();
   }
@@ -107,8 +103,7 @@ public class TestIncrementsFromClientSide {
    */
   @Test
   public void testDuplicateIncrement() throws Exception {
-    TableDescriptorBuilder builder =
-      TEST_UTIL.createModifyableTableDescriptor(name.getMethodName());
+    TableDescriptorBuilder builder = TEST_UTIL.createModifyableTableDescriptor(methodName);
     Map<String, String> kvs = new HashMap<>();
     kvs.put(SleepAtFirstRpcCall.SLEEP_TIME_CONF_KEY, "2000");
     builder.setCoprocessor(CoprocessorDescriptorBuilder
@@ -120,9 +115,8 @@ public class TestIncrementsFromClientSide {
     // Client will retry beacuse rpc timeout is small than the sleep time of first rpc call
     c.setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
 
-    try (Connection connection = ConnectionFactory.createConnection(c);
-      Table table = connection.getTableBuilder(TableName.valueOf(name.getMethodName()), null)
-        .setOperationTimeout(3 * 1000).build()) {
+    try (Connection connection = ConnectionFactory.createConnection(c); Table table = connection
+      .getTableBuilder(TableName.valueOf(methodName), null).setOperationTimeout(3 * 1000).build()) {
       Increment inc = new Increment(ROW);
       inc.addColumn(HBaseTestingUtil.fam1, QUALIFIER, 1);
       Result result = table.increment(inc);
@@ -144,8 +138,7 @@ public class TestIncrementsFromClientSide {
    */
... 7985 lines suppressed ...