private void waitAndVerifyRegionNum(HMaster master, TableName tablename, int expectedRegionNum)
    throws Exception {
    List<Pair<RegionInfo, ServerName>> tableRegionsInMeta;
    List<RegionInfo> tableRegionsInMaster;
    long timeout = EnvironmentEdgeManager.currentTime() + waitTime;
    while (EnvironmentEdgeManager.currentTime() < timeout) {
      tableRegionsInMeta =
        MetaTableAccessor.getTableRegionsAndLocations(TEST_UTIL.getConnection(), tablename);
      tableRegionsInMaster =
        master.getAssignmentManager().getRegionStates().getRegionsOfTable(tablename);
      LOG.info(Objects.toString(tableRegionsInMaster));
      LOG.info(Objects.toString(tableRegionsInMeta));
      int tableRegionsInMetaSize = tableRegionsInMeta.size();
      int tableRegionsInMasterSize = tableRegionsInMaster.size();
      if (
        tableRegionsInMetaSize == expectedRegionNum && tableRegionsInMasterSize == expectedRegionNum
      ) {
        break;
      }
      Thread.sleep(250);
    }

    tableRegionsInMeta =
      MetaTableAccessor.getTableRegionsAndLocations(TEST_UTIL.getConnection(), tablename);
    LOG.info("Regions after merge:" + Joiner.on(',').join(tableRegionsInMeta));
    assertEquals(expectedRegionNum, tableRegionsInMeta.size());
  }
This test tests 1, merging region not online; 2, merging same two regions; 3, merging unknown
regions. They are in one test case so that we don't have to create many tables, and these tests
are simple.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java