You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kafka.apache.org by ch...@apache.org on 2024/06/20 01:24:52 UTC

(kafka) branch trunk updated: KAFKA-15623 (2/N) Migrate remaining tests in streams module to JUnit 5 (integration & internals) (#16360)

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

chia7712 pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/kafka.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 26b9163487a KAFKA-15623 (2/N) Migrate remaining tests in streams module to JUnit 5 (integration & internals) (#16360)
26b9163487a is described below

commit 26b9163487a9faf6afd78abea6b65e710ed82ed1
Author: Kuan-Po (Cooper) Tseng <br...@gmail.com>
AuthorDate: Thu Jun 20 09:24:44 2024 +0800

    KAFKA-15623 (2/N) Migrate remaining tests in streams module to JUnit 5 (integration & internals) (#16360)
    
    Reviewers: Chia-Ping Tsai <ch...@gmail.com>
---
 checkstyle/suppressions.xml                        |   6 +-
 .../integration/AbstractJoinIntegrationTest.java   |  94 ++--
 .../integration/AbstractResetIntegrationTest.java  |  55 +--
 .../integration/AdjustStreamThreadCountTest.java   |   5 +-
 .../ConsistencyVectorIntegrationTest.java          |  31 +-
 .../EOSUncleanShutdownIntegrationTest.java         |  61 +--
 .../integration/EmitOnChangeIntegrationTest.java   |   1 +
 .../streams/integration/EosIntegrationTest.java    | 208 +++++----
 .../integration/EosV2UpgradeIntegrationTest.java   |  81 ++--
 .../FineGrainedAutoResetIntegrationTest.java       |   2 +-
 .../GlobalKTableEOSIntegrationTest.java            | 124 +++---
 .../integration/GlobalKTableIntegrationTest.java   |   1 +
 .../integration/GlobalStateReprocessTest.java      |   1 +
 .../integration/GlobalThreadShutDownOrderTest.java |   1 +
 ...ighAvailabilityTaskAssignorIntegrationTest.java |  25 +-
 .../streams/integration/IQv2IntegrationTest.java   |   1 +
 .../integration/IQv2StoreIntegrationTest.java      | 116 +++--
 .../IQv2VersionedStoreIntegrationTest.java         |  62 +--
 .../integration/InternalTopicIntegrationTest.java  |   1 +
 .../JoinGracePeriodDurabilityIntegrationTest.java  |  57 +--
 .../integration/JoinStoreIntegrationTest.java      |  58 +--
 .../JoinWithIncompleteMetadataIntegrationTest.java |  51 +--
 .../KStreamAggregationDedupIntegrationTest.java    |   1 +
 .../KStreamAggregationIntegrationTest.java         |   3 +-
 .../integration/KStreamKStreamIntegrationTest.java |   1 +
 .../KStreamRepartitionIntegrationTest.java         | 196 ++++----
 .../KStreamTransformIntegrationTest.java           |  40 +-
 .../integration/KTableEfficientRangeQueryTest.java |  73 +--
 ...yInnerJoinCustomPartitionerIntegrationTest.java |  23 +-
 ...bleForeignKeyInnerJoinMultiIntegrationTest.java |   3 +-
 .../KTableKTableForeignKeyJoinDistributedTest.java |   5 +-
 .../KTableKTableForeignKeyJoinIntegrationTest.java | 465 ++++++++++++++++---
 ...reignKeyJoinMaterializationIntegrationTest.java |  69 +--
 ...ableForeignKeyVersionedJoinIntegrationTest.java | 317 -------------
 .../KTableSourceTopicRestartIntegrationTest.java   |   1 +
 .../KafkaStreamsCloseOptionsIntegrationTest.java   |  46 +-
 .../integration/LagFetchIntegrationTest.java       |   3 +-
 .../integration/MetricsIntegrationTest.java        |   3 +-
 .../MetricsReporterIntegrationTest.java            |   3 +-
 .../integration/NamedTopologyIntegrationTest.java  |  19 +-
 .../OptimizedKTableIntegrationTest.java            |  38 +-
 .../integration/PauseResumeIntegrationTest.java    |  31 +-
 .../PositionRestartIntegrationTest.java            | 162 +++----
 .../PurgeRepartitionTopicIntegrationTest.java      |   3 +-
 .../integration/QueryableStateIntegrationTest.java |   3 +-
 .../integration/RangeQueryIntegrationTest.java     |  77 ++--
 .../integration/RegexSourceIntegrationTest.java    |   3 +-
 .../RelaxedNullKeyRequirementJoinTest.java         |   1 +
 .../streams/integration/ResetIntegrationTest.java  |  92 ++--
 .../integration/ResetIntegrationWithSslTest.java   |  27 +-
 .../ResetPartitionTimeIntegrationTest.java         |  52 +--
 .../integration/RestoreIntegrationTest.java        |  22 +-
 .../integration/RocksDBMetricsIntegrationTest.java |  69 +--
 .../SelfJoinUpgradeIntegrationTest.java            |  60 ++-
 .../SlidingWindowedKStreamIntegrationTest.java     | 108 ++---
 .../SmokeTestDriverIntegrationTest.java            |  15 +-
 .../StandbyTaskCreationIntegrationTest.java        |   3 +-
 .../integration/StandbyTaskEOSIntegrationTest.java |  90 ++--
 ...tandbyTaskEOSMultiRebalanceIntegrationTest.java |  26 +-
 .../integration/StateDirectoryIntegrationTest.java |  51 +--
 .../integration/StoreQueryIntegrationTest.java     |  17 +-
 .../kafka/streams/integration/StoreQuerySuite.java |   1 +
 .../integration/StoreUpgradeIntegrationTest.java   |  38 +-
 .../StreamStreamJoinIntegrationTest.java           | 144 +++---
 .../StreamTableJoinIntegrationTest.java            | 110 ++---
 ...bleJoinTopologyOptimizationIntegrationTest.java |  90 ++--
 .../StreamTableJoinWithGraceIntegrationTest.java   |  79 ++--
 ...amsUncaughtExceptionHandlerIntegrationTest.java |  61 +--
 .../StreamsUpgradeTestIntegrationTest.java         |  23 +-
 .../SuppressionDurabilityIntegrationTest.java      |  55 +--
 .../integration/SuppressionIntegrationTest.java    |  22 +-
 .../integration/TableTableJoinIntegrationTest.java | 495 +++++++++++----------
 .../integration/TaskAssignorIntegrationTest.java   |  31 +-
 .../integration/TaskMetadataIntegrationTest.java   |  39 +-
 .../TimeWindowedKStreamIntegrationTest.java        | 122 ++---
 .../VersionedKeyValueStoreIntegrationTest.java     |  70 ++-
 .../integration/utils/IntegrationTestUtils.java    |   9 +-
 .../kafka/streams/internals/ApiUtilsTest.java      |   1 -
 .../internals/metrics/ClientMetricsTest.java       |   9 +-
 79 files changed, 2156 insertions(+), 2506 deletions(-)

diff --git a/checkstyle/suppressions.xml b/checkstyle/suppressions.xml
index 1516776e8bd..349a60ba40c 100644
--- a/checkstyle/suppressions.xml
+++ b/checkstyle/suppressions.xml
@@ -245,19 +245,19 @@
               files=".*[/\\]streams[/\\].*test[/\\].*.java"/>
 
     <suppress checks="CyclomaticComplexity"
-              files="(EosV2UpgradeIntegrationTest|KStreamKStreamJoinTest|KTableKTableForeignKeyJoinIntegrationTest|KTableKTableForeignKeyVersionedJoinIntegrationTest|RocksDBGenericOptionsToDbOptionsColumnFamilyOptionsAdapterTest|RelationalSmokeTest|MockProcessorContextStateStoreTest|IQv2StoreIntegrationTest).java"/>
+              files="(EosV2UpgradeIntegrationTest|KStreamKStreamJoinTest|KTableKTableForeignKeyJoinIntegrationTest|RocksDBGenericOptionsToDbOptionsColumnFamilyOptionsAdapterTest|RelationalSmokeTest|MockProcessorContextStateStoreTest|IQv2StoreIntegrationTest).java"/>
 
     <suppress checks="JavaNCSS"
               files="(EosV2UpgradeIntegrationTest|KStreamKStreamJoinTest|StreamThreadTest|TaskManagerTest|StreamTaskTest).java"/>
 
     <suppress checks="NPathComplexity"
-              files="(EosV2UpgradeIntegrationTest|EosTestDriver|KStreamKStreamJoinTest|KTableKTableForeignKeyJoinIntegrationTest|KTableKTableForeignKeyVersionedJoinIntegrationTest|RelationalSmokeTest|MockProcessorContextStateStoreTest|TopologyTestDriverTest|IQv2StoreIntegrationTest).java"/>
+              files="(EosV2UpgradeIntegrationTest|EosTestDriver|KStreamKStreamJoinTest|KTableKTableForeignKeyJoinIntegrationTest|RelationalSmokeTest|MockProcessorContextStateStoreTest|TopologyTestDriverTest|IQv2StoreIntegrationTest).java"/>
 
     <suppress checks="(FinalLocalVariable|WhitespaceAround|LocalVariableName|ImportControl|AvoidStarImport)"
               files="Murmur3Test.java"/>
 
     <suppress checks="MethodLength"
-              files="(KStreamSlidingWindowAggregateTest|KStreamKStreamLeftJoinTest|KStreamKStreamOuterJoinTest|KTableKTableForeignKeyVersionedJoinIntegrationTest).java"/>
+              files="(KStreamSlidingWindowAggregateTest|KStreamKStreamLeftJoinTest|KStreamKStreamOuterJoinTest|KTableKTableForeignKeyJoinIntegrationTest).java"/>
 
     <suppress checks="ClassFanOutComplexity"
               files="StreamTaskTest.java"/>
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/AbstractJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/AbstractJoinIntegrationTest.java
index 8d6e2d61c56..3b84f286a7d 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/AbstractJoinIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/AbstractJoinIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.Collections;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.LongDeserializer;
 import org.apache.kafka.common.serialization.LongSerializer;
@@ -25,28 +24,20 @@ import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.common.utils.MockTime;
 import org.apache.kafka.streams.KeyValue;
-import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.TestInputTopic;
 import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.TopologyTestDriver;
 import org.apache.kafka.streams.kstream.ValueJoiner;
 import org.apache.kafka.streams.state.KeyValueIterator;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.test.TestRecord;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.ArrayList;
+
 import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -61,33 +52,14 @@ import static org.hamcrest.core.IsEqual.equalTo;
 /**
  * Tests all available joins of Kafka Streams DSL.
  */
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
 public abstract class AbstractJoinIntegrationTest {
-    @Rule
-    public final TemporaryFolder testFolder = new TemporaryFolder(TestUtils.tempDirectory());
-
-    @Parameterized.Parameters(name = "caching enabled = {0}")
-    public static Collection<Object[]> data() {
-        final List<Object[]> values = new ArrayList<>();
-        for (final boolean cacheEnabled : Arrays.asList(true, false)) {
-            values.add(new Object[]{cacheEnabled});
-        }
-        return values;
-    }
-
-    static String appID;
-
     private final MockTime time = new MockTime();
     private static final Long COMMIT_INTERVAL = 100L;
-    static final Properties STREAMS_CONFIG = new Properties();
     static final String INPUT_TOPIC_RIGHT = "inputTopicRight";
     static final String INPUT_TOPIC_LEFT = "inputTopicLeft";
     static final String OUTPUT_TOPIC = "outputTopic";
     static final long ANY_UNIQUE_KEY = 0L;
 
-    StreamsBuilder builder;
-
     protected final List<Input<String>> input = Arrays.asList(
         new Input<>(INPUT_TOPIC_LEFT, null, 1),
         new Input<>(INPUT_TOPIC_RIGHT, null, 2),
@@ -152,34 +124,36 @@ public abstract class AbstractJoinIntegrationTest {
 
     final ValueJoiner<String, String, String> valueJoiner = (value1, value2) -> value1 + "-" + value2;
 
-    final boolean cacheEnabled;
-
-    AbstractJoinIntegrationTest(final boolean cacheEnabled) {
-        this.cacheEnabled = cacheEnabled;
-    }
-
-    @BeforeClass
-    public static void setupConfigsAndUtils() {
-        STREAMS_CONFIG.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
-        STREAMS_CONFIG.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Long().getClass());
-        STREAMS_CONFIG.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
-        STREAMS_CONFIG.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, COMMIT_INTERVAL);
-    }
-
-    void prepareEnvironment() throws InterruptedException {
+    Properties setupConfigsAndUtils(final boolean cacheEnabled) {
+        final Properties streamsConfig = new Properties();
+        streamsConfig.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
+        streamsConfig.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Long().getClass());
+        streamsConfig.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
+        streamsConfig.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, COMMIT_INTERVAL);
         if (!cacheEnabled) {
-            STREAMS_CONFIG.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
+            streamsConfig.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
         }
 
-        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getRoot().getPath());
+        streamsConfig.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
+
+        return streamsConfig;
     }
 
-    void runTestWithDriver(final List<Input<String>> input, final List<List<TestRecord<Long, String>>> expectedResult) {
-        runTestWithDriver(input, expectedResult, null);
+    void runTestWithDriver(
+            final List<Input<String>> input,
+            final List<List<TestRecord<Long, String>>> expectedResult,
+            final Properties properties,
+            final Topology topology) {
+        runTestWithDriver(input, expectedResult, null, properties, topology);
     }
 
-    void runTestWithDriver(final List<Input<String>> input, final List<List<TestRecord<Long, String>>> expectedResult, final String storeName) {
-        try (final TopologyTestDriver driver = new TopologyTestDriver(builder.build(STREAMS_CONFIG), STREAMS_CONFIG)) {
+    void runTestWithDriver(
+            final List<Input<String>> input,
+            final List<List<TestRecord<Long, String>>> expectedResult,
+            final String storeName,
+            final Properties properties,
+            final Topology topology) {
+        try (final TopologyTestDriver driver = new TopologyTestDriver(topology, properties)) {
             final TestInputTopic<Long, String> right = driver.createInputTopic(INPUT_TOPIC_RIGHT, new LongSerializer(), new StringSerializer());
             final TestInputTopic<Long, String> left = driver.createInputTopic(INPUT_TOPIC_LEFT, new LongSerializer(), new StringSerializer());
             final TestOutputTopic<Long, String> outputTopic = driver.createOutputTopic(OUTPUT_TOPIC, new LongDeserializer(), new StringDeserializer());
@@ -217,8 +191,13 @@ public abstract class AbstractJoinIntegrationTest {
         }
     }
 
-    void runTestWithDriver(final List<Input<String>> input, final TestRecord<Long, String> expectedFinalResult, final String storeName) throws InterruptedException {
-        try (final TopologyTestDriver driver = new TopologyTestDriver(builder.build(STREAMS_CONFIG), STREAMS_CONFIG)) {
+    void runTestWithDriver(
+            final List<Input<String>> input,
+            final TestRecord<Long, String> expectedFinalResult,
+            final String storeName,
+            final Properties streamsConfig,
+            final Topology topology) {
+        try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<Long, String> right = driver.createInputTopic(INPUT_TOPIC_RIGHT, new LongSerializer(), new StringSerializer());
             final TestInputTopic<Long, String> left = driver.createInputTopic(INPUT_TOPIC_LEFT, new LongSerializer(), new StringSerializer());
             final TestOutputTopic<Long, String> outputTopic = driver.createOutputTopic(OUTPUT_TOPIC, new LongDeserializer(), new StringDeserializer());
@@ -250,8 +229,11 @@ public abstract class AbstractJoinIntegrationTest {
         }
     }
 
-    void runSelfJoinTestWithDriver(final List<List<TestRecord<Long, String>>> expectedResult) {
-        try (final TopologyTestDriver driver = new TopologyTestDriver(builder.build(STREAMS_CONFIG), STREAMS_CONFIG)) {
+    void runSelfJoinTestWithDriver(
+            final List<List<TestRecord<Long, String>>> expectedResult,
+            final Properties streamsConfig,
+            final Topology topology) {
+        try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<Long, String> left = driver.createInputTopic(INPUT_TOPIC_LEFT, new LongSerializer(), new StringSerializer());
             final TestOutputTopic<Long, String> outputTopic = driver.createOutputTopic(OUTPUT_TOPIC, new LongDeserializer(), new StringDeserializer());
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/AbstractResetIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/AbstractResetIntegrationTest.java
index fe41e6c1e82..65c2daf5446 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/AbstractResetIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/AbstractResetIntegrationTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import org.apache.kafka.common.utils.Utils;
-import org.apache.kafka.tools.StreamsResetter;
 import org.apache.kafka.clients.CommonClientConfigs;
 import org.apache.kafka.clients.admin.Admin;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
@@ -31,6 +29,7 @@ import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.common.utils.MockTime;
+import org.apache.kafka.common.utils.Utils;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.StreamsBuilder;
@@ -41,15 +40,12 @@ import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.TimeWindows;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.Assert;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+import org.apache.kafka.tools.StreamsResetter;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -66,11 +62,10 @@ import static java.time.Duration.ofMillis;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForEmptyConsumerGroup;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
-@Category({IntegrationTest.class})
+@Timeout(600)
 public abstract class AbstractResetIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     static EmbeddedKafkaCluster cluster;
 
@@ -80,9 +75,6 @@ public abstract class AbstractResetIntegrationTest {
 
     abstract Map<String, Object> getClientSslConfig();
 
-    @Rule
-    public final TestName testName = new TestName();
-
     protected Properties commonClientConfig;
     protected Properties streamsConfig;
     private Properties producerConfig;
@@ -139,7 +131,7 @@ public abstract class AbstractResetIntegrationTest {
         resultConsumerConfig.putAll(commonClientConfig);
 
         streamsConfig = new Properties();
-        streamsConfig.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getRoot().getPath());
+        streamsConfig.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
         streamsConfig.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Long().getClass());
         streamsConfig.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfig.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
@@ -150,9 +142,6 @@ public abstract class AbstractResetIntegrationTest {
         streamsConfig.putAll(commonClientConfig);
     }
 
-    @Rule
-    public final TemporaryFolder testFolder = new TemporaryFolder(TestUtils.tempDirectory());
-
     protected static final String INPUT_TOPIC = "inputTopic";
     protected static final String OUTPUT_TOPIC = "outputTopic";
     private static final String OUTPUT_TOPIC_2 = "outputTopic2";
@@ -163,8 +152,8 @@ public abstract class AbstractResetIntegrationTest {
     protected static final int CLEANUP_CONSUMER_TIMEOUT = 2000;
     protected static final int TIMEOUT_MULTIPLIER = 15;
 
-    void prepareTest() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    void prepareTest(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         prepareConfigs(appID);
         prepareEnvironment();
 
@@ -204,8 +193,8 @@ public abstract class AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testResetWhenInternalTopicsAreSpecified() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testResetWhenInternalTopicsAreSpecified(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
@@ -232,8 +221,8 @@ public abstract class AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testReprocessingFromScratchAfterResetWithoutIntermediateUserTopic() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testReprocessingFromScratchAfterResetWithoutIntermediateUserTopic(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
@@ -264,21 +253,21 @@ public abstract class AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testReprocessingFromScratchAfterResetWithIntermediateUserTopic() throws Exception {
-        testReprocessingFromScratchAfterResetWithIntermediateUserTopic(false);
+    public void testReprocessingFromScratchAfterResetWithIntermediateUserTopic(final TestInfo testInfo) throws Exception {
+        testReprocessingFromScratchAfterResetWithIntermediateUserTopic(false, testInfo);
     }
 
     @Test
-    public void testReprocessingFromScratchAfterResetWithIntermediateInternalTopic() throws Exception {
-        testReprocessingFromScratchAfterResetWithIntermediateUserTopic(true);
+    public void testReprocessingFromScratchAfterResetWithIntermediateInternalTopic(final TestInfo testInfo) throws Exception {
+        testReprocessingFromScratchAfterResetWithIntermediateUserTopic(true, testInfo);
     }
 
-    private void testReprocessingFromScratchAfterResetWithIntermediateUserTopic(final boolean useRepartitioned) throws Exception {
+    private void testReprocessingFromScratchAfterResetWithIntermediateUserTopic(final boolean useRepartitioned, final TestInfo testInfo) throws Exception {
         if (!useRepartitioned) {
             cluster.createTopic(INTERMEDIATE_USER_TOPIC);
         }
 
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
@@ -428,7 +417,7 @@ public abstract class AbstractResetIntegrationTest {
                              final String resetScenarioArg,
                              final String appID) throws Exception {
         final boolean cleanResult = tryCleanGlobal(withIntermediateTopics, resetScenario, resetScenarioArg, appID);
-        Assert.assertTrue(cleanResult);
+        assertTrue(cleanResult);
     }
 
     protected void assertInternalTopicsGotDeleted(final String additionalExistingTopic) throws Exception {
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/AdjustStreamThreadCountTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/AdjustStreamThreadCountTest.java
index 9cee7618494..16942856fb9 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/AdjustStreamThreadCountTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/AdjustStreamThreadCountTest.java
@@ -35,6 +35,7 @@ import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.processor.PunctuationType;
 import org.apache.kafka.streams.processor.internals.StreamThread;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -45,8 +46,6 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.Timeout;
 
-import java.util.concurrent.atomic.AtomicBoolean;
-
 import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
@@ -57,6 +56,7 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 import static org.apache.kafka.common.utils.Utils.mkEntry;
@@ -65,7 +65,6 @@ import static org.apache.kafka.common.utils.Utils.mkObjectProperties;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.purgeLocalStreamsState;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 import static org.apache.kafka.test.TestUtils.waitForCondition;
-
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/ConsistencyVectorIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/ConsistencyVectorIntegrationTest.java
index e5d8e5ae133..d9dcfbdc486 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/ConsistencyVectorIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/ConsistencyVectorIntegrationTest.java
@@ -38,15 +38,14 @@ import org.apache.kafka.streams.query.QueryResult;
 import org.apache.kafka.streams.query.StateQueryRequest;
 import org.apache.kafka.streams.query.StateQueryResult;
 import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+
+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.junit.jupiter.api.Timeout;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -64,10 +63,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
 
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class ConsistencyVectorIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final int NUM_BROKERS = 1;
     private static int port = 0;
     private static final String INPUT_TOPIC_NAME = "input-topic";
@@ -77,19 +75,16 @@ public class ConsistencyVectorIntegrationTest {
 
     public final EmbeddedKafkaCluster cluster = new EmbeddedKafkaCluster(NUM_BROKERS);
 
-    @Rule
-    public TestName testName = new TestName();
-
     private final List<KafkaStreams> streamsToCleanup = new ArrayList<>();
     private final MockTime mockTime = cluster.time;
 
-    @Before
+    @BeforeEach
     public void before() throws InterruptedException, IOException {
         cluster.start();
         cluster.createTopic(INPUT_TOPIC_NAME, 1, 1);
     }
 
-    @After
+    @AfterEach
     public void after() {
         for (final KafkaStreams kafkaStreams : streamsToCleanup) {
             kafkaStreams.close();
@@ -98,7 +93,7 @@ public class ConsistencyVectorIntegrationTest {
     }
 
     @Test
-    public void shouldHaveSamePositionBoundActiveAndStandBy() throws Exception {
+    public void shouldHaveSamePositionBoundActiveAndStandBy(final TestInfo testInfo) throws Exception {
         final Semaphore semaphore = new Semaphore(0);
 
         final StreamsBuilder builder = new StreamsBuilder();
@@ -110,7 +105,7 @@ public class ConsistencyVectorIntegrationTest {
                .toStream()
                .peek((k, v) -> semaphore.release());
 
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
         final KafkaStreams kafkaStreams1 = createKafkaStreams(builder, streamsConfiguration(safeTestName));
         final KafkaStreams kafkaStreams2 = createKafkaStreams(builder, streamsConfiguration(safeTestName));
         final List<KafkaStreams> kafkaStreamsList = Arrays.asList(kafkaStreams1, kafkaStreams2);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/EOSUncleanShutdownIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/EOSUncleanShutdownIntegrationTest.java
index 718f162a18c..90193c64cb1 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/EOSUncleanShutdownIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/EOSUncleanShutdownIntegrationTest.java
@@ -31,23 +31,17 @@ import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-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.TemporaryFolder;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -59,33 +53,20 @@ import static org.apache.kafka.common.utils.Utils.mkMap;
 import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.cleanStateBeforeTest;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.quietlyCleanStateAfterTest;
-import static org.junit.Assert.assertTrue;
-
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
  * Test the unclean shutdown behavior around state store cleanup.
  */
-@RunWith(Parameterized.class)
-@Category(IntegrationTest.class)
+@SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class EOSUncleanShutdownIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-
-    @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return Arrays.asList(new String[][] {
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String eosConfig;
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(3);
+    private static final File TEST_FOLDER = TestUtils.tempDirectory();
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
         STREAMS_CONFIG.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
@@ -93,25 +74,23 @@ public class EOSUncleanShutdownIntegrationTest {
         STREAMS_CONFIG.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         STREAMS_CONFIG.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         STREAMS_CONFIG.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, COMMIT_INTERVAL);
-        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, TEST_FOLDER.getRoot().getPath());
+        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, TEST_FOLDER.getPath());
     }
 
-    @AfterClass
-    public static void closeCluster() {
+    @AfterAll
+    public static void closeCluster() throws IOException {
         CLUSTER.stop();
     }
 
-    @ClassRule
-    public static final TemporaryFolder TEST_FOLDER = new TemporaryFolder(TestUtils.tempDirectory());
-
     private static final Properties STREAMS_CONFIG = new Properties();
     private static final StringSerializer STRING_SERIALIZER = new StringSerializer();
     private static final Long COMMIT_INTERVAL = 100L;
 
     private static final int RECORD_TOTAL = 3;
 
-    @Test
-    public void shouldWorkWithUncleanShutdownWipeOutStateStore() throws InterruptedException {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldWorkWithUncleanShutdownWipeOutStateStore(final String eosConfig) throws InterruptedException {
         final String appId = "shouldWorkWithUncleanShutdownWipeOutStateStore";
         STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appId);
         STREAMS_CONFIG.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, eosConfig);
@@ -149,7 +128,7 @@ public class EOSUncleanShutdownIntegrationTest {
         driver.start();
 
         // Task's StateDir
-        final File taskStateDir = new File(String.join("/", TEST_FOLDER.getRoot().getPath(), appId, "0_0"));
+        final File taskStateDir = new File(String.join("/", TEST_FOLDER.getPath(), appId, "0_0"));
         final File taskCheckpointFile = new File(taskStateDir, ".checkpoint");
 
         try {
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/EmitOnChangeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/EmitOnChangeIntegrationTest.java
index 00dd2d436d5..71b32fe2e59 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/EmitOnChangeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/EmitOnChangeIntegrationTest.java
@@ -31,6 +31,7 @@ import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/EosIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/EosIntegrationTest.java
index ac1f0b19e13..7cf725440c6 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/EosIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/EosIntegrationTest.java
@@ -60,20 +60,17 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.internals.OffsetCheckpoint;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.StreamsTestUtils;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-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.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -82,7 +79,6 @@ import java.io.IOException;
 import java.nio.file.Paths;
 import java.time.Duration;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -113,14 +109,13 @@ import static org.apache.kafka.test.TestUtils.waitForCondition;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
-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;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class EosIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final Logger LOG = LoggerFactory.getLogger(EosIntegrationTest.class);
     private static final int NUM_BROKERS = 3;
     private static final int MAX_POLL_INTERVAL_MS = 30_000;
@@ -131,12 +126,12 @@ public class EosIntegrationTest {
         Utils.mkProperties(Collections.singletonMap("auto.create.topics.enable", "true"))
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -166,26 +161,7 @@ public class EosIntegrationTest {
 
     private String stateTmpDir;
 
-    @SuppressWarnings("deprecation")
-    @Parameters(name = "{0}, processing threads = {1}")
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][]{
-                {StreamsConfig.AT_LEAST_ONCE, false},
-                {StreamsConfig.EXACTLY_ONCE, false},
-                {StreamsConfig.EXACTLY_ONCE_V2, false},
-                {StreamsConfig.AT_LEAST_ONCE, true},
-                {StreamsConfig.EXACTLY_ONCE, true},
-                {StreamsConfig.EXACTLY_ONCE_V2, true}
-        });
-    }
-
-    @Parameter(0)
-    public String eosConfig;
-
-    @Parameter(1)
-    public boolean processingThreadsEnabled;
-
-    @Before
+    @BeforeEach
     public void createTopics() throws Exception {
         applicationId = "appId-" + TEST_NUMBER.getAndIncrement();
         CLUSTER.deleteTopicsAndWait(
@@ -200,13 +176,15 @@ public class EosIntegrationTest {
         CLUSTER.createTopic(MULTI_PARTITION_OUTPUT_TOPIC, NUM_TOPIC_PARTITIONS, 1);
     }
 
-    @Test
-    public void shouldBeAbleToRunWithEosEnabled() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToRunWithEosEnabled(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, SINGLE_PARTITION_INPUT_TOPIC, null, SINGLE_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
-    @Test
-    public void shouldCommitCorrectOffsetIfInputTopicIsTransactional() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldCommitCorrectOffsetIfInputTopicIsTransactional(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, SINGLE_PARTITION_INPUT_TOPIC, null, SINGLE_PARTITION_OUTPUT_TOPIC, true, eosConfig);
 
         try (final Admin adminClient = Admin.create(mkMap(mkEntry(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers())));
@@ -232,28 +210,33 @@ public class EosIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldBeAbleToRestartAfterClose() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToRestartAfterClose(final String eosConfig) throws Exception {
         runSimpleCopyTest(2, SINGLE_PARTITION_INPUT_TOPIC, null, SINGLE_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
-    @Test
-    public void shouldBeAbleToCommitToMultiplePartitions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToCommitToMultiplePartitions(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, SINGLE_PARTITION_INPUT_TOPIC, null, MULTI_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
-    @Test
-    public void shouldBeAbleToCommitMultiplePartitionOffsets() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToCommitMultiplePartitionOffsets(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, MULTI_PARTITION_INPUT_TOPIC, null, SINGLE_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
-    @Test
-    public void shouldBeAbleToRunWithTwoSubtopologies() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToRunWithTwoSubtopologies(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, SINGLE_PARTITION_INPUT_TOPIC, SINGLE_PARTITION_THROUGH_TOPIC, SINGLE_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
-    @Test
-    public void shouldBeAbleToRunWithTwoSubtopologiesAndMultiplePartitions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToRunWithTwoSubtopologiesAndMultiplePartitions(final String eosConfig) throws Exception {
         runSimpleCopyTest(1, MULTI_PARTITION_INPUT_TOPIC, MULTI_PARTITION_THROUGH_TOPIC, MULTI_PARTITION_OUTPUT_TOPIC, false, eosConfig);
     }
 
@@ -344,8 +327,9 @@ public class EosIntegrationTest {
         return recordsPerKey;
     }
 
-    @Test
-    public void shouldBeAbleToPerformMultipleTransactions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldBeAbleToPerformMultipleTransactions(final String eosConfig) throws Exception {
         final StreamsBuilder builder = new StreamsBuilder();
         builder.stream(SINGLE_PARTITION_INPUT_TOPIC).to(SINGLE_PARTITION_OUTPUT_TOPIC);
 
@@ -391,8 +375,16 @@ public class EosIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldNotViolateEosIfOneTaskFails() throws Exception {
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldNotViolateEosIfOneTaskFails(final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
         if (eosConfig.equals(StreamsConfig.AT_LEAST_ONCE)) return;
 
         // this test writes 10 + 5 + 5 records per partition (running with 2 partitions)
@@ -404,7 +396,7 @@ public class EosIntegrationTest {
         // -> the failure only kills one thread
         // after fail over, we should read 40 committed records (even if 50 record got written)
 
-        try (final KafkaStreams streams = getKafkaStreams("dummy", false, "appDir", 2, eosConfig)) {
+        try (final KafkaStreams streams = getKafkaStreams("dummy", false, "appDir", 2, eosConfig, processingThreadsEnabled)) {
             startApplicationAndWaitUntilRunning(streams);
 
             final List<KeyValue<Long, Long>> committedDataBeforeFailure = prepareData(0L, 10L, 0L, 1L);
@@ -494,8 +486,16 @@ public class EosIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldNotViolateEosIfOneTaskFailsWithState() throws Exception {
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldNotViolateEosIfOneTaskFailsWithState(final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
         if (eosConfig.equals(StreamsConfig.AT_LEAST_ONCE)) return;
 
         // this test updates a store with 10 + 5 + 5 records per partition (running with 2 partitions)
@@ -512,7 +512,7 @@ public class EosIntegrationTest {
 
         // We need more processing time under "with state" situation, so increasing the max.poll.interval.ms
         // to avoid unexpected rebalance during test, which will cause unexpected fail over triggered
-        try (final KafkaStreams streams = getKafkaStreams("dummy", true, "appDir", 2, eosConfig)) {
+        try (final KafkaStreams streams = getKafkaStreams("dummy", true, "appDir", 2, eosConfig, processingThreadsEnabled)) {
             startApplicationAndWaitUntilRunning(streams);
 
             final List<KeyValue<Long, Long>> committedDataBeforeFailure = prepareData(0L, 10L, 0L, 1L);
@@ -612,8 +612,16 @@ public class EosIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldNotViolateEosIfOneTaskGetsFencedUsingIsolatedAppInstances() throws Exception {
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldNotViolateEosIfOneTaskGetsFencedUsingIsolatedAppInstances(final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
         if (eosConfig.equals(StreamsConfig.AT_LEAST_ONCE)) return;
 
         // this test writes 10 + 5 + 5 + 10 records per partition (running with 2 partitions)
@@ -629,8 +637,8 @@ public class EosIntegrationTest {
         // we write the remaining 20 records and verify to read 60 result records
 
         try (
-            final KafkaStreams streams1 = getKafkaStreams("streams1", false, "appDir1", 1, eosConfig);
-            final KafkaStreams streams2 = getKafkaStreams("streams2", false, "appDir2", 1, eosConfig)
+            final KafkaStreams streams1 = getKafkaStreams("streams1", false, "appDir1", 1, eosConfig, processingThreadsEnabled);
+            final KafkaStreams streams2 = getKafkaStreams("streams2", false, "appDir2", 1, eosConfig, processingThreadsEnabled)
         ) {
             startApplicationAndWaitUntilRunning(streams1);
             startApplicationAndWaitUntilRunning(streams2);
@@ -774,12 +782,20 @@ public class EosIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldWriteLatestOffsetsToCheckpointOnShutdown() throws Exception {
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldWriteLatestOffsetsToCheckpointOnShutdown(final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
         final List<KeyValue<Long, Long>> writtenData = prepareData(0L, 10, 0L, 1L);
         final List<KeyValue<Long, Long>> expectedResult = computeExpectedResult(writtenData);
 
-        try (final KafkaStreams streams = getKafkaStreams("streams", true, "appDir", 1, eosConfig)) {
+        try (final KafkaStreams streams = getKafkaStreams("streams", true, "appDir", 1, eosConfig, processingThreadsEnabled)) {
             writeInputData(writtenData);
 
             startApplicationAndWaitUntilRunning(streams);
@@ -807,20 +823,40 @@ public class EosIntegrationTest {
         verifyOffsetsAreInCheckpoint(1);
     }
 
-    @Test
-    public void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoringStateUpdaterEnabled() throws Exception {
-        shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(true);
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoringStateUpdaterEnabled(
+            final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
+        shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(eosConfig, processingThreadsEnabled, true);
     }
 
-    @Test
-    public void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoringStateUpdaterDisabled() throws Exception {
+    @ParameterizedTest
+    @CsvSource({
+            StreamsConfig.AT_LEAST_ONCE + ",true",
+            StreamsConfig.AT_LEAST_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE + ",true",
+            StreamsConfig.EXACTLY_ONCE + ",false",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",true",
+            StreamsConfig.EXACTLY_ONCE_V2 + ",false"
+    })
+    public void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoringStateUpdaterDisabled(
+            final String eosConfig, final boolean processingThreadsEnabled) throws Exception {
         if (!processingThreadsEnabled) {
-            shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(false);
+            shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(eosConfig, false, false);
         }
     }
 
-    @SuppressWarnings("deprecation")
-    private void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(final boolean stateUpdaterEnabled) throws Exception {
+    private void shouldCheckpointRestoredOffsetsWhenClosingCleanDuringRestoring(
+            final String eosConfig,
+            final boolean processingThreadsEnabled,
+            final boolean stateUpdaterEnabled) throws Exception {
         if (!eosConfig.equals(StreamsConfig.EXACTLY_ONCE) && !eosConfig.equals(StreamsConfig.EXACTLY_ONCE_V2)) {
             return;
         }
@@ -969,8 +1005,8 @@ public class EosIntegrationTest {
         consumer.seekToEnd(partitions);
         final long topicEndOffset = consumer.position(tp);
 
-        assertTrue("changelog topic end " + topicEndOffset + " is less than checkpointed offset " + checkpointedOffset,
-                topicEndOffset >= checkpointedOffset);
+        assertTrue(topicEndOffset >= checkpointedOffset,
+                "changelog topic end " + topicEndOffset + " is less than checkpointed offset " + checkpointedOffset);
 
         consumer.seekToBeginning(partitions);
 
@@ -982,7 +1018,8 @@ public class EosIntegrationTest {
             }
         }
 
-        assertEquals("Checkpointed offset does not match end of changelog", maxRecordOffset, (Long) checkpointedOffset);
+        assertEquals(maxRecordOffset, (Long) checkpointedOffset,
+                "Checkpointed offset does not match end of changelog");
     }
 
     private List<KeyValue<Long, Long>> prepareData(final long fromInclusive,
@@ -1000,12 +1037,13 @@ public class EosIntegrationTest {
         return data;
     }
 
-    @SuppressWarnings("deprecation") //the threads should no longer fail one thread one at a time
+    // the threads should no longer fail one thread one at a time
     private KafkaStreams getKafkaStreams(final String dummyHostName,
                                          final boolean withState,
                                          final String appDir,
                                          final int numberOfStreamsThreads,
-                                         final String eosConfig) {
+                                         final String eosConfig,
+                                         final boolean processingThreadsEnabled) {
         commitRequested = new AtomicInteger(0);
         errorInjected = new AtomicBoolean(false);
         stallInjected = new AtomicBoolean(false);
@@ -1275,11 +1313,11 @@ public class EosIntegrationTest {
         for (final QueryResult<KeyValueIterator<Long, Long>> partitionResult: result.getPartitionResults().values()) {
             try (final KeyValueIterator<Long, Long> it = partitionResult.getResult()) {
                 while (it.hasNext()) {
-                    assertTrue(reason, expectedStoreContent.remove(it.next()));
+                    assertTrue(expectedStoreContent.remove(it.next()), reason);
                 }
             }
         }
 
-        assertTrue(reason, expectedStoreContent.isEmpty());
+        assertTrue(expectedStoreContent.isEmpty(), reason);
     }
 }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/EosV2UpgradeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/EosV2UpgradeIntegrationTest.java
index 2aa6d38baf4..087a439d084 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/EosV2UpgradeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/EosV2UpgradeIntegrationTest.java
@@ -50,25 +50,22 @@ import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.StreamsTestUtils;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+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.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.File;
 import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -86,25 +83,11 @@ import static org.apache.kafka.common.utils.Utils.mkSet;
 import static org.apache.kafka.test.TestUtils.waitForCondition;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class EosV2UpgradeIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<Boolean[]> data() {
-        return Arrays.asList(new Boolean[][] {
-            {false},
-            {true}
-        });
-    }
-
-    @Parameterized.Parameter
-    public boolean injectError;
-
     private static final int NUM_BROKERS = 3;
     private static final int MAX_POLL_INTERVAL_MS = (int) Duration.ofSeconds(100L).toMillis();
     private static final long MAX_WAIT_TIME_MS = Duration.ofMinutes(1L).toMillis();
@@ -117,10 +100,8 @@ public class EosV2UpgradeIntegrationTest {
             )
         );
     private static final List<KeyValue<KafkaStreams.State, KafkaStreams.State>> CRASH =
-        Collections.unmodifiableList(
-            Collections.singletonList(
+        Collections.singletonList(
                 KeyValue.pair(State.PENDING_ERROR, State.ERROR)
-            )
         );
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(
@@ -129,12 +110,12 @@ public class EosV2UpgradeIntegrationTest {
     );
 
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -161,7 +142,7 @@ public class EosV2UpgradeIntegrationTest {
     private final AtomicInteger commitRequested = new AtomicInteger(0);
 
     private int testNumber = 0;
-    private Map<String, Integer> exceptionCounts = new HashMap<String, Integer>() {
+    private final Map<String, Integer> exceptionCounts = new HashMap<String, Integer>() {
         {
             put(APP_DIR_1, 0);
             put(APP_DIR_2, 0);
@@ -170,7 +151,7 @@ public class EosV2UpgradeIntegrationTest {
 
     private volatile boolean hasUnexpectedError = false;
 
-    @Before
+    @BeforeEach
     public void createTopics() throws Exception {
         applicationId = "appId-" + ++testNumber;
         CLUSTER.deleteTopicsAndWait(
@@ -184,8 +165,9 @@ public class EosV2UpgradeIntegrationTest {
     }
 
     @SuppressWarnings("deprecation")
-    @Test
-    public void shouldUpgradeFromEosAlphaToEosV2() throws Exception {
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void shouldUpgradeFromEosAlphaToEosV2(final boolean injectError) throws Exception {
         // We use two KafkaStreams clients that we upgrade from eos-alpha to eos-V2. During the upgrade,
         // we ensure that there are pending transaction and verify that data is processed correctly.
         //
@@ -255,7 +237,7 @@ public class EosV2UpgradeIntegrationTest {
 
         try {
             // phase 1: start both clients
-            streams1Alpha = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE);
+            streams1Alpha = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE, injectError);
             streams1Alpha.setStateListener(
                 (newState, oldState) -> stateTransitions1.add(KeyValue.pair(oldState, newState))
             );
@@ -266,7 +248,7 @@ public class EosV2UpgradeIntegrationTest {
             assignmentListener.waitForNextStableAssignment(MAX_WAIT_TIME_MS);
             waitForRunning(stateTransitions1);
 
-            streams2Alpha = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE);
+            streams2Alpha = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE, injectError);
             streams2Alpha.setStateListener(
                 (newState, oldState) -> stateTransitions2.add(KeyValue.pair(oldState, newState))
             );
@@ -409,7 +391,7 @@ public class EosV2UpgradeIntegrationTest {
                 errorInjectedClient1.set(false);
                 stateTransitions1.clear();
                 streams1Alpha.close();
-                assertFalse(UNEXPECTED_EXCEPTION_MSG, hasUnexpectedError);
+                assertFalse(hasUnexpectedError, UNEXPECTED_EXCEPTION_MSG);
             }
 
             // phase 5: (restart first client)
@@ -432,7 +414,7 @@ public class EosV2UpgradeIntegrationTest {
             commitRequested.set(0);
             stateTransitions1.clear();
             stateTransitions2.clear();
-            streams1V2 = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE_V2);
+            streams1V2 = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE_V2, injectError);
             streams1V2.setStateListener((newState, oldState) -> stateTransitions1.add(KeyValue.pair(oldState, newState)));
             assignmentListener.prepareForRebalance();
             streams1V2.start();
@@ -547,7 +529,7 @@ public class EosV2UpgradeIntegrationTest {
                 commitErrorInjectedClient2.set(false);
                 stateTransitions2.clear();
                 streams2Alpha.close();
-                assertFalse(UNEXPECTED_EXCEPTION_MSG, hasUnexpectedError);
+                assertFalse(hasUnexpectedError, UNEXPECTED_EXCEPTION_MSG);
 
                 final List<KeyValue<Long, Long>> expectedCommittedResultAfterFailure =
                     computeExpectedResult(uncommittedInputDataAfterFirstUpgrade, committedState);
@@ -576,7 +558,7 @@ public class EosV2UpgradeIntegrationTest {
                 commitCounterClient2.set(-1);
                 stateTransitions1.clear();
                 stateTransitions2.clear();
-                streams2AlphaTwo = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE);
+                streams2AlphaTwo = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE, true);
                 streams2AlphaTwo.setStateListener(
                     (newState, oldState) -> stateTransitions2.add(KeyValue.pair(oldState, newState))
                 );
@@ -638,7 +620,7 @@ public class EosV2UpgradeIntegrationTest {
                 commitErrorInjectedClient1.set(false);
                 stateTransitions1.clear();
                 streams1V2.close();
-                assertFalse(UNEXPECTED_EXCEPTION_MSG, hasUnexpectedError);
+                assertFalse(hasUnexpectedError, UNEXPECTED_EXCEPTION_MSG);
 
                 final List<KeyValue<Long, Long>> expectedCommittedResultAfterFailure =
                     computeExpectedResult(uncommittedInputDataBetweenUpgrade, committedState);
@@ -648,7 +630,7 @@ public class EosV2UpgradeIntegrationTest {
                 // 7c. restart the first client in eos-V2 mode and wait until rebalance stabilizes
                 stateTransitions1.clear();
                 stateTransitions2.clear();
-                streams1V2Two = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE_V2);
+                streams1V2Two = getKafkaStreams(APP_DIR_1, StreamsConfig.EXACTLY_ONCE_V2, true);
                 streams1V2Two.setStateListener((newState, oldState) -> stateTransitions1.add(KeyValue.pair(oldState, newState)));
                 assignmentListener.prepareForRebalance();
                 streams1V2Two.start();
@@ -760,7 +742,7 @@ public class EosV2UpgradeIntegrationTest {
                 errorInjectedClient2.set(false);
                 stateTransitions2.clear();
                 streams2AlphaTwo.close();
-                assertFalse(UNEXPECTED_EXCEPTION_MSG, hasUnexpectedError);
+                assertFalse(hasUnexpectedError, UNEXPECTED_EXCEPTION_MSG);
             }
 
             // phase 10: (restart second client)
@@ -782,7 +764,7 @@ public class EosV2UpgradeIntegrationTest {
             commitRequested.set(0);
             stateTransitions1.clear();
             stateTransitions2.clear();
-            streams2V2 = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE_V2);
+            streams2V2 = getKafkaStreams(APP_DIR_2, StreamsConfig.EXACTLY_ONCE_V2, injectError);
             streams2V2.setStateListener(
                 (newState, oldState) -> stateTransitions2.add(KeyValue.pair(oldState, newState))
             );
@@ -867,7 +849,8 @@ public class EosV2UpgradeIntegrationTest {
 
     @SuppressWarnings("deprecation")
     private KafkaStreams getKafkaStreams(final String appDir,
-                                         final String processingGuarantee) {
+                                         final String processingGuarantee,
+                                         final boolean injectError) {
         final StreamsBuilder builder = new StreamsBuilder();
 
         final String[] storeNames = new String[] {storeName};
@@ -967,7 +950,7 @@ public class EosV2UpgradeIntegrationTest {
                 e.printStackTrace(System.err);
                 hasUnexpectedError = true;
             } else {
-                int exceptionCount = (int) exceptionCounts.get(appDir);
+                int exceptionCount = exceptionCounts.get(appDir);
                 // should only have our injected exception or commit exception, and 2 exceptions for each stream
                 if (++exceptionCount > 2 || !(e instanceof RuntimeException) ||
                     !(e.getMessage().contains("test exception"))) {
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/FineGrainedAutoResetIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/FineGrainedAutoResetIntegrationTest.java
index 732642d51a9..413686c2ea5 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/FineGrainedAutoResetIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/FineGrainedAutoResetIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.consumer.KafkaConsumer;
 import org.apache.kafka.clients.consumer.OffsetAndMetadata;
@@ -40,6 +39,7 @@ import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.test.StreamsTestUtils;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableEOSIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableEOSIntegrationTest.java
index 7b2c8674083..a856b0f2b04 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableEOSIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableEOSIntegrationTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.io.File;
-import java.util.Collections;
-import java.util.concurrent.atomic.AtomicReference;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.TopicPartition;
@@ -45,37 +42,36 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.internals.OffsetCheckpoint;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.io.File;
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
 
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class GlobalKTableEOSIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     private static final int NUM_BROKERS = 1;
     private static final Properties BROKER_CONFIG;
@@ -88,28 +84,16 @@ public class GlobalKTableEOSIntegrationTest {
     public static final EmbeddedKafkaCluster CLUSTER =
             new EmbeddedKafkaCluster(NUM_BROKERS, BROKER_CONFIG);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return Arrays.asList(new String[][] {
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String eosConfig;
-
     private final MockTime mockTime = CLUSTER.time;
     private final KeyValueMapper<String, Long, Long> keyMapper = (key, value) -> value;
     private final ValueJoiner<Long, String, String> joiner = (value1, value2) -> value1 + "+" + value2;
@@ -124,13 +108,10 @@ public class GlobalKTableEOSIntegrationTest {
     private KStream<String, Long> stream;
     private ForeachAction<String, String> foreachAction;
 
-    @Rule
-    public TestName testName = new TestName();
-
-    @Before
-    public void before() throws Exception {
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws Exception {
         builder = new StreamsBuilder();
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
         createTopics(safeTestName);
         streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "app-" + safeTestName);
@@ -138,7 +119,6 @@ public class GlobalKTableEOSIntegrationTest {
         streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
         streamsConfiguration.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0L);
         streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 100L);
-        streamsConfiguration.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, eosConfig);
         streamsConfiguration.put(StreamsConfig.TASK_TIMEOUT_MS_CONFIG, 1L);
         streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
         streamsConfiguration.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 1000);
@@ -155,7 +135,7 @@ public class GlobalKTableEOSIntegrationTest {
         foreachAction = results::put;
     }
 
-    @After
+    @AfterEach
     public void after() throws Exception {
         if (kafkaStreams != null) {
             kafkaStreams.close();
@@ -163,12 +143,13 @@ public class GlobalKTableEOSIntegrationTest {
         IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
     }
 
-    @Test
-    public void shouldKStreamGlobalKTableLeftJoin() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldKStreamGlobalKTableLeftJoin(final String eosConfig) throws Exception {
         final KStream<String, String> streamTableJoin = stream.leftJoin(globalTable, keyMapper, joiner);
         streamTableJoin.foreach(foreachAction);
         produceInitialGlobalTableValues();
-        startStreams();
+        startStreams(eosConfig);
         produceTopicValues(streamTopic);
 
         final Map<String, String> expected = new HashMap<>();
@@ -232,12 +213,13 @@ public class GlobalKTableEOSIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldKStreamGlobalKTableJoin() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldKStreamGlobalKTableJoin(final String eosConfig) throws Exception {
         final KStream<String, String> streamTableJoin = stream.join(globalTable, keyMapper, joiner);
         streamTableJoin.foreach(foreachAction);
         produceInitialGlobalTableValues();
-        startStreams();
+        startStreams(eosConfig);
         produceTopicValues(streamTopic);
 
         final Map<String, String> expected = new HashMap<>();
@@ -300,11 +282,12 @@ public class GlobalKTableEOSIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldRestoreTransactionalMessages() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldRestoreTransactionalMessages(final String eosConfig) throws Exception {
         produceInitialGlobalTableValues();
 
-        startStreams();
+        startStreams(eosConfig);
 
         final Map<Long, String> expected = new HashMap<>();
         expected.put(1L, "A");
@@ -334,21 +317,22 @@ public class GlobalKTableEOSIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldSkipOverTxMarkersOnRestore() throws Exception {
-        shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(false);
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldSkipOverTxMarkersOnRestore(final String eosConfig) throws Exception {
+        shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(false, eosConfig);
     }
 
-    @Test
-    public void shouldSkipOverAbortedMessagesOnRestore() throws Exception {
-        shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(true);
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldSkipOverAbortedMessagesOnRestore(final String eosConfig) throws Exception {
+        shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(true, eosConfig);
     }
 
-    private void shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(final boolean appendAbortedMessages) throws Exception {
+    private void shouldSkipOverTxMarkersAndAbortedMessagesOnRestore(final boolean appendAbortedMessages, final String eosConfig) throws Exception {
         // records with key 1L, 2L, and 4L are written into partition-0
         // record with key 3L is written into partition-1
         produceInitialGlobalTableValues();
-
         final String stateDir = streamsConfiguration.getProperty(StreamsConfig.STATE_DIR_CONFIG);
         final File globalStateDir = new File(
             stateDir
@@ -395,13 +379,13 @@ public class GlobalKTableEOSIntegrationTest {
                 public void onRestoreEnd(final TopicPartition topicPartition,
                                          final String storeName,
                                          final long totalRestored) { }
-            });
+            }, eosConfig);
             final Exception fatal = error.get();
             if (fatal != null) {
                 throw fatal;
             }
         } else {
-            startStreams();
+            startStreams(eosConfig);
         }
 
         final Map<Long, String> expected = new HashMap<>();
@@ -432,13 +416,14 @@ public class GlobalKTableEOSIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldNotRestoreAbortedMessages() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldNotRestoreAbortedMessages(final String eosConfig) throws Exception {
         produceAbortedMessages();
         produceInitialGlobalTableValues();
         produceAbortedMessages();
 
-        startStreams();
+        startStreams(eosConfig);
         
         final Map<Long, String> expected = new HashMap<>();
         expected.put(1L, "A");
@@ -471,11 +456,12 @@ public class GlobalKTableEOSIntegrationTest {
         CLUSTER.createTopic(globalTableTopic, 2, 1);
     }
     
-    private void startStreams() {
-        startStreams(null);
+    private void startStreams(final String eosConfig) {
+        startStreams(null, eosConfig);
     }
 
-    private void startStreams(final StateRestoreListener stateRestoreListener) {
+    private void startStreams(final StateRestoreListener stateRestoreListener, final String eosConfig) {
+        streamsConfiguration.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, eosConfig);
         kafkaStreams = new KafkaStreams(builder.build(), streamsConfiguration);
         kafkaStreams.setGlobalStateRestoreListener(stateRestoreListener);
         kafkaStreams.start();
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableIntegrationTest.java
index 6bf28c52d6a..3cbce8d6c31 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalKTableIntegrationTest.java
@@ -43,6 +43,7 @@ import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.test.MockApiProcessorSupplier;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalStateReprocessTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalStateReprocessTest.java
index 20e7631857e..b610b39240d 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalStateReprocessTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalStateReprocessTest.java
@@ -40,6 +40,7 @@ import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.internals.KeyValueStoreBuilder;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalThreadShutDownOrderTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalThreadShutDownOrderTest.java
index e486565ddf1..7432eb67e01 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/GlobalThreadShutDownOrderTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/GlobalThreadShutDownOrderTest.java
@@ -39,6 +39,7 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.internals.KeyValueStoreBuilder;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/HighAvailabilityTaskAssignorIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/HighAvailabilityTaskAssignorIntegrationTest.java
index 1013d234131..52a3e839c21 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/HighAvailabilityTaskAssignorIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/HighAvailabilityTaskAssignorIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.stream.Stream;
 import org.apache.kafka.clients.CommonClientConfigs;
 import org.apache.kafka.clients.consumer.Consumer;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
@@ -46,11 +45,14 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.test.NoRetryException;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -64,9 +66,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Function;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
 
 import static java.util.Arrays.asList;
 import static org.apache.kafka.common.utils.Utils.mkEntry;
@@ -96,14 +95,6 @@ public class HighAvailabilityTaskAssignorIntegrationTest {
         )
     );
 
-    public static Stream<Arguments> data() {
-        return Stream.of(
-            Arguments.of(StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_NONE),
-            Arguments.of(StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_MIN_TRAFFIC),
-            Arguments.of(StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_BALANCE_SUBTOPOLOGY)
-        );
-    }
-
     @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
@@ -115,7 +106,10 @@ public class HighAvailabilityTaskAssignorIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("data")
+    @ValueSource(strings = {
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_NONE,
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_MIN_TRAFFIC,
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_BALANCE_SUBTOPOLOGY})
     public void shouldScaleOutWithWarmupTasksAndInMemoryStores(final String rackAwareStrategy, final TestInfo testInfo) throws InterruptedException {
         // NB: this test takes at least a minute to run, because it needs a probing rebalance, and the minimum
         // value is one minute
@@ -123,7 +117,10 @@ public class HighAvailabilityTaskAssignorIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("data")
+    @ValueSource(strings = {
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_NONE,
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_MIN_TRAFFIC,
+            StreamsConfig.RACK_AWARE_ASSIGNMENT_STRATEGY_BALANCE_SUBTOPOLOGY})
     public void shouldScaleOutWithWarmupTasksAndPersistentStores(final String rackAwareStrategy, final TestInfo testInfo) throws InterruptedException {
         // NB: this test takes at least a minute to run, because it needs a probing rebalance, and the minimum
         // value is one minute
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2IntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2IntegrationTest.java
index edfc27e458f..86543db49fe 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2IntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2IntegrationTest.java
@@ -54,6 +54,7 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.state.internals.StoreQueryUtils;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2StoreIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2StoreIntegrationTest.java
index 59a94b20562..425f1eb207f 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2StoreIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2StoreIntegrationTest.java
@@ -47,10 +47,10 @@ import org.apache.kafka.streams.query.PositionBound;
 import org.apache.kafka.streams.query.Query;
 import org.apache.kafka.streams.query.QueryResult;
 import org.apache.kafka.streams.query.RangeQuery;
-import org.apache.kafka.streams.query.TimestampedKeyQuery;
-import org.apache.kafka.streams.query.TimestampedRangeQuery;
 import org.apache.kafka.streams.query.StateQueryRequest;
 import org.apache.kafka.streams.query.StateQueryResult;
+import org.apache.kafka.streams.query.TimestampedKeyQuery;
+import org.apache.kafka.streams.query.TimestampedRangeQuery;
 import org.apache.kafka.streams.query.WindowKeyQuery;
 import org.apache.kafka.streams.query.WindowRangeQuery;
 import org.apache.kafka.streams.state.KeyValueBytesStoreSupplier;
@@ -67,18 +67,16 @@ import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.state.WindowBytesStoreSupplier;
 import org.apache.kafka.streams.state.WindowStore;
 import org.apache.kafka.streams.state.WindowStoreIterator;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -87,7 +85,6 @@ import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -105,6 +102,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.stream.Stream;
 
 import static org.apache.kafka.common.utils.Utils.mkEntry;
 import static org.apache.kafka.common.utils.Utils.mkMap;
@@ -116,14 +114,12 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.matchesPattern;
 import static org.hamcrest.Matchers.not;
-import static org.junit.Assert.fail;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
 
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class IQv2StoreIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     private static final Logger LOG = LoggerFactory.getLogger(IQv2StoreIntegrationTest.class);
 
@@ -147,11 +143,6 @@ public class IQv2StoreIntegrationTest {
 
     public static class UnknownQuery implements Query<Void> { }
 
-    private final StoresToTest storeToTest;
-    private final String kind;
-    private final boolean cache;
-    private final boolean log;
-
     private KafkaStreams kafkaStreams;
 
     public enum StoresToTest {
@@ -363,15 +354,14 @@ public class IQv2StoreIntegrationTest {
         }
     }
 
-    @Parameterized.Parameters(name = "cache={0}, log={1}, supplier={2}, kind={3}")
-    public static Collection<Object[]> data() {
+    public static Stream<Arguments> data() {
         LOG.info("Generating test cases according to random seed: {}", SEED);
-        final List<Object[]> values = new ArrayList<>();
+        final List<Arguments> values = new ArrayList<>();
         for (final boolean cacheEnabled : Arrays.asList(true, false)) {
             for (final boolean logEnabled : Arrays.asList(true, false)) {
                 for (final StoresToTest toTest : StoresToTest.values()) {
                     for (final String kind : Arrays.asList("DSL", "PAPI")) {
-                        values.add(new Object[]{cacheEnabled, logEnabled, toTest.name(), kind});
+                        values.add(Arguments.of(cacheEnabled, logEnabled, toTest.name(), kind));
                     }
                 }
             }
@@ -381,21 +371,10 @@ public class IQv2StoreIntegrationTest {
         // it for the constant at the top of the file. This will cause exactly the same sequence
         // of pseudorandom values to be generated.
         Collections.shuffle(values, RANDOM);
-        return values;
-    }
-
-    public IQv2StoreIntegrationTest(
-        final boolean cache,
-        final boolean log,
-        final String storeToTest,
-        final String kind) {
-        this.cache = cache;
-        this.log = log;
-        this.storeToTest = StoresToTest.valueOf(storeToTest);
-        this.kind = kind;
+        return values.stream();
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void before()
         throws InterruptedException, IOException, ExecutionException, TimeoutException {
 
@@ -448,8 +427,7 @@ public class IQv2StoreIntegrationTest {
         ));
     }
 
-    @Before
-    public void beforeTest() {
+    public void setup(final boolean cache, final boolean log, final StoresToTest storeToTest, final String kind) {
         final StoreSupplier<?> supplier = storeToTest.supplier();
         final Properties streamsConfig = streamsConfiguration(
             cache,
@@ -460,17 +438,17 @@ public class IQv2StoreIntegrationTest {
 
         final StreamsBuilder builder = new StreamsBuilder();
         if (Objects.equals(kind, "DSL") && supplier instanceof KeyValueBytesStoreSupplier) {
-            setUpKeyValueDSLTopology((KeyValueBytesStoreSupplier) supplier, builder);
+            setUpKeyValueDSLTopology((KeyValueBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof KeyValueBytesStoreSupplier) {
-            setUpKeyValuePAPITopology((KeyValueBytesStoreSupplier) supplier, builder);
+            setUpKeyValuePAPITopology((KeyValueBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else if (Objects.equals(kind, "DSL") && supplier instanceof WindowBytesStoreSupplier) {
-            setUpWindowDSLTopology((WindowBytesStoreSupplier) supplier, builder);
+            setUpWindowDSLTopology((WindowBytesStoreSupplier) supplier, builder, cache, log);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof WindowBytesStoreSupplier) {
-            setUpWindowPAPITopology((WindowBytesStoreSupplier) supplier, builder);
+            setUpWindowPAPITopology((WindowBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else if (Objects.equals(kind, "DSL") && supplier instanceof SessionBytesStoreSupplier) {
-            setUpSessionDSLTopology((SessionBytesStoreSupplier) supplier, builder);
+            setUpSessionDSLTopology((SessionBytesStoreSupplier) supplier, builder, cache, log);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof SessionBytesStoreSupplier) {
-            setUpSessionPAPITopology((SessionBytesStoreSupplier) supplier, builder);
+            setUpSessionPAPITopology((SessionBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else {
             throw new AssertionError("Store supplier is an unrecognized type.");
         }
@@ -487,7 +465,9 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpSessionDSLTopology(final SessionBytesStoreSupplier supplier,
-                                         final StreamsBuilder builder) {
+                                         final StreamsBuilder builder,
+                                         final boolean cache,
+                                         final boolean log) {
         final Materialized<Integer, Integer, SessionStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -516,7 +496,9 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpWindowDSLTopology(final WindowBytesStoreSupplier supplier,
-                                        final StreamsBuilder builder) {
+                                        final StreamsBuilder builder,
+                                        final boolean cache,
+                                        final boolean log) {
         final Materialized<Integer, Integer, WindowStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -544,7 +526,10 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpKeyValueDSLTopology(final KeyValueBytesStoreSupplier supplier,
-                                          final StreamsBuilder builder) {
+                                          final StreamsBuilder builder,
+                                          final boolean cache,
+                                          final boolean log,
+                                          final StoresToTest storeToTest) {
         final Materialized<Integer, Integer, KeyValueStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -576,7 +561,10 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpKeyValuePAPITopology(final KeyValueBytesStoreSupplier supplier,
-                                           final StreamsBuilder builder) {
+                                           final StreamsBuilder builder,
+                                           final boolean cache,
+                                           final boolean log,
+                                           final StoresToTest storeToTest) {
         final StoreBuilder<?> keyValueStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         if (storeToTest.timestamped()) {
@@ -641,7 +629,10 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpWindowPAPITopology(final WindowBytesStoreSupplier supplier,
-                                         final StreamsBuilder builder) {
+                                         final StreamsBuilder builder,
+                                         final boolean cache,
+                                         final boolean log,
+                                         final StoresToTest storeToTest) {
         final StoreBuilder<?> windowStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         if (storeToTest.timestamped()) {
@@ -709,7 +700,10 @@ public class IQv2StoreIntegrationTest {
     }
 
     private void setUpSessionPAPITopology(final SessionBytesStoreSupplier supplier,
-                                          final StreamsBuilder builder) {
+                                          final StreamsBuilder builder,
+                                          final boolean cache,
+                                          final boolean log,
+                                          final StoresToTest storeToTest) {
         final StoreBuilder<?> sessionStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         sessionStoreStoreBuilder = Stores.sessionStoreBuilder(
@@ -756,8 +750,7 @@ public class IQv2StoreIntegrationTest {
 
     }
 
-
-    @After
+    @AfterEach
     public void afterTest() {
         // only needed because some of the PAPI cases aren't added yet.
         if (kafkaStreams != null) {
@@ -766,13 +759,15 @@ public class IQv2StoreIntegrationTest {
         }
     }
 
-    @AfterClass
+    @AfterAll
     public static void after() {
         CLUSTER.stop();
     }
 
-    @Test
-    public void verifyStore() {
+    @ParameterizedTest
+    @MethodSource("data")
+    public void verifyStore(final boolean cache, final boolean log, final StoresToTest storeToTest, final String kind) {
+        setup(cache, log, storeToTest, kind);
         try {
             if (storeToTest.global()) {
                 // See KAFKA-13523
@@ -781,7 +776,6 @@ public class IQv2StoreIntegrationTest {
                 shouldRejectUnknownQuery();
                 shouldCollectExecutionInfo();
                 shouldCollectExecutionInfoUnderFailure();
-                final String kind = this.kind;
                 if (storeToTest.keyValue()) {
                     if (storeToTest.timestamped()) {
                         shouldHandleKeyQuery(2,  5);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2VersionedStoreIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2VersionedStoreIntegrationTest.java
index 3c49b864185..7e88fd5e808 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/IQv2VersionedStoreIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/IQv2VersionedStoreIntegrationTest.java
@@ -16,23 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.empty;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.time.temporal.ChronoField;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Optional;
-import java.util.Properties;
-
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.producer.KafkaProducer;
 import org.apache.kafka.clients.producer.ProducerConfig;
@@ -56,17 +39,34 @@ import org.apache.kafka.streams.query.StateQueryRequest;
 import org.apache.kafka.streams.query.StateQueryResult;
 import org.apache.kafka.streams.query.VersionedKeyQuery;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.streams.state.VersionedRecordIterator;
 import org.apache.kafka.streams.state.VersionedRecord;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-@Category({IntegrationTest.class})
+import org.apache.kafka.streams.state.VersionedRecordIterator;
+
+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 java.time.Duration;
+import java.time.Instant;
+import java.time.temporal.ChronoField;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@Tag("integration")
 public class IQv2VersionedStoreIntegrationTest {
     private static final int NUM_BROKERS = 1;
     private static final String INPUT_TOPIC_NAME = "input-topic";
@@ -89,7 +89,7 @@ public class IQv2VersionedStoreIntegrationTest {
 
     private KafkaStreams kafkaStreams;
 
-    @BeforeClass
+    @BeforeAll
     public static void before() throws Exception {
         CLUSTER.start();
 
@@ -106,7 +106,7 @@ public class IQv2VersionedStoreIntegrationTest {
         INPUT_POSITION.withComponent(INPUT_TOPIC_NAME, 0, 3);
     }
 
-    @Before
+    @BeforeEach
     public void beforeTest() {
         final StreamsBuilder builder = new StreamsBuilder();
         builder.table(INPUT_TOPIC_NAME,
@@ -119,7 +119,7 @@ public class IQv2VersionedStoreIntegrationTest {
         kafkaStreams = IntegrationTestUtils.getStartedStreams(configs, builder, true);
     }
 
-    @After
+    @AfterEach
     public void afterTest() {
         if (kafkaStreams != null) {
             kafkaStreams.close();
@@ -127,7 +127,7 @@ public class IQv2VersionedStoreIntegrationTest {
         }
     }
 
-    @AfterClass
+    @AfterAll
     public static void after() {
         CLUSTER.stop();
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/InternalTopicIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/InternalTopicIntegrationTest.java
index 274cdb045a3..7a3ac7365dd 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/InternalTopicIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/InternalTopicIntegrationTest.java
@@ -42,6 +42,7 @@ import org.apache.kafka.streams.processor.internals.ProcessorStateManager;
 import org.apache.kafka.streams.state.WindowStore;
 import org.apache.kafka.test.MockMapper;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/JoinGracePeriodDurabilityIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/JoinGracePeriodDurabilityIntegrationTest.java
index 6fa378cb4a7..d867b05b4f2 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/JoinGracePeriodDurabilityIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/JoinGracePeriodDurabilityIntegrationTest.java
@@ -19,7 +19,6 @@ package org.apache.kafka.streams.integration;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.serialization.Deserializer;
-import org.apache.kafka.common.serialization.LongDeserializer;
 import org.apache.kafka.common.serialization.Serde;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.serialization.Serializer;
@@ -37,23 +36,19 @@ import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.MockValueJoiner;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.IOException;
 import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.List;
 import java.util.Optional;
 import java.util.Properties;
@@ -71,11 +66,9 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.sa
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class JoinGracePeriodDurabilityIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(
         3,
@@ -83,42 +76,26 @@ public class JoinGracePeriodDurabilityIntegrationTest {
         0L
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
     private static final StringDeserializer STRING_DESERIALIZER = new StringDeserializer();
     private static final StringSerializer STRING_SERIALIZER = new StringSerializer();
     private static final Serde<String> STRING_SERDE = Serdes.String();
-    private static final LongDeserializer LONG_DESERIALIZER = new LongDeserializer();
     private static final long COMMIT_INTERVAL = 100L;
 
     @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return Arrays.asList(new String[][] {
-            {StreamsConfig.AT_LEAST_ONCE},
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String processingGuaranteee;
-
-    @Test
-    @SuppressWarnings("deprecation")
-    public void shouldRecoverBufferAfterShutdown() {
-        final String testId = safeUniqueTestName(testName);
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldRecoverBufferAfterShutdown(final String processingGuarantee, final TestInfo testInfo) {
+        final String testId = safeUniqueTestName(testInfo);
         final String appId = "appId_" + testId;
         final String streamInput = "Streaminput" + testId;
         final String tableInput = "Tableinput" + testId;
@@ -147,7 +124,7 @@ public class JoinGracePeriodDurabilityIntegrationTest {
             mkEntry(StreamsConfig.APPLICATION_ID_CONFIG, appId),
             mkEntry(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers()),
             mkEntry(StreamsConfig.POLL_MS_CONFIG, Long.toString(COMMIT_INTERVAL)),
-            mkEntry(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, processingGuaranteee),
+            mkEntry(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, processingGuarantee),
             mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath()),
             mkEntry(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.StringSerde.class),
             mkEntry(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class)
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/JoinStoreIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/JoinStoreIntegrationTest.java
index 071393a11cf..c71ac31672a 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/JoinStoreIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/JoinStoreIntegrationTest.java
@@ -16,10 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.Collection;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 import org.apache.kafka.clients.admin.Admin;
 import org.apache.kafka.clients.admin.AdminClientConfig;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
@@ -31,42 +27,44 @@ import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.errors.UnknownStateStoreException;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
+import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Consumed;
 import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.StreamJoined;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.Timeout;
+
+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.Timeout;
 
 import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static java.time.Duration.ofMillis;
 import static org.apache.kafka.streams.StoreQueryParameters.fromNameAndType;
 import static org.apache.kafka.streams.state.QueryableStoreTypes.keyValueStore;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 @SuppressWarnings("deprecation")
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class JoinStoreIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
-    public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
+    private static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
         STREAMS_CONFIG.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
@@ -78,15 +76,11 @@ public class JoinStoreIntegrationTest {
         ADMIN_CONFIG.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-
-    @Rule
-    public final TemporaryFolder testFolder = new TemporaryFolder(TestUtils.tempDirectory());
-
     private static final String APP_ID = "join-store-integration-test";
     private static final Long COMMIT_INTERVAL = 100L;
     static final Properties STREAMS_CONFIG = new Properties();
@@ -95,20 +89,16 @@ public class JoinStoreIntegrationTest {
     static final String OUTPUT_TOPIC = "outputTopic";
     static final Properties ADMIN_CONFIG = new Properties();
 
-
-    StreamsBuilder builder;
-
-    @Before
+    @BeforeEach
     public void prepareTopology() throws InterruptedException {
         CLUSTER.createTopics(INPUT_TOPIC_LEFT, INPUT_TOPIC_RIGHT, OUTPUT_TOPIC);
-        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getRoot().getPath());
-
-        builder = new StreamsBuilder();
+        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
     }
 
-    @After
-    public void cleanup() throws InterruptedException {
+    @AfterEach
+    public void cleanup() throws InterruptedException, IOException {
         CLUSTER.deleteAllTopicsAndWait(120000);
+        IntegrationTestUtils.purgeLocalStreamsState(STREAMS_CONFIG);
     }
 
     @Test
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/JoinWithIncompleteMetadataIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/JoinWithIncompleteMetadataIntegrationTest.java
index 17cbf5f2504..58b00f81d53 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/JoinWithIncompleteMetadataIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/JoinWithIncompleteMetadataIntegrationTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.io.IOException;
-import java.util.Properties;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.streams.KafkaStreamsWrapper;
@@ -28,28 +26,28 @@ import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.ValueJoiner;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.Timeout;
-
-import static org.junit.Assert.assertTrue;
-
-@Category({IntegrationTest.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.Test;
+import org.junit.jupiter.api.Timeout;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@Tag("integration")
+@Timeout(600)
 public class JoinWithIncompleteMetadataIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
         STREAMS_CONFIG.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
@@ -59,15 +57,11 @@ public class JoinWithIncompleteMetadataIntegrationTest {
         STREAMS_CONFIG.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, COMMIT_INTERVAL);
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-
-    @Rule
-    public final TemporaryFolder testFolder = new TemporaryFolder(TestUtils.tempDirectory());
-
     private static final String APP_ID = "join-incomplete-metadata-integration-test";
     private static final Long COMMIT_INTERVAL = 100L;
     static final Properties STREAMS_CONFIG = new Properties();
@@ -79,18 +73,19 @@ public class JoinWithIncompleteMetadataIntegrationTest {
     final ValueJoiner<String, String, String> valueJoiner = (value1, value2) -> value1 + "-" + value2;
     private KTable<Long, String> rightTable;
 
-    @Before
+    @BeforeEach
     public void prepareTopology() throws InterruptedException {
         CLUSTER.createTopics(INPUT_TOPIC_RIGHT, OUTPUT_TOPIC);
-        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getRoot().getPath());
+        STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
 
         builder = new StreamsBuilder();
         rightTable = builder.table(INPUT_TOPIC_RIGHT);
     }
 
-    @After
-    public void cleanup() throws InterruptedException {
+    @AfterEach
+    public void cleanup() throws InterruptedException, IOException {
         CLUSTER.deleteAllTopicsAndWait(120000);
+        IntegrationTestUtils.purgeLocalStreamsState(STREAMS_CONFIG);
     }
 
     @Test
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationDedupIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationDedupIntegrationTest.java
index 887bf416da3..e92ea85dde9 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationDedupIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationDedupIntegrationTest.java
@@ -42,6 +42,7 @@ import org.apache.kafka.streams.kstream.Reducer;
 import org.apache.kafka.streams.kstream.TimeWindows;
 import org.apache.kafka.test.MockMapper;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationIntegrationTest.java
index 1f3fc98b778..a9b63f66d29 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamAggregationIntegrationTest.java
@@ -28,9 +28,9 @@ import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.server.util.MockTime;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Aggregator;
@@ -63,6 +63,7 @@ import org.apache.kafka.test.MockMapper;
 import org.apache.kafka.test.TestUtils;
 import org.apache.kafka.tools.consumer.ConsoleConsumer;
 import org.apache.kafka.tools.consumer.ConsoleConsumerOptions;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamKStreamIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamKStreamIntegrationTest.java
index cff5c6e39b7..3f55d7bb2ca 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamKStreamIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamKStreamIntegrationTest.java
@@ -34,6 +34,7 @@ import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.ValueJoiner;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamRepartitionIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamRepartitionIntegrationTest.java
index 79e62c48ef1..6bfc4bdaf15 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamRepartitionIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamRepartitionIntegrationTest.java
@@ -27,6 +27,7 @@ import org.apache.kafka.common.serialization.LongDeserializer;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
+import org.apache.kafka.common.utils.Utils;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KafkaStreams.State;
 import org.apache.kafka.streams.KeyValue;
@@ -40,33 +41,29 @@ import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Named;
 import org.apache.kafka.streams.kstream.Repartitioned;
 import org.apache.kafka.streams.processor.StreamPartitioner;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.io.File;
 import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
-import java.util.Optional;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -80,63 +77,41 @@ import static org.apache.kafka.streams.KafkaStreams.State.ERROR;
 import static org.apache.kafka.streams.KafkaStreams.State.REBALANCING;
 import static org.apache.kafka.streams.KafkaStreams.State.RUNNING;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-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.assertTrue;
 
-@RunWith(value = Parameterized.class)
-@Category({IntegrationTest.class})
 @SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class KStreamRepartitionIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     private static final int NUM_BROKERS = 1;
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(NUM_BROKERS);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-
     private String topicB;
     private String inputTopic;
     private String outputTopic;
     private String applicationId;
-
     private String safeTestName;
-
-    private Properties streamsConfiguration;
     private List<KafkaStreams> kafkaStreamsInstances;
+    private final File testFolder = TestUtils.tempDirectory();
 
-    @Parameter
-    public String topologyOptimization;
-
-    @Parameters(name = "Optimization = {0}")
-    public static Collection<?> topologyOptimization() {
-        return Arrays.asList(new String[][]{
-            {StreamsConfig.OPTIMIZE},
-            {StreamsConfig.NO_OPTIMIZATION}
-        });
-    }
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Before
-    public void before() throws InterruptedException {
-        streamsConfiguration = new Properties();
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws InterruptedException {
         kafkaStreamsInstances = new ArrayList<>();
-
-        safeTestName = safeUniqueTestName(testName);
-
+        safeTestName = safeUniqueTestName(testInfo);
         topicB = "topic-b-" + safeTestName;
         inputTopic = "input-topic-" + safeTestName;
         outputTopic = "output-topic-" + safeTestName;
@@ -144,28 +119,33 @@ public class KStreamRepartitionIntegrationTest {
 
         CLUSTER.createTopic(inputTopic, 4, 1);
         CLUSTER.createTopic(outputTopic, 1, 1);
+    }
 
+    private Properties createStreamsConfig(final String topologyOptimization) {
+        final Properties streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, applicationId);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
-        streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
+        streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getPath());
         streamsConfiguration.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
         streamsConfiguration.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 100L);
         streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Integer().getClass());
         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfiguration.put(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, topologyOptimization);
+        return streamsConfiguration;
     }
 
-    @After
+    @AfterEach
     public void whenShuttingDown() throws IOException {
         kafkaStreamsInstances.stream()
                              .filter(Objects::nonNull)
                              .forEach(KafkaStreams::close);
 
-        IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
+        Utils.delete(testFolder);
     }
 
-    @Test
-    public void shouldThrowAnExceptionWhenNumberOfPartitionsOfRepartitionOperationDoNotMatchSourceTopicWhenJoining() throws InterruptedException {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldThrowAnExceptionWhenNumberOfPartitionsOfRepartitionOperationDoNotMatchSourceTopicWhenJoining(final String topologyOptimization) throws InterruptedException {
         final int topicBNumberOfPartitions = 6;
         final String inputTopicRepartitionName = "join-repartition-test";
         final AtomicReference<Throwable> expectedThrowable = new AtomicReference<>();
@@ -184,12 +164,13 @@ public class KStreamRepartitionIntegrationTest {
 
         builder.stream(inputTopic, Consumed.with(Serdes.Integer(), Serdes.String()))
                .repartition(inputTopicRepartitioned)
-               .join(topicBStream, (value1, value2) -> value2, JoinWindows.of(Duration.ofSeconds(10)))
+               .join(topicBStream, (value1, value2) -> value2, JoinWindows.ofTimeDifferenceWithNoGrace(Duration.ofSeconds(10)))
                .to(outputTopic);
 
+        final Properties streamsConfiguration = createStreamsConfig(topologyOptimization);
         builder.build(streamsConfiguration);
 
-        startStreams(builder, REBALANCING, ERROR, (t, e) -> expectedThrowable.set(e));
+        startStreams(builder, REBALANCING, ERROR, streamsConfiguration, (t, e) -> expectedThrowable.set(e));
 
         final String expectedMsg = String.format("Number of partitions [%s] of repartition topic [%s] " +
                                                  "doesn't match number of partitions [%s] of the source topic.",
@@ -200,8 +181,9 @@ public class KStreamRepartitionIntegrationTest {
         assertTrue(expectedThrowable.get().getMessage().contains(expectedMsg));
     }
 
-    @Test
-    public void shouldDeductNumberOfPartitionsFromRepartitionOperation() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldDeductNumberOfPartitionsFromRepartitionOperation(final String topologyOptimization) throws Exception {
         final String topicBMapperName = "topic-b-mapper";
         final int topicBNumberOfPartitions = 6;
         final String inputTopicRepartitionName = "join-repartition-test";
@@ -234,9 +216,10 @@ public class KStreamRepartitionIntegrationTest {
                .join(topicBStream, (value1, value2) -> value2, JoinWindows.of(Duration.ofSeconds(10)))
                .to(outputTopic);
 
+        final Properties streamsConfiguration = createStreamsConfig(topologyOptimization);
         builder.build(streamsConfiguration);
 
-        startStreams(builder);
+        startStreams(builder, streamsConfiguration);
 
         assertEquals(inputTopicRepartitionedNumOfPartitions,
                      getNumberOfPartitionsForTopic(toRepartitionTopicName(inputTopicRepartitionName)));
@@ -251,8 +234,9 @@ public class KStreamRepartitionIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldDoProperJoiningWhenNumberOfPartitionsAreValidWhenUsingRepartitionOperation() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldDoProperJoiningWhenNumberOfPartitionsAreValidWhenUsingRepartitionOperation(final String topologyOptimization) throws Exception {
         final String topicBRepartitionedName = "topic-b-scale-up";
         final String inputTopicRepartitionedName = "input-topic-scale-up";
 
@@ -290,7 +274,7 @@ public class KStreamRepartitionIntegrationTest {
                .join(topicBStream, (value1, value2) -> value2, JoinWindows.of(Duration.ofSeconds(10)))
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         assertEquals(4, getNumberOfPartitionsForTopic(toRepartitionTopicName(topicBRepartitionedName)));
         assertEquals(4, getNumberOfPartitionsForTopic(toRepartitionTopicName(inputTopicRepartitionedName)));
@@ -302,8 +286,9 @@ public class KStreamRepartitionIntegrationTest {
         );
     }
 
-    @Test
-    public void shouldRepartitionToMultiplePartitions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldRepartitionToMultiplePartitions(final String topologyOptimization) throws Exception {
         final String repartitionName = "broadcasting-partitioner-test";
         final long timestamp = System.currentTimeMillis();
         final AtomicInteger partitionerInvocation = new AtomicInteger(0);
@@ -351,7 +336,7 @@ public class KStreamRepartitionIntegrationTest {
             .repartition(repartitioned)
             .to(broadcastingOutputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         final String topic = toRepartitionTopicName(repartitionName);
 
@@ -376,8 +361,9 @@ public class KStreamRepartitionIntegrationTest {
     }
 
 
-    @Test
-    public void shouldUseStreamPartitionerForRepartitionOperation() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldUseStreamPartitionerForRepartitionOperation(final String topologyOptimization) throws Exception {
         final int partition = 1;
         final String repartitionName = "partitioner-test";
         final long timestamp = System.currentTimeMillis();
@@ -403,7 +389,7 @@ public class KStreamRepartitionIntegrationTest {
                .repartition(repartitioned)
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         final String topic = toRepartitionTopicName(repartitionName);
 
@@ -417,8 +403,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(expectedRecords.size(), partitionerInvocation.get());
     }
 
-    @Test
-    public void shouldPerformSelectKeyWithRepartitionOperation() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldPerformSelectKeyWithRepartitionOperation(final String topologyOptimization) throws Exception {
         final long timestamp = System.currentTimeMillis();
 
         sendEvents(
@@ -436,7 +423,7 @@ public class KStreamRepartitionIntegrationTest {
                .repartition()
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new IntegerDeserializer(),
@@ -452,8 +439,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(1, countOccurrencesInTopology(topology, "Sink: .*-repartition.*"));
     }
 
-    @Test
-    public void shouldCreateRepartitionTopicIfKeyChangingOperationWasNotPerformed() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldCreateRepartitionTopicIfKeyChangingOperationWasNotPerformed(final String topologyOptimization) throws Exception {
         final String repartitionName = "dummy";
         final long timestamp = System.currentTimeMillis();
 
@@ -471,7 +459,7 @@ public class KStreamRepartitionIntegrationTest {
                .repartition(Repartitioned.as(repartitionName))
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new IntegerDeserializer(),
@@ -488,8 +476,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(1, countOccurrencesInTopology(topology, "Sink: .*dummy-repartition.*"));
     }
 
-    @Test
-    public void shouldPerformKeySelectOperationWhenRepartitionOperationIsUsedWithKeySelector() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldPerformKeySelectOperationWhenRepartitionOperationIsUsedWithKeySelector(final String topologyOptimization) throws Exception {
         final String repartitionedName = "new-key";
         final long timestamp = System.currentTimeMillis();
 
@@ -514,7 +503,7 @@ public class KStreamRepartitionIntegrationTest {
                .toStream()
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new StringDeserializer(),
@@ -533,8 +522,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(1, countOccurrencesInTopology(topology, "<-- " + repartitionedName + "\n"));
     }
 
-    @Test
-    public void shouldCreateRepartitionTopicWithSpecifiedNumberOfPartitions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldCreateRepartitionTopicWithSpecifiedNumberOfPartitions(final String topologyOptimization) throws Exception {
         final String repartitionName = "new-partitions";
         final long timestamp = System.currentTimeMillis();
 
@@ -555,7 +545,7 @@ public class KStreamRepartitionIntegrationTest {
                .toStream()
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new IntegerDeserializer(),
@@ -572,8 +562,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(2, getNumberOfPartitionsForTopic(repartitionTopicName));
     }
 
-    @Test
-    public void shouldInheritRepartitionTopicPartitionNumberFromUpstreamTopicWhenNumberOfPartitionsIsNotSpecified() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldInheritRepartitionTopicPartitionNumberFromUpstreamTopicWhenNumberOfPartitionsIsNotSpecified(final String topologyOptimization) throws Exception {
         final String repartitionName = "new-topic";
         final long timestamp = System.currentTimeMillis();
 
@@ -594,7 +585,7 @@ public class KStreamRepartitionIntegrationTest {
                .toStream()
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new IntegerDeserializer(),
@@ -611,8 +602,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(4, getNumberOfPartitionsForTopic(repartitionTopicName));
     }
 
-    @Test
-    public void shouldCreateOnlyOneRepartitionTopicWhenRepartitionIsFollowedByGroupByKey() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldCreateOnlyOneRepartitionTopicWhenRepartitionIsFollowedByGroupByKey(final String topologyOptimization) throws Exception {
         final String repartitionName = "new-partitions";
         final long timestamp = System.currentTimeMillis();
 
@@ -639,7 +631,7 @@ public class KStreamRepartitionIntegrationTest {
                .toStream()
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         final String topology = builder.build().describe().toString();
 
@@ -656,8 +648,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(1, countOccurrencesInTopology(topology, "Sink: .*-repartition"));
     }
 
-    @Test
-    public void shouldGenerateRepartitionTopicWhenNameIsNotSpecified() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldGenerateRepartitionTopicWhenNameIsNotSpecified(final String topologyOptimization) throws Exception {
         final long timestamp = System.currentTimeMillis();
 
         sendEvents(
@@ -675,7 +668,7 @@ public class KStreamRepartitionIntegrationTest {
                .repartition(Repartitioned.with(Serdes.String(), Serdes.String()))
                .to(outputTopic);
 
-        startStreams(builder);
+        startStreams(builder, createStreamsConfig(topologyOptimization));
 
         validateReceivedMessages(
             new StringDeserializer(),
@@ -691,8 +684,9 @@ public class KStreamRepartitionIntegrationTest {
         assertEquals(1, countOccurrencesInTopology(topology, "Sink: .*-repartition"));
     }
 
-    @Test
-    public void shouldGoThroughRebalancingCorrectly() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldGoThroughRebalancingCorrectly(final String topologyOptimization) throws Exception {
         final String repartitionName = "rebalancing-test";
         final long timestamp = System.currentTimeMillis();
 
@@ -719,7 +713,8 @@ public class KStreamRepartitionIntegrationTest {
                .toStream()
                .to(outputTopic);
 
-        startStreams(builder);
+        final Properties streamsConfiguration = createStreamsConfig(topologyOptimization);
+        startStreams(builder, streamsConfiguration);
         final Properties streamsToCloseConfigs = new Properties();
         streamsToCloseConfigs.putAll(streamsConfiguration);
         streamsToCloseConfigs.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath() + "-2");
@@ -804,13 +799,13 @@ public class KStreamRepartitionIntegrationTest {
     }
 
     private void sendEvents(final long timestamp,
-                            final List<KeyValue<Integer, String>> events) throws Exception {
+                            final List<KeyValue<Integer, String>> events) {
         sendEvents(inputTopic, timestamp, events);
     }
 
     private void sendEvents(final String topic,
                             final long timestamp,
-                            final List<KeyValue<Integer, String>> events) throws Exception {
+                            final List<KeyValue<Integer, String>> events) {
         IntegrationTestUtils.produceKeyValuesSynchronouslyWithTimestamp(
             topic,
             events,
@@ -824,21 +819,10 @@ public class KStreamRepartitionIntegrationTest {
         );
     }
 
-    private KafkaStreams startStreams(final StreamsBuilder builder) throws InterruptedException {
-        return startStreams(builder, REBALANCING, RUNNING, streamsConfiguration, null);
-    }
-
     private KafkaStreams startStreams(final StreamsBuilder builder, final Properties streamsConfiguration) throws InterruptedException {
         return startStreams(builder, REBALANCING, RUNNING, streamsConfiguration, null);
     }
 
-    private KafkaStreams startStreams(final StreamsBuilder builder,
-                                      final State expectedOldState,
-                                      final State expectedNewState,
-                                      final Thread.UncaughtExceptionHandler uncaughtExceptionHandler) throws InterruptedException {
-        return startStreams(builder, expectedOldState, expectedNewState, streamsConfiguration, uncaughtExceptionHandler);
-    }
-
     private KafkaStreams startStreams(final StreamsBuilder builder,
                                       final State expectedOldState,
                                       final State expectedNewState,
@@ -889,8 +873,6 @@ public class KStreamRepartitionIntegrationTest {
                                                  final Deserializer<V> valueSerializer,
                                                  final List<KeyValue<K, V>> expectedRecords,
                                                  final String outputTopic) throws Exception {
-
-        final String safeTestName = safeUniqueTestName(testName);
         final Properties consumerProperties = new Properties();
         consumerProperties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
         consumerProperties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "group-" + safeTestName);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamTransformIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamTransformIntegrationTest.java
index d916faa9d72..0c5cc4b5398 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KStreamTransformIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KStreamTransformIntegrationTest.java
@@ -18,11 +18,12 @@ package org.apache.kafka.streams.integration;
 
 import org.apache.kafka.common.serialization.IntegerSerializer;
 import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TopologyTestDriver;
 import org.apache.kafka.streams.kstream.Consumed;
 import org.apache.kafka.streams.kstream.ForeachAction;
-import org.apache.kafka.streams.KeyValue;
-import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Transformer;
 import org.apache.kafka.streams.kstream.TransformerSupplier;
@@ -34,31 +35,26 @@ import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.streams.TopologyTestDriver;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.StreamsTestUtils;
 
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
 import java.util.Properties;
+import java.util.Set;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
 
-@SuppressWarnings("unchecked")
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class KStreamTransformIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private StreamsBuilder builder;
     private final String topic = "stream";
     private final String stateStoreName = "myTransformState";
@@ -66,7 +62,7 @@ public class KStreamTransformIntegrationTest {
     private final ForeachAction<Integer, Integer> accumulateExpected = (key, value) -> results.add(KeyValue.pair(key, value));
     private KStream<Integer, Integer> stream;
 
-    @Before
+    @BeforeEach
     public void before() {
         builder = new StreamsBuilder();
         stream = builder.stream(topic, Consumed.with(Serdes.Integer(), Serdes.Integer()));
@@ -97,10 +93,9 @@ public class KStreamTransformIntegrationTest {
     private class TestTransformer implements Transformer<Integer, Integer, KeyValue<Integer, Integer>> {
         private KeyValueStore<Integer, Integer> state;
 
-        @SuppressWarnings("unchecked")
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
@@ -166,10 +161,9 @@ public class KStreamTransformIntegrationTest {
     private class TestFlatTransformer implements Transformer<Integer, Integer, Iterable<KeyValue<Integer, Integer>>> {
         private KeyValueStore<Integer, Integer> state;
 
-        @SuppressWarnings("unchecked")
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
@@ -264,7 +258,7 @@ public class KStreamTransformIntegrationTest {
 
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
@@ -323,7 +317,7 @@ public class KStreamTransformIntegrationTest {
 
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
@@ -390,7 +384,7 @@ public class KStreamTransformIntegrationTest {
 
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
@@ -485,7 +479,7 @@ public class KStreamTransformIntegrationTest {
 
         @Override
         public void init(final ProcessorContext context) {
-            state = (KeyValueStore<Integer, Integer>) context.getStateStore(stateStoreName);
+            state = context.getStateStore(stateStoreName);
         }
 
         @Override
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableEfficientRangeQueryTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableEfficientRangeQueryTest.java
index 571bbf95ed0..5528df32aa8 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableEfficientRangeQueryTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableEfficientRangeQueryTest.java
@@ -23,7 +23,6 @@ import org.apache.kafka.common.utils.Bytes;
 import org.apache.kafka.common.utils.Utils;
 import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.StreamsBuilder;
-import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.TestInputTopic;
 import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.TopologyTestDriver;
@@ -34,17 +33,12 @@ import org.apache.kafka.streams.state.KeyValueIterator;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -52,31 +46,21 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Properties;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 
-import static org.apache.kafka.common.utils.Utils.mkEntry;
-import static org.apache.kafka.common.utils.Utils.mkMap;
-import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class KTableEfficientRangeQueryTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private enum StoreType { InMemory, RocksDB, Timed }
     private static final String TABLE_NAME = "mytable";
     private static final int DATA_SIZE = 5;
 
-    private StoreType storeType;
-    private boolean enableLogging;
-    private boolean enableCaching;
-    private boolean forward;
-
-    private LinkedList<KeyValue<String, String>> records;
+    private final LinkedList<KeyValue<String, String>> records;
     private String low;
     private String high;
     private String middle;
@@ -85,14 +69,7 @@ public class KTableEfficientRangeQueryTest {
     private String innerLowBetween;
     private String innerHighBetween;
 
-    private Properties streamsConfig;
-
-    public KTableEfficientRangeQueryTest(final StoreType storeType, final boolean enableLogging, final boolean enableCaching, final boolean forward) {
-        this.storeType = storeType;
-        this.enableLogging = enableLogging;
-        this.enableCaching = enableCaching;
-        this.forward = forward;
-
+    public KTableEfficientRangeQueryTest() {
         this.records = new LinkedList<>();
         final int m = DATA_SIZE / 2;
         for (int i = 0; i < DATA_SIZE; i++) {
@@ -117,19 +94,15 @@ public class KTableEfficientRangeQueryTest {
                 innerHighBetween = "key-" + index;
             }
         }
-        Assert.assertNotNull(low);
-        Assert.assertNotNull(high);
-        Assert.assertNotNull(middle);
-        Assert.assertNotNull(innerLow);
-        Assert.assertNotNull(innerHigh);
-        Assert.assertNotNull(innerLowBetween);
-        Assert.assertNotNull(innerHighBetween);
+        assertNotNull(low);
+        assertNotNull(high);
+        assertNotNull(middle);
+        assertNotNull(innerLow);
+        assertNotNull(innerHigh);
+        assertNotNull(innerLowBetween);
+        assertNotNull(innerHighBetween);
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
-    @Parameterized.Parameters(name = "storeType={0}, enableLogging={1}, enableCaching={2}, forward={3}")
     public static Collection<Object[]> data() {
         final List<StoreType> types = Arrays.asList(StoreType.InMemory, StoreType.RocksDB, StoreType.Timed);
         final List<Boolean> logging = Arrays.asList(true, false);
@@ -138,15 +111,9 @@ public class KTableEfficientRangeQueryTest {
         return buildParameters(types, logging, caching, forward);
     }
 
-    @Before
-    public void setup() {
-        streamsConfig = mkProperties(mkMap(
-                mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath())
-        ));
-    }
-
-    @Test
-    public void testStoreConfig() {
+    @ParameterizedTest
+    @MethodSource("data")
+    public void testStoreConfig(final StoreType storeType, final boolean enableLogging, final boolean enableCaching, final boolean forward) {
         final Materialized<String, String, KeyValueStore<Bytes, byte[]>> stateStoreConfig = getStoreConfig(storeType, TABLE_NAME, enableLogging, enableCaching);
         //Create topology: table from input topic
         final StreamsBuilder builder = new StreamsBuilder();
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinCustomPartitionerIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinCustomPartitionerIntegrationTest.java
index ebdb6b7b631..e2389d6a516 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinCustomPartitionerIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinCustomPartitionerIntegrationTest.java
@@ -17,14 +17,6 @@
 
 package org.apache.kafka.streams.integration;
 
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Optional;
-import java.util.Arrays;
-
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.serialization.Serdes;
@@ -58,16 +50,23 @@ 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.Timeout;
 import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
 
 import static java.time.Duration.ofSeconds;
 import static java.util.Arrays.asList;
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitUntilMinKeyValueRecordsReceived;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForApplicationState;
-
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitUntilMinKeyValueRecordsReceived;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsEqual.equalTo;
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinMultiIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinMultiIntegrationTest.java
index 367717cfa00..c0c688df153 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinMultiIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyInnerJoinMultiIntegrationTest.java
@@ -41,13 +41,14 @@ import org.apache.kafka.streams.kstream.ValueJoiner;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.utils.UniqueTopicSerdeScope;
 import org.apache.kafka.test.TestUtils;
+
 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.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.Collections;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinDistributedTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinDistributedTest.java
index a6d5b1a70f2..58438efc5b1 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinDistributedTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinDistributedTest.java
@@ -26,21 +26,22 @@ import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.ThreadMetadata;
+import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.ValueJoiner;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.Arrays;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinIntegrationTest.java
index 2bb7b6ea190..b4ac10fdbc6 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinIntegrationTest.java
@@ -35,28 +35,29 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.utils.UniqueTopicSerdeScope;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
+
 import org.junit.jupiter.api.Assertions;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import java.nio.ByteBuffer;
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static java.util.Collections.emptyMap;
 import static org.apache.kafka.common.utils.Utils.mkEntry;
@@ -65,12 +66,9 @@ import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-
-@RunWith(Parameterized.class)
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class KTableKTableForeignKeyJoinIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     protected static final String LEFT_TABLE = "left_table";
     protected static final String RIGHT_TABLE = "right_table";
     protected static final String OUTPUT = "output-topic";
@@ -78,57 +76,63 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
 
     private final MockTime time = new MockTime();
 
-    protected final boolean leftJoin;
-    protected final boolean materialized;
-    private final String optimization;
-    protected final boolean rejoin;
-    protected final boolean leftVersioned;
-    protected final boolean rightVersioned;
-
-    protected Properties streamsConfig;
     protected long baseTimestamp;
 
-    public KTableKTableForeignKeyJoinIntegrationTest(final boolean leftJoin,
-                                                     final String optimization,
-                                                     final boolean materialized,
-                                                     final boolean rejoin) {
-        // versioning is disabled for these tests, even though the code supports building a
-        // topology with versioned tables, since KTableKTableForeignKeyVersionedJoinIntegrationTest
-        // extends this test class.
-        this(leftJoin, optimization, materialized, rejoin, false, false);
+    @BeforeEach
+    public void before() {
+        baseTimestamp = time.milliseconds();
     }
 
-    protected KTableKTableForeignKeyJoinIntegrationTest(final boolean leftJoin,
-                                                        final String optimization,
-                                                        final boolean materialized,
-                                                        final boolean rejoin,
-                                                        final boolean leftVersioned,
-                                                        final boolean rightVersioned) {
-        this.rejoin = rejoin;
-        this.leftJoin = leftJoin;
-        this.materialized = materialized;
-        this.optimization = optimization;
-        this.leftVersioned = leftVersioned;
-        this.rightVersioned = rightVersioned;
+    private static Properties getStreamsProperties(final String optimization) {
+        return mkProperties(mkMap(
+                mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath()),
+                mkEntry(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, optimization)
+        ));
     }
 
-    @Rule
-    public TestName testName = new TestName();
+    // versioning is disabled for these tests, even though the code supports building a
+    // topology with versioned tables, since KTableKTableForeignKeyVersionedJoinIntegrationTest
+    // extends this test class.
+    private static Collection<Object[]> data() {
+        final List<Boolean> leftJoin = Arrays.asList(true, false);
+        final List<String> optimization = Arrays.asList(StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION);
+        final List<Boolean> materialized = Arrays.asList(true, false);
+        final List<Boolean> rejoin = Arrays.asList(true, false);
+        final List<Boolean> leftVersioned = Collections.singletonList(false);
+        final List<Boolean> rightVersioned = Collections.singletonList(false);
+        return buildParameters(leftJoin, optimization, materialized, rejoin, leftVersioned, rightVersioned);
+    }
 
-    @Before
-    public void before() {
-        streamsConfig = mkProperties(mkMap(
-            mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath()),
-            mkEntry(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, optimization)
-        ));
-        baseTimestamp = time.milliseconds();
+    // optimizations and rejoin are disabled for these tests, as these tests focus on versioning.
+    // see KTableKTableForeignKeyJoinIntegrationTest for test coverage for optimizations and rejoin
+    private static Collection<Object[]> versionedData() {
+        final List<Boolean> leftJoin = Arrays.asList(true, false);
+        final List<String> optimization = Collections.singletonList(StreamsConfig.NO_OPTIMIZATION);
+        final List<Boolean> materialized = Arrays.asList(true, false);
+        final List<Boolean> rejoin = Collections.singletonList(false);
+        final List<Boolean> leftVersioned = Arrays.asList(true, false);
+        final List<Boolean> rightVersioned = Arrays.asList(true, false);
+        return buildParameters(leftJoin, optimization, materialized, rejoin, leftVersioned, rightVersioned);
+    }
+
+    // deduplicate test cases in data and versionedData
+    private static Stream<Arguments> testCases() {
+        return Stream.concat(data().stream().map(Arrays::asList), versionedData().stream().map(Arrays::asList))
+                .collect(Collectors.toSet())
+                .stream()
+                .map(a -> Arguments.of(a.toArray()));
+    }
+
+    // remove first argument: leftJoin and deduplicate test cases
+    private static Stream<Arguments> testCasesWithoutLeftJoinArg() {
+        return testCases().map(arguments -> Arrays.asList(Arrays.copyOfRange(arguments.get(), 1, arguments.get().length)))
+                .collect(Collectors.toSet())
+                .stream()
+                .map(a -> Arguments.of(a.toArray()));
     }
 
-    @Parameterized.Parameters(name = "leftJoin={0}, optimization={1}, materialized={2}, rejoin={3}")
-    public static Collection<Object[]> data() {
-        final List<Boolean> booleans = Arrays.asList(true, false);
-        final List<String> optimizations = Arrays.asList(StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION);
-        return buildParameters(booleans, optimizations, booleans, booleans);
+    private static Stream<Arguments> versionedDataTestCases() {
+        return versionedData().stream().map(Arguments::of);
     }
 
     protected static Collection<Object[]> buildParameters(final List<?>... argOptions) {
@@ -155,8 +159,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         return result;
     }
 
-    @Test
-    public void doJoinFromLeftThenDeleteLeftEntity() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void doJoinFromLeftThenDeleteLeftEntity(final boolean leftJoin,
+                                                   final String optimization,
+                                                   final boolean materialized,
+                                                   final boolean rejoin,
+                                                   final boolean leftVersioned,
+                                                   final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
@@ -273,8 +284,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void doJoinFromRightThenDeleteRightEntity() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void doJoinFromRightThenDeleteRightEntity(final boolean leftJoin,
+                                                     final String optimization,
+                                                     final boolean materialized,
+                                                     final boolean rejoin,
+                                                     final boolean leftVersioned,
+                                                     final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
@@ -386,8 +404,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldEmitTombstoneWhenDeletingNonJoiningRecords() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void shouldEmitTombstoneWhenDeletingNonJoiningRecords(final boolean leftJoin,
+                                                                 final String optimization,
+                                                                 final boolean materialized,
+                                                                 final boolean rejoin,
+                                                                 final boolean leftVersioned,
+                                                                 final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
@@ -445,8 +470,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldNotEmitTombstonesWhenDeletingNonExistingRecords() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void shouldNotEmitTombstonesWhenDeletingNonExistingRecords(final boolean leftJoin,
+                                                                      final String optimization,
+                                                                      final boolean materialized,
+                                                                      final boolean rejoin,
+                                                                      final boolean leftVersioned,
+                                                                      final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
@@ -470,8 +502,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void joinShouldProduceNullsWhenValueHasNonMatchingForeignKey() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void joinShouldProduceNullsWhenValueHasNonMatchingForeignKey(final boolean leftJoin,
+                                                                        final String optimization,
+                                                                        final boolean materialized,
+                                                                        final boolean rejoin,
+                                                                        final boolean leftVersioned,
+                                                                        final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
@@ -570,8 +609,15 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldUnsubscribeOldForeignKeyIfLeftSideIsUpdated() {
+    @ParameterizedTest
+    @MethodSource("testCases")
+    public void shouldUnsubscribeOldForeignKeyIfLeftSideIsUpdated(final boolean leftJoin,
+                                                                  final String optimization,
+                                                                  final boolean materialized,
+                                                                  final boolean rejoin,
+                                                                  final boolean leftVersioned,
+                                                                  final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
@@ -649,8 +695,14 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldEmitRecordOnNullForeignKeyForLeftJoins() {
+    @ParameterizedTest
+    @MethodSource("testCasesWithoutLeftJoinArg")
+    public void shouldEmitRecordOnNullForeignKeyForLeftJoins(final String optimization,
+                                                             final boolean materialized,
+                                                             final boolean rejoin,
+                                                             final boolean leftVersioned,
+                                                             final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, true, rejoin, leftVersioned, rightVersioned, value -> null);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
@@ -670,8 +722,13 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldEmitRecordWhenOldAndNewFkDiffer() {
+    @ParameterizedTest
+    @MethodSource("testCasesWithoutLeftJoinArg")
+    public void shouldEmitRecordWhenOldAndNewFkDiffer(final String optimization,
+                                                      final boolean materialized,
+                                                      final boolean rejoin,
+                                                      final boolean leftVersioned,
+                                                      final boolean rightVersioned) {
         final Function<String, String> foreignKeyExtractor = value -> {
             final String split = value.split("\\|")[1];
             if (split.equals("returnNull")) {
@@ -682,6 +739,7 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
                 return split;
             }
         };
+        final Properties streamsConfig = getStreamsProperties(optimization);
         final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, true, rejoin, leftVersioned, rightVersioned, foreignKeyExtractor);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
@@ -848,4 +906,267 @@ public class KTableKTableForeignKeyJoinIntegrationTest {
 
         return builder.build(streamsConfig);
     }
+
+    @ParameterizedTest
+    @MethodSource("versionedDataTestCases")
+    public void shouldIgnoreOutOfOrderRecordsIffVersioned(final boolean leftJoin,
+                                                          final String optimization,
+                                                          final boolean materialized,
+                                                          final boolean rejoin,
+                                                          final boolean leftVersioned,
+                                                          final boolean rightVersioned) {
+        final Properties streamsConfig = getStreamsProperties(optimization);
+        final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
+        try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
+            final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
+            final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
+            final TestOutputTopic<String, String> outputTopic = driver.createOutputTopic(OUTPUT, new StringDeserializer(), new StringDeserializer());
+            final KeyValueStore<String, String> store = driver.getKeyValueStore("store");
+
+            // RHS record
+            right.pipeInput("rhs1", "rhsValue1", baseTimestamp + 4);
+
+            assertThat(
+                    outputTopic.readKeyValuesToMap(),
+                    is(emptyMap())
+            );
+            if (materialized) {
+                assertThat(
+                        asMap(store),
+                        is(emptyMap())
+                );
+            }
+
+            // LHS records with match to existing RHS record
+            left.pipeInput("lhs1", "lhsValue1|rhs1", baseTimestamp + 3);
+            left.pipeInput("lhs2", "lhsValue2|rhs1", baseTimestamp + 5);
+            {
+                final Map<String, String> expected = mkMap(
+                        mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)"),
+                        mkEntry("lhs2", "(lhsValue2|rhs1,rhsValue1)")
+                );
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(expected)
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(expected)
+                    );
+                }
+            }
+
+            // replace with tombstone, to validate behavior when latest record is null
+            left.pipeInput("lhs2", null, baseTimestamp + 6);
+            {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(mkMap(
+                                mkEntry("lhs2", null)
+                        ))
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            }
+
+            // out-of-order LHS record (for existing key) does not produce a new result iff LHS is versioned
+            left.pipeInput("lhs1", "lhsValue1_ooo|rhs1", baseTimestamp + 2);
+            left.pipeInput("lhs2", "lhsValue2_ooo|rhs1", baseTimestamp + 2);
+            if (leftVersioned) {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(emptyMap())
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            } else {
+                final Map<String, String> expected = mkMap(
+                        mkEntry("lhs1", "(lhsValue1_ooo|rhs1,rhsValue1)"),
+                        mkEntry("lhs2", "(lhsValue2_ooo|rhs1,rhsValue1)")
+                );
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(expected)
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(expected)
+                    );
+                }
+            }
+
+            // out-of-order LHS tombstone (for existing key) is similarly ignored (iff LHS is versioned)
+            left.pipeInput("lhs1", null, baseTimestamp + 2);
+            if (leftVersioned) {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(emptyMap())
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            } else {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(mkMap(
+                                mkEntry("lhs1", null)
+                        ))
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs2", "(lhsValue2_ooo|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            }
+
+            // LHS record with larger timestamp always produces a new result
+            left.pipeInput("lhs1", "lhsValue1_new|rhs1", baseTimestamp + 8);
+            left.pipeInput("lhs2", "lhsValue2_new|rhs1", baseTimestamp + 8);
+            {
+                final Map<String, String> expected = mkMap(
+                        mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
+                        mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
+                );
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(expected)
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(expected)
+                    );
+                }
+            }
+
+            // out-of-order RHS record (for existing key) does not produce a new result iff RHS is versioned
+            right.pipeInput("rhs1", "rhsValue1_ooo", baseTimestamp + 1);
+            if (rightVersioned) {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(emptyMap())
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
+                                    mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            } else {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(mkMap(
+                                mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_ooo)"),
+                                mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_ooo)")
+                        ))
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_ooo)"),
+                                    mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_ooo)")
+                            ))
+                    );
+                }
+            }
+
+            // out-of-order RHS tombstone (for existing key) is similarly ignored (iff RHS is versioned)
+            right.pipeInput("rhs1", null, baseTimestamp + 1);
+            if (rightVersioned) {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(emptyMap())
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
+                                    mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
+                            ))
+                    );
+                }
+            } else {
+                if (leftJoin) {
+                    assertThat(
+                            outputTopic.readKeyValuesToMap(),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1_new|rhs1,null)"),
+                                    mkEntry("lhs2", "(lhsValue2_new|rhs1,null)")
+                            ))
+                    );
+                    if (materialized) {
+                        assertThat(
+                                asMap(store),
+                                is(mkMap(
+                                        mkEntry("lhs1", "(lhsValue1_new|rhs1,null)"),
+                                        mkEntry("lhs2", "(lhsValue2_new|rhs1,null)")
+                                ))
+                        );
+                    }
+                } else {
+                    assertThat(
+                            outputTopic.readKeyValuesToMap(),
+                            is(mkMap(
+                                    mkEntry("lhs1", null),
+                                    mkEntry("lhs2", null)
+                            ))
+                    );
+                    if (materialized) {
+                        assertThat(
+                                asMap(store),
+                                is(emptyMap())
+                        );
+                    }
+                }
+            }
+
+            // RHS record with larger timestamps always produces new results
+            right.pipeInput("rhs1", "rhsValue1_new", baseTimestamp + 6);
+            {
+                assertThat(
+                        outputTopic.readKeyValuesToMap(),
+                        is(mkMap(
+                                mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_new)"),
+                                mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_new)")
+                        ))
+                );
+                if (materialized) {
+                    assertThat(
+                            asMap(store),
+                            is(mkMap(
+                                    mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_new)"),
+                                    mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_new)")
+                            ))
+                    );
+                }
+            }
+        }
+    }
 }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinMaterializationIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinMaterializationIntegrationTest.java
index 6655f697bb7..e0e51b84b7b 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinMaterializationIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyJoinMaterializationIntegrationTest.java
@@ -32,19 +32,14 @@ import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.ValueJoiner;
 import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-import java.util.Arrays;
-import java.util.Collection;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
@@ -57,48 +52,26 @@ import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-
-@RunWith(Parameterized.class)
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class KTableKTableForeignKeyJoinMaterializationIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final String LEFT_TABLE = "left_table";
     private static final String RIGHT_TABLE = "right_table";
     private static final String OUTPUT = "output-topic";
-    private final boolean materialized;
-    private final boolean queryable;
 
     private Properties streamsConfig;
 
-    public KTableKTableForeignKeyJoinMaterializationIntegrationTest(final boolean materialized, final boolean queryable) {
-        this.materialized = materialized;
-        this.queryable = queryable;
-    }
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Before
+    @BeforeEach
     public void before() {
         streamsConfig = mkProperties(mkMap(
             mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath())
         ));
     }
 
-
-    @Parameterized.Parameters(name = "materialized={0}, queryable={1}")
-    public static Collection<Object[]> data() {
-        return Arrays.asList(
-            new Object[] {false, false},
-            new Object[] {true, false},
-            new Object[] {true, true}
-        );
-    }
-
-    @Test
-    public void shouldEmitTombstoneWhenDeletingNonJoiningRecords() {
-        final Topology topology = getTopology(streamsConfig, "store");
+    @ParameterizedTest
+    @CsvSource({"false, false", "true, false", "true, true"})
+    public void shouldEmitTombstoneWhenDeletingNonJoiningRecords(final boolean materialized, final boolean queryable) {
+        final Topology topology = getTopology(streamsConfig, "store", materialized, queryable);
         try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
             final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
             final TestOutputTopic<String, String> outputTopic = driver.createOutputTopic(OUTPUT, new StringDeserializer(), new StringDeserializer());
@@ -167,7 +140,9 @@ public class KTableKTableForeignKeyJoinMaterializationIntegrationTest {
     }
 
     private Topology getTopology(final Properties streamsConfig,
-                                 final String queryableStoreName) {
+                                 final String queryableStoreName,
+                                 final boolean materialized,
+                                 final boolean queryable) {
         final StreamsBuilder builder = new StreamsBuilder();
 
         final KTable<String, String> left = builder.table(LEFT_TABLE, Consumed.with(Serdes.String(), Serdes.String()));
@@ -176,20 +151,20 @@ public class KTableKTableForeignKeyJoinMaterializationIntegrationTest {
         final Function<String, String> extractor = value -> value.split("\\|")[1];
         final ValueJoiner<String, String, String> joiner = (value1, value2) -> "(" + value1 + "," + value2 + ")";
 
-        final Materialized<String, String, KeyValueStore<Bytes, byte[]>> materialized;
+        final Materialized<String, String, KeyValueStore<Bytes, byte[]>> materializedStore;
         if (queryable) {
-            materialized = Materialized.<String, String, KeyValueStore<Bytes, byte[]>>as(queryableStoreName).withValueSerde(Serdes.String());
+            materializedStore = Materialized.<String, String, KeyValueStore<Bytes, byte[]>>as(queryableStoreName).withValueSerde(Serdes.String());
         } else {
-            materialized = Materialized.with(null, Serdes.String());
+            materializedStore = Materialized.with(null, Serdes.String());
         }
 
         final KTable<String, String> joinResult;
-        if (this.materialized) {
+        if (materialized) {
             joinResult = left.join(
                 right,
                 extractor,
                 joiner,
-                materialized
+                materializedStore
             );
         } else {
             joinResult = left.join(
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyVersionedJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyVersionedJoinIntegrationTest.java
deleted file mode 100644
index 3703c910388..00000000000
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableKTableForeignKeyVersionedJoinIntegrationTest.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.kafka.streams.integration;
-
-import static java.util.Collections.emptyMap;
-import static org.apache.kafka.common.utils.Utils.mkEntry;
-import static org.apache.kafka.common.utils.Utils.mkMap;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import org.apache.kafka.common.serialization.StringDeserializer;
-import org.apache.kafka.common.serialization.StringSerializer;
-import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.TestInputTopic;
-import org.apache.kafka.streams.TestOutputTopic;
-import org.apache.kafka.streams.Topology;
-import org.apache.kafka.streams.TopologyTestDriver;
-import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-@Category(IntegrationTest.class)
-public class KTableKTableForeignKeyVersionedJoinIntegrationTest extends KTableKTableForeignKeyJoinIntegrationTest {
-
-    public KTableKTableForeignKeyVersionedJoinIntegrationTest(final boolean leftJoin,
-                                                              final boolean materialized,
-                                                              final boolean leftVersioned,
-                                                              final boolean rightVersioned) {
-        // optimizations and rejoin are disabled for these tests, as these tests focus on versioning.
-        // see KTableKTableForeignKeyJoinIntegrationTest for test coverage for optimizations and rejoin
-        super(leftJoin, StreamsConfig.NO_OPTIMIZATION, materialized, false, leftVersioned, rightVersioned);
-    }
-
-    @Parameterized.Parameters(name = "leftJoin={0}, materialized={1}, leftVersioned={2}, rightVersioned={3}")
-    public static Collection<Object[]> data() {
-        final List<Boolean> booleans = Arrays.asList(true, false);
-        return buildParameters(booleans, booleans, booleans, booleans);
-    }
-
-    @Test
-    public void shouldIgnoreOutOfOrderRecordsIffVersioned() {
-        final Topology topology = getTopology(streamsConfig, materialized ? "store" : null, leftJoin, rejoin, leftVersioned, rightVersioned);
-        try (final TopologyTestDriver driver = new TopologyTestDriver(topology, streamsConfig)) {
-            final TestInputTopic<String, String> right = driver.createInputTopic(RIGHT_TABLE, new StringSerializer(), new StringSerializer());
-            final TestInputTopic<String, String> left = driver.createInputTopic(LEFT_TABLE, new StringSerializer(), new StringSerializer());
-            final TestOutputTopic<String, String> outputTopic = driver.createOutputTopic(OUTPUT, new StringDeserializer(), new StringDeserializer());
-            final KeyValueStore<String, String> store = driver.getKeyValueStore("store");
-
-            // RHS record
-            right.pipeInput("rhs1", "rhsValue1", baseTimestamp + 4);
-
-            assertThat(
-                outputTopic.readKeyValuesToMap(),
-                is(emptyMap())
-            );
-            if (materialized) {
-                assertThat(
-                    asMap(store),
-                    is(emptyMap())
-                );
-            }
-
-            // LHS records with match to existing RHS record
-            left.pipeInput("lhs1", "lhsValue1|rhs1", baseTimestamp + 3);
-            left.pipeInput("lhs2", "lhsValue2|rhs1", baseTimestamp + 5);
-            {
-                final Map<String, String> expected = mkMap(
-                    mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)"),
-                    mkEntry("lhs2", "(lhsValue2|rhs1,rhsValue1)")
-                );
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(expected)
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(expected)
-                    );
-                }
-            }
-
-            // replace with tombstone, to validate behavior when latest record is null
-            left.pipeInput("lhs2", null, baseTimestamp + 6);
-            {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(mkMap(
-                        mkEntry("lhs2", null)
-                    ))
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            }
-
-            // out-of-order LHS record (for existing key) does not produce a new result iff LHS is versioned
-            left.pipeInput("lhs1", "lhsValue1_ooo|rhs1", baseTimestamp + 2);
-            left.pipeInput("lhs2", "lhsValue2_ooo|rhs1", baseTimestamp + 2);
-            if (leftVersioned) {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(emptyMap())
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            } else {
-                final Map<String, String> expected = mkMap(
-                    mkEntry("lhs1", "(lhsValue1_ooo|rhs1,rhsValue1)"),
-                    mkEntry("lhs2", "(lhsValue2_ooo|rhs1,rhsValue1)")
-                );
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(expected)
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(expected)
-                    );
-                }
-            }
-
-            // out-of-order LHS tombstone (for existing key) is similarly ignored (iff LHS is versioned)
-            left.pipeInput("lhs1", null, baseTimestamp + 2);
-            if (leftVersioned) {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(emptyMap())
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            } else {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(mkMap(
-                        mkEntry("lhs1", null)
-                    ))
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs2", "(lhsValue2_ooo|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            }
-
-            // LHS record with larger timestamp always produces a new result
-            left.pipeInput("lhs1", "lhsValue1_new|rhs1", baseTimestamp + 8);
-            left.pipeInput("lhs2", "lhsValue2_new|rhs1", baseTimestamp + 8);
-            {
-                final Map<String, String> expected = mkMap(
-                    mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
-                    mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
-                );
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(expected)
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(expected)
-                    );
-                }
-            }
-
-            // out-of-order RHS record (for existing key) does not produce a new result iff RHS is versioned
-            right.pipeInput("rhs1", "rhsValue1_ooo", baseTimestamp + 1);
-            if (rightVersioned) {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(emptyMap())
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
-                            mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            } else {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(mkMap(
-                        mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_ooo)"),
-                        mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_ooo)")
-                    ))
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_ooo)"),
-                            mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_ooo)")
-                        ))
-                    );
-                }
-            }
-
-            // out-of-order RHS tombstone (for existing key) is similarly ignored (iff RHS is versioned)
-            right.pipeInput("rhs1", null, baseTimestamp + 1);
-            if (rightVersioned) {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(emptyMap())
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1)"),
-                            mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1)")
-                        ))
-                    );
-                }
-            } else {
-                if (leftJoin) {
-                    assertThat(
-                        outputTopic.readKeyValuesToMap(),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1_new|rhs1,null)"),
-                            mkEntry("lhs2", "(lhsValue2_new|rhs1,null)")
-                        ))
-                    );
-                    if (materialized) {
-                        assertThat(
-                            asMap(store),
-                            is(mkMap(
-                                mkEntry("lhs1", "(lhsValue1_new|rhs1,null)"),
-                                mkEntry("lhs2", "(lhsValue2_new|rhs1,null)")
-                            ))
-                        );
-                    }
-                } else {
-                    assertThat(
-                        outputTopic.readKeyValuesToMap(),
-                        is(mkMap(
-                            mkEntry("lhs1", null),
-                            mkEntry("lhs2", null)
-                        ))
-                    );
-                    if (materialized) {
-                        assertThat(
-                            asMap(store),
-                            is(emptyMap())
-                        );
-                    }
-                }
-            }
-
-            // RHS record with larger timestamps always produces new results
-            right.pipeInput("rhs1", "rhsValue1_new", baseTimestamp + 6);
-            {
-                assertThat(
-                    outputTopic.readKeyValuesToMap(),
-                    is(mkMap(
-                        mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_new)"),
-                        mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_new)")
-                    ))
-                );
-                if (materialized) {
-                    assertThat(
-                        asMap(store),
-                        is(mkMap(
-                            mkEntry("lhs1", "(lhsValue1_new|rhs1,rhsValue1_new)"),
-                            mkEntry("lhs2", "(lhsValue2_new|rhs1,rhsValue1_new)")
-                        ))
-                    );
-                }
-            }
-        }
-    }
-}
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KTableSourceTopicRestartIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KTableSourceTopicRestartIntegrationTest.java
index d16aa2f0254..50621fc095b 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KTableSourceTopicRestartIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KTableSourceTopicRestartIntegrationTest.java
@@ -34,6 +34,7 @@ import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.processor.StateRestoreListener;
 import org.apache.kafka.streams.processor.WallclockTimestampExtractor;
 import org.apache.kafka.test.TestUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/KafkaStreamsCloseOptionsIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/KafkaStreamsCloseOptionsIntegrationTest.java
index 4fe1952f9bb..c7c34600fc8 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/KafkaStreamsCloseOptionsIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/KafkaStreamsCloseOptionsIntegrationTest.java
@@ -26,6 +26,7 @@ import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.common.utils.MockTime;
+import org.apache.kafka.common.utils.Utils;
 import org.apache.kafka.coordinator.group.GroupCoordinatorConfig;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KafkaStreams.CloseOptions;
@@ -37,19 +38,18 @@ import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Produced;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
 
+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.junit.jupiter.api.Timeout;
+
+import java.io.File;
 import java.io.IOException;
 import java.time.Duration;
 import java.util.Arrays;
@@ -59,17 +59,11 @@ import java.util.Properties;
 
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForEmptyConsumerGroup;
 
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class KafkaStreamsCloseOptionsIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-    @Rule
-    public final TestName testName = new TestName();
     private static MockTime mockTime;
 
-    @Rule
-    public final TemporaryFolder testFolder = new TemporaryFolder(TestUtils.tempDirectory());
-
     protected static final String INPUT_TOPIC = "inputTopic";
     protected static final String OUTPUT_TOPIC = "outputTopic";
 
@@ -79,6 +73,7 @@ public class KafkaStreamsCloseOptionsIntegrationTest {
     protected Properties commonClientConfig;
     private Properties producerConfig;
     protected Properties resultConsumerConfig;
+    private final File testFolder = TestUtils.tempDirectory();
 
     public static final EmbeddedKafkaCluster CLUSTER;
 
@@ -88,18 +83,18 @@ public class KafkaStreamsCloseOptionsIntegrationTest {
         CLUSTER = new EmbeddedKafkaCluster(1, brokerProps);
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Before
-    public void before() throws Exception {
+    @BeforeEach
+    public void before(final TestInfo testName) throws Exception {
         mockTime = CLUSTER.time;
 
         final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
@@ -110,7 +105,7 @@ public class KafkaStreamsCloseOptionsIntegrationTest {
         streamsConfig = new Properties();
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
         streamsConfig.put(ConsumerConfig.GROUP_INSTANCE_ID_CONFIG, "someGroupInstance");
-        streamsConfig.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getRoot().getPath());
+        streamsConfig.put(StreamsConfig.STATE_DIR_CONFIG, testFolder.getPath());
         streamsConfig.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Long().getClass());
         streamsConfig.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfig.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
@@ -146,11 +141,12 @@ public class KafkaStreamsCloseOptionsIntegrationTest {
         add10InputElements();
     }
 
-    @After
+    @AfterEach
     public void after() throws Exception {
         if (streams != null) {
             streams.close(Duration.ofSeconds(30));
         }
+        Utils.delete(testFolder);
     }
 
     @Test
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/LagFetchIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/LagFetchIntegrationTest.java
index 0d7be9b8e14..810abe73cd4 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/LagFetchIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/LagFetchIntegrationTest.java
@@ -38,14 +38,15 @@ import org.apache.kafka.streams.processor.StateRestoreListener;
 import org.apache.kafka.streams.processor.internals.StreamThread;
 import org.apache.kafka.streams.processor.internals.assignment.FallbackPriorTaskAssignor;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/MetricsIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/MetricsIntegrationTest.java
index 663fb22c5b2..d13de4b402b 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/MetricsIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/MetricsIntegrationTest.java
@@ -42,14 +42,15 @@ import org.apache.kafka.streams.state.SessionStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.WindowStore;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.time.Duration;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/MetricsReporterIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/MetricsReporterIntegrationTest.java
index b9b34be5e6c..e08146ebf7a 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/MetricsReporterIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/MetricsReporterIntegrationTest.java
@@ -27,13 +27,14 @@ import org.apache.kafka.streams.Topology;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.kstream.Consumed;
 import org.apache.kafka.streams.kstream.Produced;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.HashMap;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/NamedTopologyIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/NamedTopologyIntegrationTest.java
index 9d9c77850e2..4e341b07234 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/NamedTopologyIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/NamedTopologyIntegrationTest.java
@@ -55,31 +55,33 @@ import org.apache.kafka.streams.state.internals.StreamsMetadataImpl;
 import org.apache.kafka.streams.utils.UniqueTopicSerdeScope;
 import org.apache.kafka.test.TestUtils;
 
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Queue;
-import org.junit.jupiter.api.Disabled;
 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.Disabled;
+import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.time.Duration;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
+import java.util.Queue;
 import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.singleton;
 import static org.apache.kafka.common.utils.Utils.mkSet;
 import static org.apache.kafka.streams.KeyQueryMetadata.NOT_AVAILABLE;
 import static org.apache.kafka.streams.KeyValue.pair;
@@ -87,13 +89,10 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.DE
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForApplicationState;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitUntilMinKeyValueRecordsReceived;
-
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static java.util.Arrays.asList;
-import static java.util.Collections.singleton;
 
 @Timeout(600)
 @Tag("integration")
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/OptimizedKTableIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/OptimizedKTableIntegrationTest.java
index 5d1a46f89e3..5c2d07fb20f 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/OptimizedKTableIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/OptimizedKTableIntegrationTest.java
@@ -16,23 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.is;
-
-import java.io.IOException;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.serialization.IntegerSerializer;
@@ -54,17 +37,36 @@ import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.test.NoRetryException;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
 @Timeout(600)
 @Tag("integration")
 public class OptimizedKTableIntegrationTest {
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/PauseResumeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/PauseResumeIntegrationTest.java
index 3f4412256b7..f20c350d037 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/PauseResumeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/PauseResumeIntegrationTest.java
@@ -36,6 +36,7 @@ import org.apache.kafka.streams.processor.internals.namedtopology.NamedTopologyB
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.CoreMatchers;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -44,7 +45,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.time.Duration;
 import java.util.ArrayList;
@@ -52,7 +53,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Properties;
-import java.util.stream.Stream;
 
 import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
@@ -65,9 +65,9 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.wa
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitUntilStreamsHasPolled;
 import static org.apache.kafka.test.TestUtils.waitForCondition;
 import static org.hamcrest.MatcherAssert.assertThat;
-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;
 
 @Tag("integration")
 public class PauseResumeIntegrationTest {
@@ -101,13 +101,6 @@ public class PauseResumeIntegrationTest {
     private KafkaStreams kafkaStreams, kafkaStreams2;
     private KafkaStreamsNamedTopologyWrapper streamsNamedTopologyWrapper;
 
-
-    private static Stream<Boolean> parameters() {
-        return Stream.of(
-            Boolean.TRUE,
-            Boolean.FALSE);
-    }
-
     @BeforeAll
     public static void startCluster() throws Exception {
         CLUSTER.start();
@@ -158,7 +151,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldPauseAndResumeKafkaStreams(final boolean stateUpdaterEnabled) throws Exception {
         kafkaStreams = buildKafkaStreams(OUTPUT_STREAM_1, stateUpdaterEnabled);
         kafkaStreams.start();
@@ -183,7 +176,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldAllowForTopologiesToStartPaused(final boolean stateUpdaterEnabled) throws Exception {
         kafkaStreams = buildKafkaStreams(OUTPUT_STREAM_1, stateUpdaterEnabled);
         kafkaStreams.pause();
@@ -204,7 +197,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldPauseAndResumeKafkaStreamsWithNamedTopologies(final boolean stateUpdaterEnabled) throws Exception {
         streamsNamedTopologyWrapper = new KafkaStreamsNamedTopologyWrapper(props(stateUpdaterEnabled));
         final NamedTopologyBuilder builder1 = getNamedTopologyBuilder1();
@@ -239,7 +232,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldPauseAndResumeAllKafkaStreamsWithNamedTopologies(final boolean stateUpdaterEnabled) throws Exception {
         streamsNamedTopologyWrapper = new KafkaStreamsNamedTopologyWrapper(props(stateUpdaterEnabled));
         final NamedTopologyBuilder builder1 = getNamedTopologyBuilder1();
@@ -275,7 +268,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldAllowForNamedTopologiesToStartPaused(final boolean stateUpdaterEnabled) throws Exception {
         streamsNamedTopologyWrapper = new KafkaStreamsNamedTopologyWrapper(props(stateUpdaterEnabled));
         final NamedTopologyBuilder builder1 = getNamedTopologyBuilder1();
@@ -305,7 +298,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void pauseResumeShouldWorkAcrossInstances(final boolean stateUpdaterEnabled) throws Exception {
         produceToInputTopics(INPUT_STREAM_1, STANDARD_INPUT_DATA);
 
@@ -335,7 +328,7 @@ public class PauseResumeIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void pausedTopologyShouldNotRestoreStateStores(final boolean stateUpdaterEnabled) throws Exception {
         final Properties properties1 = props(stateUpdaterEnabled);
         properties1.put(StreamsConfig.NUM_STANDBY_REPLICAS_CONFIG, 1);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/PositionRestartIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/PositionRestartIntegrationTest.java
index 1c40b1ea6fb..044acfac8b0 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/PositionRestartIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/PositionRestartIntegrationTest.java
@@ -61,18 +61,16 @@ import org.apache.kafka.streams.state.TimestampedWindowStore;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.state.WindowBytesStoreSupplier;
 import org.apache.kafka.streams.state.WindowStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -81,7 +79,6 @@ import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
@@ -92,6 +89,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.stream.Stream;
 
 import static org.apache.kafka.common.utils.Utils.mkSet;
 import static org.apache.kafka.streams.query.StateQueryRequest.inStore;
@@ -99,11 +97,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.is;
 
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class PositionRestartIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final Logger LOG = LoggerFactory.getLogger(PositionRestartIntegrationTest.class);
     private static final long SEED = new Random().nextLong();
     private static final int NUM_BROKERS = 1;
@@ -116,12 +112,7 @@ public class PositionRestartIntegrationTest {
     private static final long WINDOW_START =
         (RECORD_TIME / WINDOW_SIZE.toMillis()) * WINDOW_SIZE.toMillis();
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(NUM_BROKERS);
-    private final StoresToTest storeToTest;
-    private final String kind;
-    private final boolean cache;
-    private final boolean log;
     private KafkaStreams kafkaStreams;
-    private final Properties streamsConfig;
 
     public enum StoresToTest {
         IN_MEMORY_KV {
@@ -259,10 +250,9 @@ public class PositionRestartIntegrationTest {
         }
     }
 
-    @Parameterized.Parameters(name = "cache={0}, log={1}, supplier={2}, kind={3}")
-    public static Collection<Object[]> data() {
+    public static Stream<Arguments> data() {
         LOG.info("Generating test cases according to random seed: {}", SEED);
-        final List<Object[]> values = new ArrayList<>();
+        final List<Arguments> values = new ArrayList<>();
         for (final boolean cacheEnabled : Arrays.asList(true, false)) {
             for (final boolean logEnabled : Arrays.asList(true, false)) {
                 for (final StoresToTest toTest : StoresToTest.values()) {
@@ -270,33 +260,16 @@ public class PositionRestartIntegrationTest {
                     // survive restarts, since those are by definition not durable.
                     if (logEnabled || toTest.supplier().get().persistent()) {
                         for (final String kind : Arrays.asList("DSL", "PAPI")) {
-                            values.add(new Object[]{cacheEnabled, logEnabled, toTest.name(), kind});
+                            values.add(Arguments.of(cacheEnabled, logEnabled, toTest, kind));
                         }
                     }
                 }
             }
         }
-        return values;
-    }
-
-    public PositionRestartIntegrationTest(
-        final boolean cache,
-        final boolean log,
-        final String storeToTest,
-        final String kind) {
-        this.cache = cache;
-        this.log = log;
-        this.storeToTest = StoresToTest.valueOf(storeToTest);
-        this.kind = kind;
-        this.streamsConfig = streamsConfiguration(
-            cache,
-            log,
-            storeToTest,
-            kind
-        );
+        return values.stream();
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void before()
         throws InterruptedException, IOException, ExecutionException, TimeoutException {
 
@@ -347,65 +320,52 @@ public class PositionRestartIntegrationTest {
         ));
     }
 
-    @Before
-    public void beforeTest() {
-        beforeTest(true);
-    }
-
-    public void beforeTest(final boolean cleanup) {
+    public static StreamsBuilder getStreamBuilder(final boolean cache,
+                                           final boolean log,
+                                           final StoresToTest storeToTest,
+                                           final String kind) {
         final StoreSupplier<?> supplier = storeToTest.supplier();
 
         final StreamsBuilder builder = new StreamsBuilder();
         if (Objects.equals(kind, "DSL") && supplier instanceof KeyValueBytesStoreSupplier) {
-            setUpKeyValueDSLTopology((KeyValueBytesStoreSupplier) supplier, builder);
+            setUpKeyValueDSLTopology((KeyValueBytesStoreSupplier) supplier, builder, cache, log);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof KeyValueBytesStoreSupplier) {
-            setUpKeyValuePAPITopology((KeyValueBytesStoreSupplier) supplier, builder);
+            setUpKeyValuePAPITopology((KeyValueBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else if (Objects.equals(kind, "DSL") && supplier instanceof WindowBytesStoreSupplier) {
-            setUpWindowDSLTopology((WindowBytesStoreSupplier) supplier, builder);
+            setUpWindowDSLTopology((WindowBytesStoreSupplier) supplier, builder, cache, log);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof WindowBytesStoreSupplier) {
-            setUpWindowPAPITopology((WindowBytesStoreSupplier) supplier, builder);
+            setUpWindowPAPITopology((WindowBytesStoreSupplier) supplier, builder, cache, log, storeToTest);
         } else if (Objects.equals(kind, "DSL") && supplier instanceof SessionBytesStoreSupplier) {
-            setUpSessionDSLTopology((SessionBytesStoreSupplier) supplier, builder);
+            setUpSessionDSLTopology((SessionBytesStoreSupplier) supplier, builder, cache, log);
         } else if (Objects.equals(kind, "PAPI") && supplier instanceof SessionBytesStoreSupplier) {
-            setUpSessionPAPITopology((SessionBytesStoreSupplier) supplier, builder);
+            setUpSessionPAPITopology((SessionBytesStoreSupplier) supplier, builder, cache, log);
         } else {
             throw new AssertionError("Store supplier is an unrecognized type.");
         }
 
-        kafkaStreams =
-            IntegrationTestUtils.getStartedStreams(
-                streamsConfig,
-                builder,
-                cleanup
-            );
+        return builder;
     }
 
-    @After
+    @AfterEach
     public void afterTest() {
-        afterTest(true);
-    }
-
-    public void afterTest(final boolean cleanup) {
         if (kafkaStreams != null) {
             kafkaStreams.close();
-            if (cleanup) {
-                kafkaStreams.cleanUp();
-            }
+            kafkaStreams.cleanUp();
         }
     }
 
-    @AfterClass
+    @AfterAll
     public static void after() {
         CLUSTER.stop();
     }
 
-    public void reboot() {
-        afterTest(false);
-        beforeTest(false);
-    }
+    @ParameterizedTest
+    @MethodSource("data")
+    public void verifyStore(final boolean cache, final boolean log, final StoresToTest storeToTest, final String kind) {
+        final Properties streamsConfig = streamsConfiguration(cache, log, storeToTest.name(), kind);
+        final StreamsBuilder streamsBuilder = getStreamBuilder(cache, log, storeToTest, kind);
+        kafkaStreams = IntegrationTestUtils.getStartedStreams(streamsConfig, streamsBuilder, true);
 
-    @Test
-    public void verifyStore() {
         final Query<?> query;
         if (storeToTest.keyValue()) {
             query = RangeQuery.withNoBounds();
@@ -422,7 +382,9 @@ public class PositionRestartIntegrationTest {
         }
         shouldReachExpectedPosition(query);
 
-        reboot();
+        // reboot
+        kafkaStreams.close();
+        kafkaStreams = IntegrationTestUtils.getStartedStreams(streamsConfig, streamsBuilder, false);
 
         shouldReachExpectedPosition(query);
     }
@@ -440,8 +402,10 @@ public class PositionRestartIntegrationTest {
         assertThat(result.getPosition(), is(INPUT_POSITION));
     }
 
-    private void setUpSessionDSLTopology(final SessionBytesStoreSupplier supplier,
-                                         final StreamsBuilder builder) {
+    private static void setUpSessionDSLTopology(final SessionBytesStoreSupplier supplier,
+                                         final StreamsBuilder builder,
+                                         final boolean cache,
+                                         final boolean log) {
         final Materialized<Integer, Integer, SessionStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -469,8 +433,10 @@ public class PositionRestartIntegrationTest {
             );
     }
 
-    private void setUpWindowDSLTopology(final WindowBytesStoreSupplier supplier,
-                                        final StreamsBuilder builder) {
+    private static void setUpWindowDSLTopology(final WindowBytesStoreSupplier supplier,
+                                        final StreamsBuilder builder,
+                                        final boolean cache,
+                                        final boolean log) {
         final Materialized<Integer, Integer, WindowStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -497,8 +463,10 @@ public class PositionRestartIntegrationTest {
             );
     }
 
-    private void setUpKeyValueDSLTopology(final KeyValueBytesStoreSupplier supplier,
-                                          final StreamsBuilder builder) {
+    private static void setUpKeyValueDSLTopology(final KeyValueBytesStoreSupplier supplier,
+                                          final StreamsBuilder builder,
+                                          final boolean cache,
+                                          final boolean log) {
         final Materialized<Integer, Integer, KeyValueStore<Bytes, byte[]>> materialized =
             Materialized.as(supplier);
 
@@ -521,8 +489,11 @@ public class PositionRestartIntegrationTest {
         );
     }
 
-    private void setUpKeyValuePAPITopology(final KeyValueBytesStoreSupplier supplier,
-                                           final StreamsBuilder builder) {
+    private static void setUpKeyValuePAPITopology(final KeyValueBytesStoreSupplier supplier,
+                                           final StreamsBuilder builder,
+                                           final boolean cache,
+                                           final boolean log,
+                                           final StoresToTest storeToTest) {
         final StoreBuilder<?> keyValueStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         if (storeToTest.timestamped()) {
@@ -577,8 +548,11 @@ public class PositionRestartIntegrationTest {
 
     }
 
-    private void setUpWindowPAPITopology(final WindowBytesStoreSupplier supplier,
-                                         final StreamsBuilder builder) {
+    private static void setUpWindowPAPITopology(final WindowBytesStoreSupplier supplier,
+                                         final StreamsBuilder builder,
+                                         final boolean cache,
+                                         final boolean log,
+                                         final StoresToTest storeToTest) {
         final StoreBuilder<?> windowStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         if (storeToTest.timestamped()) {
@@ -634,8 +608,10 @@ public class PositionRestartIntegrationTest {
 
     }
 
-    private void setUpSessionPAPITopology(final SessionBytesStoreSupplier supplier,
-                                          final StreamsBuilder builder) {
+    private static void setUpSessionPAPITopology(final SessionBytesStoreSupplier supplier,
+                                          final StreamsBuilder builder,
+                                          final boolean cache,
+                                          final boolean log) {
         final StoreBuilder<?> sessionStoreStoreBuilder;
         final ProcessorSupplier<Integer, Integer, Void, Void> processorSupplier;
         sessionStoreStoreBuilder = Stores.sessionStoreBuilder(
@@ -670,8 +646,10 @@ public class PositionRestartIntegrationTest {
             .process(processorSupplier, sessionStoreStoreBuilder.name());
     }
 
-    private static Properties streamsConfiguration(final boolean cache, final boolean log,
-                                                   final String supplier, final String kind) {
+    private static Properties streamsConfiguration(final boolean cache,
+                                            final boolean log,
+                                            final String supplier,
+                                            final String kind) {
         final String safeTestName =
             PositionRestartIntegrationTest.class.getName() + "-" + cache + "-" + log + "-"
                 + supplier + "-" + kind;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/PurgeRepartitionTopicIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/PurgeRepartitionTopicIntegrationTest.java
index 71c9d483dc9..b484a7d8834 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/PurgeRepartitionTopicIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/PurgeRepartitionTopicIntegrationTest.java
@@ -37,13 +37,14 @@ import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.test.MockMapper;
 import org.apache.kafka.test.TestCondition;
 import org.apache.kafka.test.TestUtils;
+
 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.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.time.Duration;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/QueryableStateIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/QueryableStateIntegrationTest.java
index df87793420b..2dcf1ba54df 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/QueryableStateIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/QueryableStateIntegrationTest.java
@@ -59,15 +59,16 @@ import org.apache.kafka.streams.state.WindowStoreIterator;
 import org.apache.kafka.test.MockMapper;
 import org.apache.kafka.test.NoRetryException;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.Matchers;
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/RangeQueryIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/RangeQueryIntegrationTest.java
index 7ad97b151d7..477024dce53 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/RangeQueryIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/RangeQueryIntegrationTest.java
@@ -35,20 +35,17 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-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.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -60,15 +57,15 @@ import java.util.List;
 import java.util.Properties;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
+import java.util.stream.Stream;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class RangeQueryIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
     private static final Properties STREAMS_CONFIG = new Properties();
     private static final String APP_ID = "range-query-integration-test";
@@ -79,10 +76,6 @@ public class RangeQueryIntegrationTest {
 
     private enum StoreType { InMemory, RocksDB, Timed }
 
-    private final StoreType storeType;
-    private final boolean enableLogging;
-    private final boolean enableCaching;
-    private final boolean forward;
     private final LinkedList<KeyValue<String, String>> records;
 
     private String low;
@@ -93,12 +86,7 @@ public class RangeQueryIntegrationTest {
     private String innerLowBetween;
     private String innerHighBetween;
 
-    public RangeQueryIntegrationTest(final StoreType storeType, final boolean enableLogging, final boolean enableCaching, final boolean forward) {
-        this.storeType = storeType;
-        this.enableLogging = enableLogging;
-        this.enableCaching = enableCaching;
-        this.forward = forward;
-
+    public RangeQueryIntegrationTest() {
         records = new LinkedList<>();
         final int m = DATA_SIZE / 2;
         for (int i = 0; i < DATA_SIZE; i++) {
@@ -123,28 +111,24 @@ public class RangeQueryIntegrationTest {
                 innerHighBetween = "key-" + index;
             }
         }
-        Assert.assertNotNull(low);
-        Assert.assertNotNull(high);
-        Assert.assertNotNull(middle);
-        Assert.assertNotNull(innerLow);
-        Assert.assertNotNull(innerHigh);
-        Assert.assertNotNull(innerLowBetween);
-        Assert.assertNotNull(innerHighBetween);
+        assertNotNull(low);
+        assertNotNull(high);
+        assertNotNull(middle);
+        assertNotNull(innerLow);
+        assertNotNull(innerHigh);
+        assertNotNull(innerLowBetween);
+        assertNotNull(innerHighBetween);
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
-    @Parameterized.Parameters(name = "storeType={0}, enableLogging={1}, enableCaching={2}, forward={3}")
-    public static Collection<Object[]> data() {
+    public static Stream<Arguments> data() {
         final List<StoreType> types = Arrays.asList(StoreType.InMemory, StoreType.RocksDB, StoreType.Timed);
         final List<Boolean> logging = Arrays.asList(true, false);
         final List<Boolean> caching = Arrays.asList(true, false);
         final List<Boolean> forward = Arrays.asList(true, false);
-        return buildParameters(types, logging, caching, forward);
+        return buildParameters(types, logging, caching, forward).stream().map(Arguments::of);
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
         STREAMS_CONFIG.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
@@ -156,24 +140,25 @@ public class RangeQueryIntegrationTest {
         STREAMS_CONFIG.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Before
+    @BeforeEach
     public void setupTopics() throws Exception {
         inputStream = "input-topic";
         CLUSTER.createTopic(inputStream);
     }
 
-    @After
+    @AfterEach
     public void cleanup() throws InterruptedException {
         CLUSTER.deleteAllTopicsAndWait(120000);
     }
 
-    @Test
-    public void testStoreConfig() throws Exception {
+    @ParameterizedTest
+    @MethodSource("data")
+    public void testStoreConfig(final StoreType storeType, final boolean enableLogging, final boolean enableCaching, final boolean forward) throws Exception {
         final StreamsBuilder builder = new StreamsBuilder();
         final Materialized<String, String, KeyValueStore<Bytes, byte[]>> stateStoreConfig = getStoreConfig(storeType, enableLogging, enableCaching);
         builder.table(inputStream, stateStoreConfig);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/RegexSourceIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/RegexSourceIntegrationTest.java
index cb5a3da1631..ae953020520 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/RegexSourceIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/RegexSourceIntegrationTest.java
@@ -46,14 +46,15 @@ import org.apache.kafka.test.MockKeyValueStoreBuilder;
 import org.apache.kafka.test.StreamsTestUtils;
 import org.apache.kafka.test.TestCondition;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.ArrayList;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/RelaxedNullKeyRequirementJoinTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/RelaxedNullKeyRequirementJoinTest.java
index a6ea2fba689..8789dadc090 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/RelaxedNullKeyRequirementJoinTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/RelaxedNullKeyRequirementJoinTest.java
@@ -29,6 +29,7 @@ import org.apache.kafka.streams.kstream.GlobalKTable;
 import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.ValueJoiner;
+
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationTest.java
index bb3a1ebf235..1c8599a3b19 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationTest.java
@@ -16,27 +16,24 @@
  */
 package org.apache.kafka.streams.integration;
 
-import org.apache.kafka.network.SocketServerConfigs;
-import org.apache.kafka.tools.StreamsResetter;
-
 import org.apache.kafka.clients.consumer.ConsumerConfig;
+import org.apache.kafka.network.SocketServerConfigs;
 import org.apache.kafka.streams.KafkaStreams;
 import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
-import org.apache.kafka.test.IntegrationTest;
-
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-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.experimental.categories.Category;
-import org.junit.rules.Timeout;
+import org.apache.kafka.tools.StreamsResetter;
+
+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.junit.jupiter.api.Timeout;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -52,14 +49,15 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.is
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForEmptyConsumerGroup;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 
 /**
  * Tests local state store and global application cleanup.
  */
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class ResetIntegrationTest extends AbstractResetIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final String NON_EXISTING_TOPIC = "nonExistingTopic";
 
     public static final EmbeddedKafkaCluster CLUSTER;
@@ -73,12 +71,12 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         CLUSTER = new EmbeddedKafkaCluster(1, brokerProps);
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -88,20 +86,20 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         return null;
     }
 
-    @Before
-    public void before() throws Exception {
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws Exception {
         cluster = CLUSTER;
-        prepareTest();
+        prepareTest(testInfo);
     }
 
-    @After
+    @AfterEach
     public void after() throws Exception {
         cleanupTest();
     }
 
     @Test
-    public void shouldNotAllowToResetWhileStreamsIsRunning() {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void shouldNotAllowToResetWhileStreamsIsRunning(final TestInfo testInfo) {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         final String[] parameters = new String[] {
             "--application-id", appID,
             "--bootstrap-server", cluster.bootstrapServers(),
@@ -118,14 +116,14 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         streams.start();
 
         final int exitCode = new StreamsResetter().execute(parameters, cleanUpConfig);
-        Assert.assertEquals(1, exitCode);
+        assertEquals(1, exitCode);
 
         streams.close();
     }
 
     @Test
-    public void shouldNotAllowToResetWhenInputTopicAbsent() {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void shouldNotAllowToResetWhenInputTopicAbsent(final TestInfo testInfo) {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         final String[] parameters = new String[] {
             "--application-id", appID,
             "--bootstrap-server", cluster.bootstrapServers(),
@@ -136,12 +134,12 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         cleanUpConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, Integer.toString(CLEANUP_CONSUMER_TIMEOUT));
 
         final int exitCode = new StreamsResetter().execute(parameters, cleanUpConfig);
-        Assert.assertEquals(1, exitCode);
+        assertEquals(1, exitCode);
     }
 
     @Test
-    public void shouldNotAllowToResetWhenIntermediateTopicAbsent() {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void shouldNotAllowToResetWhenIntermediateTopicAbsent(final TestInfo testInfo) {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         final String[] parameters = new String[] {
             "--application-id", appID,
             "--bootstrap-server", cluster.bootstrapServers(),
@@ -152,12 +150,12 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         cleanUpConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, Integer.toString(CLEANUP_CONSUMER_TIMEOUT));
 
         final int exitCode = new StreamsResetter().execute(parameters, cleanUpConfig);
-        Assert.assertEquals(1, exitCode);
+        assertEquals(1, exitCode);
     }
 
     @Test
-    public void shouldNotAllowToResetWhenSpecifiedInternalTopicDoesNotExist() {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void shouldNotAllowToResetWhenSpecifiedInternalTopicDoesNotExist(final TestInfo testInfo) {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         final String[] parameters = new String[] {
             "--application-id", appID,
             "--bootstrap-server", cluster.bootstrapServers(),
@@ -168,12 +166,12 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         cleanUpConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, Integer.toString(CLEANUP_CONSUMER_TIMEOUT));
 
         final int exitCode = new StreamsResetter().execute(parameters, cleanUpConfig);
-        Assert.assertEquals(1, exitCode);
+        assertEquals(1, exitCode);
     }
 
     @Test
-    public void shouldNotAllowToResetWhenSpecifiedInternalTopicIsNotInternal() {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void shouldNotAllowToResetWhenSpecifiedInternalTopicIsNotInternal(final TestInfo testInfo) {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         final String[] parameters = new String[] {
             "--application-id", appID,
             "--bootstrap-server", cluster.bootstrapServers(),
@@ -184,12 +182,12 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
         cleanUpConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, Integer.toString(CLEANUP_CONSUMER_TIMEOUT));
 
         final int exitCode = new StreamsResetter().execute(parameters, cleanUpConfig);
-        Assert.assertEquals(1, exitCode);
+        assertEquals(1, exitCode);
     }
 
     @Test
-    public void testResetWhenLongSessionTimeoutConfiguredWithForceOption() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testResetWhenLongSessionTimeoutConfiguredWithForceOption(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
         streamsConfig.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, Integer.toString(STREAMS_CONSUMER_TIMEOUT * 100));
 
@@ -206,7 +204,7 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
 
         // Reset would fail since long session timeout has been configured
         final boolean cleanResult = tryCleanGlobal(false, null, null, appID);
-        Assert.assertFalse(cleanResult);
+        assertFalse(cleanResult);
 
         // Reset will success with --force, it will force delete active members on broker side
         cleanGlobal(false, "--force", null, appID);
@@ -224,8 +222,8 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testReprocessingFromFileAfterResetWithoutIntermediateUserTopic() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testReprocessingFromFileAfterResetWithoutIntermediateUserTopic(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
@@ -265,8 +263,8 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testReprocessingFromDateTimeAfterResetWithoutIntermediateUserTopic() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testReprocessingFromDateTimeAfterResetWithoutIntermediateUserTopic(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
@@ -310,8 +308,8 @@ public class ResetIntegrationTest extends AbstractResetIntegrationTest {
     }
 
     @Test
-    public void testReprocessingByDurationAfterResetWithoutIntermediateUserTopic() throws Exception {
-        final String appID = IntegrationTestUtils.safeUniqueTestName(testName);
+    public void testReprocessingByDurationAfterResetWithoutIntermediateUserTopic(final TestInfo testInfo) throws Exception {
+        final String appID = IntegrationTestUtils.safeUniqueTestName(testInfo);
         streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, appID);
 
         // RUN
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationWithSslTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationWithSslTest.java
index a12a6138a1c..1574098e7cb 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationWithSslTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/ResetIntegrationWithSslTest.java
@@ -19,14 +19,15 @@ package org.apache.kafka.streams.integration;
 import org.apache.kafka.common.network.Mode;
 import org.apache.kafka.network.SocketServerConfigs;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestSslUtils;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.TestInfo;
 
 import java.io.IOException;
 import java.util.Map;
@@ -37,7 +38,7 @@ import static org.apache.kafka.server.config.ReplicationConfigs.INTER_BROKER_LIS
 /**
  * Tests command line SSL setup for reset tool.
  */
-@Category({IntegrationTest.class})
+@Tag("integration")
 public class ResetIntegrationWithSslTest extends AbstractResetIntegrationTest {
 
     public static final EmbeddedKafkaCluster CLUSTER;
@@ -64,12 +65,12 @@ public class ResetIntegrationWithSslTest extends AbstractResetIntegrationTest {
         CLUSTER = new EmbeddedKafkaCluster(1, brokerProps);
     }
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -79,13 +80,13 @@ public class ResetIntegrationWithSslTest extends AbstractResetIntegrationTest {
         return SSL_CONFIG;
     }
 
-    @Before
-    public void before() throws Exception {
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws Exception {
         cluster = CLUSTER;
-        prepareTest();
+        prepareTest(testInfo);
     }
 
-    @After 
+    @AfterEach
     public void after() throws Exception {
         cleanupTest();
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/ResetPartitionTimeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/ResetPartitionTimeIntegrationTest.java
index 40c03e6d891..d76889dc95e 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/ResetPartitionTimeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/ResetPartitionTimeIntegrationTest.java
@@ -33,21 +33,17 @@ import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Consumed;
 import org.apache.kafka.streams.processor.TimestampExtractor;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -63,11 +59,9 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.sa
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class ResetPartitionTimeIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final int NUM_BROKERS = 1;
     private static final Properties BROKER_CONFIG;
     static {
@@ -78,12 +72,12 @@ public class ResetPartitionTimeIntegrationTest {
     public static final EmbeddedKafkaCluster CLUSTER =
         new EmbeddedKafkaCluster(NUM_BROKERS, BROKER_CONFIG, 0L);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -95,24 +89,10 @@ public class ResetPartitionTimeIntegrationTest {
     private static long lastRecordedTimestamp = -2L;
 
     @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return Arrays.asList(new String[][] {
-            {StreamsConfig.AT_LEAST_ONCE},
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String processingGuarantee;
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Test
-    public void shouldPreservePartitionTimeOnKafkaStreamRestart() {
-        final String appId = "app-" + safeUniqueTestName(testName);
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldPreservePartitionTimeOnKafkaStreamRestart(final String processingGuarantee, final TestInfo testInfo) {
+        final String appId = "app-" + safeUniqueTestName(testInfo);
         final String input = "input";
         final String outputRaw = "output-raw";
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/RestoreIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/RestoreIntegrationTest.java
index 1db1d2a981e..a71bf93980a 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/RestoreIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/RestoreIntegrationTest.java
@@ -61,6 +61,7 @@ import org.apache.kafka.streams.state.internals.KeyValueStoreBuilder;
 import org.apache.kafka.streams.state.internals.OffsetCheckpoint;
 import org.apache.kafka.test.StreamsTestUtils;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.CoreMatchers;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -71,7 +72,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -92,7 +93,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import java.util.stream.Stream;
 
 import static java.util.Arrays.asList;
 import static org.apache.kafka.common.utils.Utils.mkEntry;
@@ -177,12 +177,6 @@ public class RestoreIntegrationTest {
         streamsConfigurations.clear();
     }
 
-    private static Stream<Boolean> parameters() {
-        return Stream.of(
-                Boolean.TRUE,
-                Boolean.FALSE);
-    }
-
     @Test
     public void shouldRestoreNullRecord() throws Exception {
         final StreamsBuilder builder = new StreamsBuilder();
@@ -249,7 +243,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldRestoreStateFromSourceTopicForReadOnlyStore(final boolean stateUpdaterEnabled) throws Exception {
         final AtomicInteger numReceived = new AtomicInteger(0);
         final Topology topology = new Topology();
@@ -305,7 +299,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldRestoreStateFromSourceTopicForGlobalTable(final boolean stateUpdaterEnabled) throws Exception {
         final AtomicInteger numReceived = new AtomicInteger(0);
         final StreamsBuilder builder = new StreamsBuilder();
@@ -356,7 +350,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldRestoreStateFromChangelogTopic(final boolean stateUpdaterEnabled) throws Exception {
         final String changelog = appId + "-store-changelog";
         CLUSTER.createTopic(changelog, 2, 1);
@@ -408,7 +402,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldSuccessfullyStartWhenLoggingDisabled(final boolean stateUpdaterEnabled) throws InterruptedException {
         final StreamsBuilder builder = new StreamsBuilder();
 
@@ -434,7 +428,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldProcessDataFromStoresWithLoggingDisabled(final boolean stateUpdaterEnabled) throws InterruptedException {
         IntegrationTestUtils.produceKeyValuesSynchronously(inputStream,
                 asList(KeyValue.pair(1, 1),
@@ -479,7 +473,7 @@ public class RestoreIntegrationTest {
     }
 
     @ParameterizedTest
-    @MethodSource("parameters")
+    @ValueSource(booleans = {true, false})
     public void shouldRecycleStateFromStandbyTaskPromotedToActiveTaskAndNotRestore(final boolean stateUpdaterEnabled) throws Exception {
         final StreamsBuilder builder = new StreamsBuilder();
         builder.table(
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/RocksDBMetricsIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/RocksDBMetricsIntegrationTest.java
index 706b27c4063..17fd60d568f 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/RocksDBMetricsIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/RocksDBMetricsIntegrationTest.java
@@ -36,27 +36,21 @@ import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.TimeWindows;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.WindowStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
@@ -64,27 +58,24 @@ import java.util.stream.Collectors;
 
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
-
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 
-@Category({IntegrationTest.class})
-@RunWith(Parameterized.class)
 @SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class RocksDBMetricsIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final int NUM_BROKERS = 3;
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(NUM_BROKERS);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -95,7 +86,6 @@ public class RocksDBMetricsIntegrationTest {
     private static final String STREAM_OUTPUT_TWO = "STREAM_OUTPUT_TWO";
     private static final String MY_STORE_PERSISTENT_KEY_VALUE = "myStorePersistentKeyValue";
     private static final Duration WINDOW_SIZE = Duration.ofMillis(50);
-    private static final long TIMEOUT = 60000;
 
     // RocksDB metrics
     private static final String METRICS_GROUP = "stream-state-metrics";
@@ -138,29 +128,13 @@ public class RocksDBMetricsIntegrationTest {
     private static final String ESTIMATED_MEMORY_OF_TABLE_READERS = "estimate-table-readers-mem";
     private static final String NUMBER_OF_BACKGROUND_ERRORS = "background-errors";
 
-    @SuppressWarnings("deprecation")
-    @Parameters(name = "{0}")
-    public static Collection<Object[]> data() {
-        return Arrays.asList(new Object[][] {
-            {StreamsConfig.AT_LEAST_ONCE},
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameter
-    public String processingGuarantee;
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Before
+    @BeforeEach
     public void before() throws Exception {
         CLUSTER.createTopic(STREAM_INPUT_ONE, 1, 3);
         CLUSTER.createTopic(STREAM_INPUT_TWO, 1, 3);
     }
 
-    @After
+    @AfterEach
     public void after() throws Exception {
         CLUSTER.deleteTopicsAndWait(STREAM_INPUT_ONE, STREAM_INPUT_TWO, STREAM_OUTPUT_ONE, STREAM_OUTPUT_TWO);
     }
@@ -170,9 +144,10 @@ public class RocksDBMetricsIntegrationTest {
         void verify(final KafkaStreams kafkaStreams, final String metricScope) throws Exception;
     }
 
-    @Test
-    public void shouldExposeRocksDBMetricsBeforeAndAfterFailureWithEmptyStateDir() throws Exception {
-        final Properties streamsConfiguration = streamsConfig();
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldExposeRocksDBMetricsBeforeAndAfterFailureWithEmptyStateDir(final String processingGuarantee, final TestInfo testInfo) throws Exception {
+        final Properties streamsConfiguration = streamsConfig(processingGuarantee, testInfo);
         IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
         final StreamsBuilder builder = builderForStateStores();
 
@@ -191,9 +166,9 @@ public class RocksDBMetricsIntegrationTest {
         );
     }
 
-    private Properties streamsConfig() {
+    private Properties streamsConfig(final String processingGuarantee, final TestInfo testInfo) {
         final Properties streamsConfiguration = new Properties();
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "test-application-" + safeTestName);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
         streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Integer().getClass());
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/SelfJoinUpgradeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/SelfJoinUpgradeIntegrationTest.java
index 21bcb609541..1a583dd15f6 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/SelfJoinUpgradeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/SelfJoinUpgradeIntegrationTest.java
@@ -17,17 +17,6 @@
 
 package org.apache.kafka.streams.integration;
 
-import static java.time.Duration.ofMinutes;
-import static java.util.Arrays.asList;
-import static java.util.Collections.singletonList;
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-
-import java.io.IOException;
-import java.time.Duration;
-import java.util.List;
-import java.util.Properties;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.serialization.StringDeserializer;
@@ -44,18 +33,29 @@ import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.kstream.ValueJoiner;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-
-@Category({IntegrationTest.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.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.List;
+import java.util.Properties;
+
+import static java.time.Duration.ofMinutes;
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+@Tag("integration")
 public class SelfJoinUpgradeIntegrationTest {
     public static final String INPUT_TOPIC = "selfjoin-input";
     public static final String OUTPUT_TOPIC = "selfjoin-output";
@@ -66,24 +66,21 @@ public class SelfJoinUpgradeIntegrationTest {
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
     private String safeTestName;
 
-    @Before
-    public void createTopics() throws Exception {
-        safeTestName = safeUniqueTestName(testName);
+    @BeforeEach
+    public void createTopics(final TestInfo testInfo) throws Exception {
+        safeTestName = safeUniqueTestName(testInfo);
         inputTopic = INPUT_TOPIC + safeTestName;
         outputTopic = OUTPUT_TOPIC + safeTestName;
         CLUSTER.createTopic(inputTopic);
@@ -105,7 +102,7 @@ public class SelfJoinUpgradeIntegrationTest {
         return streamsConfiguration;
     }
 
-    @After
+    @AfterEach
     public void shutdown() {
         if (kafkaStreams != null) {
             kafkaStreams.close(Duration.ofSeconds(30L));
@@ -128,7 +125,6 @@ public class SelfJoinUpgradeIntegrationTest {
         );
         joinedOld.to(outputTopic, Produced.with(Serdes.String(), Serdes.String()));
 
-        final String safeTestName = safeUniqueTestName(testName);
         final Properties props = props();
         props.put(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, StreamsConfig.NO_OPTIMIZATION);
         kafkaStreams = new KafkaStreams(streamsBuilderOld.build(), props);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/SlidingWindowedKStreamIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/SlidingWindowedKStreamIntegrationTest.java
index 6dcbd80384a..53568a45999 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/SlidingWindowedKStreamIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/SlidingWindowedKStreamIntegrationTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Optional;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.Deserializer;
 import org.apache.kafka.common.serialization.Serde;
@@ -27,14 +24,13 @@ import org.apache.kafka.common.serialization.Serdes.StringSerde;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.StreamsConfig.InternalConfig;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Consumed;
-import org.apache.kafka.streams.kstream.EmitStrategy;
 import org.apache.kafka.streams.kstream.EmitStrategy.StrategyType;
 import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
@@ -46,29 +42,27 @@ import org.apache.kafka.streams.kstream.TimeWindowedDeserializer;
 import org.apache.kafka.streams.kstream.Windowed;
 import org.apache.kafka.streams.kstream.WindowedSerdes;
 import org.apache.kafka.streams.kstream.internals.TimeWindow;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.MockAggregator;
 import org.apache.kafka.test.MockInitializer;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
 
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
-
 import static java.time.Duration.ofMillis;
 import static java.util.Arrays.asList;
 import static org.apache.kafka.common.utils.Utils.mkEntry;
@@ -79,11 +73,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 
 @SuppressWarnings({"unchecked"})
-@Category({IntegrationTest.class})
-@RunWith(Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class SlidingWindowedKStreamIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final int NUM_BROKERS = 1;
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(NUM_BROKERS,
@@ -92,12 +84,12 @@ public class SlidingWindowedKStreamIntegrationTest {
         )
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -108,35 +100,12 @@ public class SlidingWindowedKStreamIntegrationTest {
     private String streamOneInput;
     private String streamTwoInput;
     private String outputTopic;
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Parameter
-    public StrategyType type;
-
-    @Parameter(1)
-    public boolean withCache;
-
-    private EmitStrategy emitStrategy;
-    private boolean emitFinal;
-
     private String safeTestName;
 
-    @Parameterized.Parameters(name = "{0}_cache:{1}")
-    public static Collection<Object[]> getEmitStrategy() {
-        return asList(new Object[][] {
-            {StrategyType.ON_WINDOW_UPDATE, true},
-            {StrategyType.ON_WINDOW_UPDATE, false},
-            {StrategyType.ON_WINDOW_CLOSE, true},
-            {StrategyType.ON_WINDOW_CLOSE, false}
-        });
-    }
-
-    @Before
-    public void before() throws InterruptedException {
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws InterruptedException {
         builder = new StreamsBuilder();
-        safeTestName = safeUniqueTestName(testName);
+        safeTestName = safeUniqueTestName(testInfo);
         createTopics();
         streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "app-" + safeTestName);
@@ -149,12 +118,9 @@ public class SlidingWindowedKStreamIntegrationTest {
         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfiguration.put(InternalConfig.EMIT_INTERVAL_MS_KSTREAMS_WINDOWED_AGGREGATION, 0); // Always process
         streamsConfiguration.put(StreamsConfig.WINDOW_STORE_CHANGE_LOG_ADDITIONAL_RETENTION_MS_CONFIG, Long.MAX_VALUE); // Don't expire changelog
-
-        emitStrategy = StrategyType.forType(type);
-        emitFinal = type.equals(StrategyType.ON_WINDOW_CLOSE);
     }
 
-    @After
+    @AfterEach
     public void whenShuttingDown() throws IOException {
         if (kafkaStreams != null) {
             kafkaStreams.close();
@@ -163,8 +129,9 @@ public class SlidingWindowedKStreamIntegrationTest {
         IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
     }
 
-    @Test
-    public void shouldAggregateWindowedWithNoGrace() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldAggregateWindowedWithNoGrace(final StrategyType strategyType, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "1", 0),  // Create [0, 10](0+1)
@@ -181,17 +148,18 @@ public class SlidingWindowedKStreamIntegrationTest {
         builder.stream(streamOneInput, Consumed.with(Serdes.String(), Serdes.String()))
             .groupByKey()
             .windowedBy(SlidingWindows.ofTimeDifferenceWithNoGrace(ofMillis(10L)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(strategyType))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
 
         startStreams();
 
+        final boolean emitFinal = strategyType.equals(StrategyType.ON_WINDOW_CLOSE);
         final List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
             new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
             new StringDeserializer(),
@@ -227,8 +195,9 @@ public class SlidingWindowedKStreamIntegrationTest {
         assertThat(windowedMessages, is(expectResult));
     }
 
-    @Test
-    public void shouldAggregateWindowedWithGrace() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldAggregateWindowedWithGrace(final StrategyType strategyType, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "1", 0),  // Create [0, 10](0+1)
@@ -245,17 +214,18 @@ public class SlidingWindowedKStreamIntegrationTest {
         builder.stream(streamOneInput, Consumed.with(Serdes.String(), Serdes.String()))
             .groupByKey()
             .windowedBy(SlidingWindows.ofTimeDifferenceAndGrace(ofMillis(10L), ofMillis(5)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(strategyType))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
 
         startStreams();
 
+        final boolean emitFinal = strategyType.equals(StrategyType.ON_WINDOW_CLOSE);
         final List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
             new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
             new StringDeserializer(),
@@ -300,8 +270,9 @@ public class SlidingWindowedKStreamIntegrationTest {
         assertThat(windowedMessages, is(expectResult));
     }
 
-    @Test
-    public void shouldRestoreAfterJoinRestart() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldRestoreAfterJoinRestart(final StrategyType strategyType, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "L1", 0),
@@ -333,17 +304,18 @@ public class SlidingWindowedKStreamIntegrationTest {
 
         joinedStream.groupByKey()
             .windowedBy(SlidingWindows.ofTimeDifferenceWithNoGrace(ofMillis(10L)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(strategyType))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
 
         startStreams();
 
+        final boolean emitFinal = strategyType.equals(StrategyType.ON_WINDOW_CLOSE);
         List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
             new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
             new StringDeserializer(),
@@ -439,7 +411,7 @@ public class SlidingWindowedKStreamIntegrationTest {
         );
     }
 
-    private Materialized getMaterialized() {
+    private Materialized getMaterialized(final boolean withCache) {
         if (withCache) {
             return Materialized.with(null, new StringSerde()).withCachingEnabled();
         }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/SmokeTestDriverIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/SmokeTestDriverIntegrationTest.java
index 0ed52cfbb8e..eb35666675e 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/SmokeTestDriverIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/SmokeTestDriverIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.stream.Stream;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.utils.Exit;
 import org.apache.kafka.streams.StreamsConfig;
@@ -25,13 +24,13 @@ import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.tests.SmokeTestClient;
 import org.apache.kafka.streams.tests.SmokeTestDriver;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.CsvSource;
 
 import java.io.IOException;
 import java.time.Duration;
@@ -95,20 +94,12 @@ public class SmokeTestDriverIntegrationTest {
 
     }
 
-    private static Stream<Arguments> parameters() {
-        return Stream.of(
-            Arguments.of(false, false),
-            Arguments.of(true, false),
-            Arguments.of(true, true)
-        );
-    }
-
     // In this test, we try to keep creating new stream, and closing the old one, to maintain only 3 streams alive.
     // During the new stream added and old stream left, the stream process should still complete without issue.
     // We set 2 timeout condition to fail the test before passing the verification:
     // (1) 10 min timeout, (2) 30 tries of polling without getting any data
     @ParameterizedTest
-    @MethodSource("parameters")
+    @CsvSource({"false, false", "true, false", "true, true"})
     public void shouldWorkWithRebalance(final boolean stateUpdaterEnabled, final boolean processingThreadsEnabled) throws InterruptedException {
         Exit.setExitProcedure((statusCode, message) -> {
             throw new AssertionError("Test called exit(). code:" + statusCode + " message:" + message);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskCreationIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskCreationIntegrationTest.java
index 2ecb24b94cd..d2002f1a76e 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskCreationIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskCreationIntegrationTest.java
@@ -33,14 +33,15 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.StoreBuilder;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.test.TestUtils;
+
 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.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.Tag;
 
 import java.io.IOException;
 import java.util.Properties;
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSIntegrationTest.java
index 33f33a192a6..77939602193 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSIntegrationTest.java
@@ -38,24 +38,21 @@ import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.internals.OffsetCheckpoint;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.File;
 import java.io.IOException;
 import java.time.Duration;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Properties;
 import java.util.concurrent.CountDownLatch;
@@ -66,33 +63,20 @@ import static java.util.Arrays.asList;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.startApplicationAndWaitUntilRunning;
 import static org.apache.kafka.test.TestUtils.waitForCondition;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
  * An integration test to verify the conversion of a dirty-closed EOS
  * task towards a standby task is safe across restarts of the application.
  */
-@RunWith(Parameterized.class)
-@Category(IntegrationTest.class)
+@SuppressWarnings("deprecation")
+@Tag("integration")
+@Timeout(600)
 public class StandbyTaskEOSIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final long REBALANCE_TIMEOUT = Duration.ofMinutes(2L).toMillis();
     private static final int KEY_0 = 0;
     private static final int KEY_1 = 1;
 
-    @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return asList(new String[][] {
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String eosConfig;
-
     private final AtomicBoolean skipRecord = new AtomicBoolean(false);
 
     private String appId;
@@ -106,22 +90,19 @@ public class StandbyTaskEOSIntegrationTest {
 
     private static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(3);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
-    @Before
-    public void createTopics() throws Exception {
-        final String safeTestName = safeUniqueTestName(testName);
+    @BeforeEach
+    public void createTopics(final TestInfo testInfo) throws Exception {
+        final String safeTestName = safeUniqueTestName(testInfo);
         appId = "app-" + safeTestName;
         inputTopic = "input-" + safeTestName;
         outputTopic = "output-" + safeTestName;
@@ -131,7 +112,7 @@ public class StandbyTaskEOSIntegrationTest {
         CLUSTER.createTopic(outputTopic, 1, 3);
     }
 
-    @After
+    @AfterEach
     public void cleanUp() {
         if (streamInstanceOne != null) {
             streamInstanceOne.close();
@@ -144,8 +125,9 @@ public class StandbyTaskEOSIntegrationTest {
         }
     }
 
-    @Test
-    public void shouldSurviveWithOneTaskAsStandby() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldSurviveWithOneTaskAsStandby(final String eosConfig) throws Exception {
         IntegrationTestUtils.produceKeyValuesSynchronouslyWithTimestamp(
             inputTopic,
             Collections.singletonList(
@@ -164,8 +146,8 @@ public class StandbyTaskEOSIntegrationTest {
 
         final CountDownLatch instanceLatch = new CountDownLatch(1);
 
-        streamInstanceOne = buildStreamWithDirtyStateDir(stateDirPath + "/" + appId + "-1/", instanceLatch);
-        streamInstanceTwo = buildStreamWithDirtyStateDir(stateDirPath + "/" + appId + "-2/", instanceLatch);
+        streamInstanceOne = buildStreamWithDirtyStateDir(stateDirPath + "/" + appId + "-1/", instanceLatch, eosConfig);
+        streamInstanceTwo = buildStreamWithDirtyStateDir(stateDirPath + "/" + appId + "-2/", instanceLatch, eosConfig);
 
         startApplicationAndWaitUntilRunning(asList(streamInstanceOne, streamInstanceTwo), Duration.ofSeconds(60));
 
@@ -180,12 +162,13 @@ public class StandbyTaskEOSIntegrationTest {
     }
 
     private KafkaStreams buildStreamWithDirtyStateDir(final String stateDirPath,
-                                                      final CountDownLatch recordProcessLatch) throws Exception {
+                                                      final CountDownLatch recordProcessLatch,
+                                                      final String eosConfig) throws Exception {
 
         final StreamsBuilder builder = new StreamsBuilder();
         final TaskId taskId = new TaskId(0, 0);
 
-        final Properties props = props(stateDirPath);
+        final Properties props = props(stateDirPath, eosConfig);
 
         final StateDirectory stateDirectory = new StateDirectory(
             new StreamsConfig(props), new MockTime(), true, false);
@@ -206,8 +189,9 @@ public class StandbyTaskEOSIntegrationTest {
         return new KafkaStreams(builder.build(), props);
     }
 
-    @Test
-    public void shouldWipeOutStandbyStateDirectoryIfCheckpointIsMissing() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldWipeOutStandbyStateDirectoryIfCheckpointIsMissing(final String eosConfig) throws Exception {
         final long time = System.currentTimeMillis();
         final String base = TestUtils.tempDirectory(appId).getPath();
 
@@ -225,8 +209,8 @@ public class StandbyTaskEOSIntegrationTest {
             10L + time
         );
 
-        streamInstanceOne = buildWithDeduplicationTopology(base + "-1");
-        streamInstanceTwo = buildWithDeduplicationTopology(base + "-2");
+        streamInstanceOne = buildWithDeduplicationTopology(base + "-1", eosConfig);
+        streamInstanceTwo = buildWithDeduplicationTopology(base + "-2", eosConfig);
 
         // start first instance and wait for processing
         startApplicationAndWaitUntilRunning(streamInstanceOne);
@@ -293,7 +277,7 @@ public class StandbyTaskEOSIntegrationTest {
             2
         );
 
-        streamInstanceOneRecovery = buildWithDeduplicationTopology(base + "-1");
+        streamInstanceOneRecovery = buildWithDeduplicationTopology(base + "-1", eosConfig);
 
         // "restart" first client and wait for standby recovery
         // (could actually also be active, but it does not matter as long as we enable "state stores"
@@ -342,7 +326,7 @@ public class StandbyTaskEOSIntegrationTest {
     }
 
     @SuppressWarnings("deprecation")
-    private KafkaStreams buildWithDeduplicationTopology(final String stateDirPath) {
+    private KafkaStreams buildWithDeduplicationTopology(final String stateDirPath, final String eosConfig) {
         final StreamsBuilder builder = new StreamsBuilder();
 
         builder.addStateStore(Stores.keyValueStoreBuilder(
@@ -392,11 +376,11 @@ public class StandbyTaskEOSIntegrationTest {
             )
             .to(outputTopic);
 
-        return new KafkaStreams(builder.build(), props(stateDirPath));
+        return new KafkaStreams(builder.build(), props(stateDirPath, eosConfig));
     }
 
 
-    private Properties props(final String stateDirPath) {
+    private Properties props(final String stateDirPath, final String eosConfig) {
         final Properties streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, appId);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSMultiRebalanceIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSMultiRebalanceIntegrationTest.java
index e8d8d009865..66f5b5f0209 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSMultiRebalanceIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StandbyTaskEOSMultiRebalanceIntegrationTest.java
@@ -28,21 +28,21 @@ import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
-import org.apache.kafka.streams.processor.api.ProcessorContext;
 import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorContext;
 import org.apache.kafka.streams.processor.api.Record;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.QueryableStoreTypes;
 import org.apache.kafka.streams.state.Stores;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.Matchers;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,7 +60,7 @@ import static org.apache.kafka.test.TestUtils.waitForCondition;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
 public class StandbyTaskEOSMultiRebalanceIntegrationTest {
 
     private static final Logger LOG = LoggerFactory.getLogger(StandbyTaskEOSMultiRebalanceIntegrationTest.class);
@@ -80,17 +80,17 @@ public class StandbyTaskEOSMultiRebalanceIntegrationTest {
 
     private static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(3);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Before
+    @BeforeEach
     public void createTopics() throws Exception {
         final String safeTestName = UUID.randomUUID().toString();
         appId = "app-" + safeTestName;
@@ -106,7 +106,7 @@ public class StandbyTaskEOSMultiRebalanceIntegrationTest {
 
     private final int partitionCount = 12;
 
-    @After
+    @AfterEach
     public void cleanUp() {
         if (streamInstanceOne != null) {
             streamInstanceOne.close();
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StateDirectoryIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StateDirectoryIntegrationTest.java
index 69466197bca..df4359228c6 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StateDirectoryIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StateDirectoryIntegrationTest.java
@@ -16,14 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Properties;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
 import org.apache.kafka.clients.producer.KafkaProducer;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.clients.producer.ProducerRecord;
@@ -38,47 +30,48 @@ import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
 
+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.junit.jupiter.api.Timeout;
 
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Properties;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import static org.apache.kafka.common.utils.Utils.mkEntry;
 import static org.apache.kafka.common.utils.Utils.mkMap;
 import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class StateDirectoryIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(3);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
     @Test
-    public void testCleanUpStateDirIfEmpty() throws InterruptedException {
-        final String uniqueTestName = safeUniqueTestName(testName);
+    public void testCleanUpStateDirIfEmpty(final TestInfo testInfo) throws InterruptedException {
+        final String uniqueTestName = safeUniqueTestName(testInfo);
 
         // Create Topic
         final String input = uniqueTestName + "-input";
@@ -183,8 +176,8 @@ public class StateDirectoryIntegrationTest {
     }
 
     @Test
-    public void testNotCleanUpStateDirIfNotEmpty() throws InterruptedException {
-        final String uniqueTestName = safeUniqueTestName(testName);
+    public void testNotCleanUpStateDirIfNotEmpty(final TestInfo testInfo) throws InterruptedException {
+        final String uniqueTestName = safeUniqueTestName(testInfo);
 
         // Create Topic
         final String input = uniqueTestName + "-input";
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StoreQueryIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StoreQueryIntegrationTest.java
index 006a32cca41..bc49aa722a2 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StoreQueryIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StoreQueryIntegrationTest.java
@@ -43,15 +43,16 @@ import org.apache.kafka.streams.state.QueryableStoreType;
 import org.apache.kafka.streams.state.ReadOnlyKeyValueStore;
 import org.apache.kafka.test.TestCondition;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.Matcher;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
 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.Timeout;
 import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,15 +60,15 @@ import java.io.IOException;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 import java.util.Properties;
+import java.util.Set;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
-import java.util.Set;
-import java.util.Collections;
 
 import static java.util.Collections.singletonList;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.getStore;
@@ -76,15 +77,15 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.st
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForApplicationState;
 import static org.apache.kafka.streams.state.QueryableStoreTypes.keyValueStore;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.anyOf;
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
-import static org.hamcrest.Matchers.anyOf;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
 
 @Timeout(600)
 @Tag("integration")
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StoreQuerySuite.java b/streams/src/test/java/org/apache/kafka/streams/integration/StoreQuerySuite.java
index 31b8554612b..56660187850 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StoreQuerySuite.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StoreQuerySuite.java
@@ -22,6 +22,7 @@ import org.apache.kafka.streams.state.internals.CompositeReadOnlyWindowStoreTest
 import org.apache.kafka.streams.state.internals.GlobalStateStoreProviderTest;
 import org.apache.kafka.streams.state.internals.StreamThreadStateStoreProviderTest;
 import org.apache.kafka.streams.state.internals.WrappingStoreProviderTest;
+
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StoreUpgradeIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StoreUpgradeIntegrationTest.java
index 5db747b1b46..557650a6838 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StoreUpgradeIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StoreUpgradeIntegrationTest.java
@@ -20,9 +20,9 @@ import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.IntegerSerializer;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.KeyValue;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Windowed;
@@ -40,16 +40,15 @@ import org.apache.kafka.streams.state.TimestampedKeyValueStore;
 import org.apache.kafka.streams.state.TimestampedWindowStore;
 import org.apache.kafka.streams.state.ValueAndTimestamp;
 import org.apache.kafka.streams.state.WindowStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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 java.io.IOException;
 import java.time.Duration;
@@ -61,7 +60,7 @@ import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 
-@Category({IntegrationTest.class})
+@Tag("integration")
 public class StoreUpgradeIntegrationTest {
     private static final String STORE_NAME = "store";
     private String inputStream;
@@ -70,28 +69,27 @@ public class StoreUpgradeIntegrationTest {
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
+    public String safeTestName;
 
-    @Before
-    public void createTopics() throws Exception {
-        inputStream = "input-stream-" + safeUniqueTestName(testName);
+    @BeforeEach
+    public void createTopics(final TestInfo testInfo) throws Exception {
+        safeTestName = safeUniqueTestName(testInfo);
+        inputStream = "input-stream-" + safeTestName;
         CLUSTER.createTopic(inputStream);
     }
 
     private Properties props() {
         final Properties streamsConfiguration = new Properties();
-        final String safeTestName = safeUniqueTestName(testName);
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "app-" + safeTestName);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
         streamsConfiguration.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
@@ -103,7 +101,7 @@ public class StoreUpgradeIntegrationTest {
         return streamsConfiguration;
     }
 
-    @After
+    @AfterEach
     public void shutdown() {
         if (kafkaStreams != null) {
             kafkaStreams.close(Duration.ofSeconds(30L));
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamStreamJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamStreamJoinIntegrationTest.java
index b1d2390dc83..ebbdb328d84 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamStreamJoinIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamStreamJoinIntegrationTest.java
@@ -21,20 +21,17 @@ import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.test.TestRecord;
-import org.apache.kafka.test.IntegrationTest;
-import org.apache.kafka.test.MockMapper;
 
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.apache.kafka.test.MockMapper;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 import static java.time.Duration.ofHours;
 import static java.time.Duration.ofSeconds;
@@ -42,33 +39,19 @@ import static java.time.Duration.ofSeconds;
 /**
  * Tests all available joins of Kafka Streams DSL.
  */
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-    private KStream<Long, String> leftStream;
-    private KStream<Long, String> rightStream;
-
-    public StreamStreamJoinIntegrationTest(final boolean cacheEnabled) {
-        super(cacheEnabled);
-    }
-
-    @Before
-    public void prepareTopology() throws InterruptedException {
-        super.prepareEnvironment();
-
-        appID = "stream-stream-join-integration-test";
-
-        builder = new StreamsBuilder();
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightStream = builder.stream(INPUT_TOPIC_RIGHT);
-    }
+    private static final String APP_ID = "stream-stream-join-integration-test";
 
-    @Test
-    public void testSelfJoin() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-selfJoin");
-        STREAMS_CONFIG.put(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, StreamsConfig.OPTIMIZE);
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testSelfJoin(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-selfJoin");
+        streamsConfig.put(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, StreamsConfig.OPTIMIZE);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -101,12 +84,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
             JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
         ).to(OUTPUT_TOPIC);
 
-        runSelfJoinTestWithDriver(expectedResult);
+        runSelfJoinTestWithDriver(expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testInner() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -148,12 +136,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
             JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
         ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testInnerRepartitioned() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-repartitioned");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerRepartitioned(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-repartitioned");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -197,12 +190,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
                 JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
             ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeft() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -245,12 +243,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
             JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
         ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeftRepartitioned() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left-repartitioned");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftRepartitioned(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left-repartitioned");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -295,12 +298,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
                 JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
             ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testOuter() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuter(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -344,12 +352,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
             JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
         ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testOuterRepartitioned() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterRepartitioned(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -395,12 +408,17 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
                 JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
             ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testMultiInner() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-multi-inner");
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testMultiInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KStream<Long, String> rightStream = builder.stream(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-multi-inner");
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -494,6 +512,6 @@ public class StreamStreamJoinIntegrationTest extends AbstractJoinIntegrationTest
             JoinWindows.ofTimeDifferenceAndGrace(ofSeconds(10), ofHours(24))
         ).to(OUTPUT_TOPIC);
 
-        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult);
+        runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinIntegrationTest.java
index e4e46ec69a2..18ce26abe08 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.time.Duration;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.kstream.KStream;
@@ -24,52 +23,35 @@ import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.test.TestRecord;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 /**
  * Tests all available joins of Kafka Streams DSL.
  */
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class StreamTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
-
     private static final String STORE_NAME = "table-store";
-
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-    private KStream<Long, String> leftStream;
-    private KTable<Long, String> rightTable;
-
-    public StreamTableJoinIntegrationTest(final boolean cacheEnabled) {
-        super(cacheEnabled);
-    }
-
-    @Before
-    public void prepareTopology() throws InterruptedException {
-        super.prepareEnvironment();
-
-        appID = "stream-table-join-integration-test";
-
-        builder = new StreamsBuilder();
-    }
-
-    @Test
-    public void testInner() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT);
+    private static final String APP_ID = "stream-table-join-integration-test";
+
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftStream.join(rightTable, valueJoiner).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
@@ -98,15 +80,17 @@ public class StreamTableJoinIntegrationTest extends AbstractJoinIntegrationTest
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeft() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT);
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT);
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftStream.leftJoin(rightTable, valueJoiner).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
@@ -135,16 +119,18 @@ public class StreamTableJoinIntegrationTest extends AbstractJoinIntegrationTest
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testInnerWithVersionedStore() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
-            Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerWithVersionedStore(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
+                Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftStream.join(rightTable, valueJoiner).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
@@ -173,16 +159,18 @@ public class StreamTableJoinIntegrationTest extends AbstractJoinIntegrationTest
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeftWithVersionedStore() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
-            Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftWithVersionedStore(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
+                Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftStream.leftJoin(rightTable, valueJoiner).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
@@ -211,6 +199,6 @@ public class StreamTableJoinIntegrationTest extends AbstractJoinIntegrationTest
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinTopologyOptimizationIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinTopologyOptimizationIntegrationTest.java
index 073e80a7287..2b630b65ee4 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinTopologyOptimizationIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinTopologyOptimizationIntegrationTest.java
@@ -36,23 +36,20 @@ import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.kstream.Named;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-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.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.io.IOException;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Properties;
@@ -61,25 +58,23 @@ import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-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;
 
-@RunWith(value = Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class StreamTableJoinTopologyOptimizationIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
     private static final int NUM_BROKERS = 1;
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(NUM_BROKERS);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -91,26 +86,13 @@ public class StreamTableJoinTopologyOptimizationIntegrationTest {
     private KafkaStreams kafkaStreams;
 
     private Properties streamsConfiguration;
+    private TestInfo testInfo;
 
-    @Rule
-    public TestName testName = new TestName();
-
-    @Parameterized.Parameter
-    public String topologyOptimization;
-
-    @Parameterized.Parameters(name = "Optimization = {0}")
-    public static Collection<?> topologyOptimization() {
-        return Arrays.asList(new String[][]{
-            {StreamsConfig.OPTIMIZE},
-            {StreamsConfig.NO_OPTIMIZATION}
-        });
-    }
-
-    @Before
-    public void before() throws InterruptedException {
-        streamsConfiguration = new Properties();
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws InterruptedException {
+        this.testInfo = testInfo;
 
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
 
         tableTopic = "table-topic" + safeTestName;
         inputTopic = "stream-topic-" + safeTestName;
@@ -120,7 +102,18 @@ public class StreamTableJoinTopologyOptimizationIntegrationTest {
         CLUSTER.createTopic(inputTopic, 4, 1);
         CLUSTER.createTopic(tableTopic, 2, 1);
         CLUSTER.createTopic(outputTopic, 4, 1);
+    }
 
+    @AfterEach
+    public void whenShuttingDown() throws IOException {
+        if (kafkaStreams != null) {
+            kafkaStreams.close();
+        }
+        IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
+    }
+
+    private Properties getStreamsConfiguration(final String topologyOptimization) {
+        final Properties streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, applicationId);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
         streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath());
@@ -129,18 +122,13 @@ public class StreamTableJoinTopologyOptimizationIntegrationTest {
         streamsConfiguration.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.Integer().getClass());
         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfiguration.put(StreamsConfig.TOPOLOGY_OPTIMIZATION_CONFIG, topologyOptimization);
+        return streamsConfiguration;
     }
 
-    @After
-    public void whenShuttingDown() throws IOException {
-        if (kafkaStreams != null) {
-            kafkaStreams.close();
-        }
-        IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
-    }
-
-    @Test
-    public void shouldDoStreamTableJoinWithDifferentNumberOfPartitions() throws Exception {
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.OPTIMIZE, StreamsConfig.NO_OPTIMIZATION})
+    public void shouldDoStreamTableJoinWithDifferentNumberOfPartitions(final String topologyOptimization) throws Exception {
+        this.streamsConfiguration = getStreamsConfiguration(topologyOptimization);
         final String storeName = "store";
         final String selectKeyName = "selectKey";
 
@@ -241,7 +229,7 @@ public class StreamTableJoinTopologyOptimizationIntegrationTest {
                                                  final Deserializer<V> valueSerializer,
                                                  final List<KeyValue<K, V>> expectedRecords) throws Exception {
 
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
         final Properties consumerProperties = new Properties();
         consumerProperties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
         consumerProperties.setProperty(ConsumerConfig.GROUP_ID_CONFIG, "group-" + safeTestName);
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinWithGraceIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinWithGraceIntegrationTest.java
index cf859e46ba4..bcfd2445de2 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinWithGraceIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamTableJoinWithGraceIntegrationTest.java
@@ -25,55 +25,40 @@ import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.test.TestRecord;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 /**
  * Tests all available joins of Kafka Streams DSL.
  */
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class StreamTableJoinWithGraceIntegrationTest extends AbstractJoinIntegrationTest {
-
     private static final String STORE_NAME = "table-store";
+    private static final String APP_ID = "stream-table-join-integration-test";
+    private static final Joined<Long, String, String> JOINED =
+            Joined.with(Serdes.Long(), Serdes.String(), Serdes.String(), "Grace", Duration.ofMillis(2));
 
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-    private KStream<Long, String> leftStream;
-    private KTable<Long, String> rightTable;
-    private Joined<Long, String, String> joined;
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerWithVersionedStore(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
+                Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
 
-    public StreamTableJoinWithGraceIntegrationTest(final boolean cacheEnabled) {
-        super(cacheEnabled);
-    }
-
-    @Before
-    public void prepareTopology() throws InterruptedException {
-        super.prepareEnvironment();
-        appID = "stream-table-join-integration-test";
-        builder = new StreamsBuilder();
-        joined = Joined.with(Serdes.Long(), Serdes.String(), Serdes.String(), "Grace", Duration.ofMillis(2));
-    }
-    
-    @Test
-    public void testInnerWithVersionedStore() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
-            Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
-        leftStream.join(rightTable, valueJoiner, joined).to(OUTPUT_TOPIC);
+        leftStream.join(rightTable, valueJoiner, JOINED).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -101,17 +86,19 @@ public class StreamTableJoinWithGraceIntegrationTest extends AbstractJoinIntegra
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeftWithVersionedStore() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftStream = builder.stream(INPUT_TOPIC_LEFT);
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
-            Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
-        leftStream.leftJoin(rightTable, valueJoiner, joined).to(OUTPUT_TOPIC);
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftWithVersionedStore(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KStream<Long, String> leftStream = builder.stream(INPUT_TOPIC_LEFT);
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.as(
+                Stores.persistentVersionedKeyValueStore(STORE_NAME, Duration.ofMinutes(5))));
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
+        leftStream.leftJoin(rightTable, valueJoiner, JOINED).to(OUTPUT_TOPIC);
 
         final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
             null,
@@ -139,6 +126,6 @@ public class StreamTableJoinWithGraceIntegrationTest extends AbstractJoinIntegra
             null
         );
 
-        runTestWithDriver(input, expectedResult);
+        runTestWithDriver(input, expectedResult, streamsConfig, builder.build(streamsConfig));
     }
 }
\ No newline at end of file
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUncaughtExceptionHandlerIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUncaughtExceptionHandlerIntegrationTest.java
index 63bb1a15b07..005efe92d10 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUncaughtExceptionHandlerIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUncaughtExceptionHandlerIntegrationTest.java
@@ -38,17 +38,16 @@ import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.kstream.Named;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.state.internals.KeyValueStoreBuilder;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+
+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.junit.jupiter.api.Timeout;
 
 import java.io.IOException;
 import java.time.Duration;
@@ -59,6 +58,7 @@ import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import static java.util.Arrays.asList;
 import static org.apache.kafka.common.utils.Utils.mkEntry;
 import static org.apache.kafka.common.utils.Utils.mkMap;
 import static org.apache.kafka.common.utils.Utils.mkObjectProperties;
@@ -71,43 +71,37 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.st
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.waitForApplicationState;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
-import static java.util.Arrays.asList;
+import static org.junit.jupiter.api.Assertions.fail;
 
-@Category(IntegrationTest.class)
 @SuppressWarnings("deprecation") //Need to call the old handler, will remove those calls when the old handler is removed
+@Tag("integration")
+@Timeout(600)
 public class StreamsUncaughtExceptionHandlerIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1, new Properties(), Collections.emptyList(), 0L, 0L);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
     public static final Duration DEFAULT_DURATION = Duration.ofSeconds(30);
 
-    @Rule
-    public final TestName testName = new TestName();
-
-    private final String testId = safeUniqueTestName(testName);
-    private final String appId = "appId_" + testId;
-    private final String inputTopic = "input" + testId;
-    private final String inputTopic2 = "input2" + testId;
-    private final String outputTopic = "output" + testId;
-    private final String outputTopic2 = "output2" + testId;
+    private String appId;
+    private String inputTopic;
+    private String inputTopic2;
+    private String outputTopic;
+    private String outputTopic2;
     private final StreamsBuilder builder = new StreamsBuilder();
     private final List<String> processorValueCollector = new ArrayList<>();
     private static AtomicBoolean throwError = new AtomicBoolean(true);
 
-    private final Properties properties = basicProps();
+    private Properties properties;
 
     private Properties basicProps() {
         return mkObjectProperties(
@@ -123,14 +117,21 @@ public class StreamsUncaughtExceptionHandlerIntegrationTest {
         );
     }
 
-    @Before
-    public void setup() {
+    @BeforeEach
+    public void setup(final TestInfo testInfo) {
+        final String testId = safeUniqueTestName(testInfo);
+        appId = "appId_" + testId;
+        inputTopic = "input" + testId;
+        inputTopic2 = "input2" + testId;
+        outputTopic = "output" + testId;
+        outputTopic2 = "output2" + testId;
         IntegrationTestUtils.cleanStateBeforeTest(CLUSTER, inputTopic, inputTopic2, outputTopic, outputTopic2);
         final KStream<String, String> stream = builder.stream(inputTopic);
         stream.process(() -> new ShutdownProcessor(processorValueCollector), Named.as("process"));
+        properties = basicProps();
     }
 
-    @After
+    @AfterEach
     public void teardown() throws IOException {
         purgeLocalStreamsState(properties);
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUpgradeTestIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUpgradeTestIntegrationTest.java
index 6a9453e9926..00a0ef27936 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUpgradeTestIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/StreamsUpgradeTestIntegrationTest.java
@@ -21,13 +21,12 @@ import org.apache.kafka.streams.StreamsConfig;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.tests.StreamsUpgradeTest;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
+
+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.Timeout;
 
 import java.io.IOException;
 import java.time.Duration;
@@ -39,25 +38,23 @@ import static org.apache.kafka.common.utils.Utils.mkEntry;
 import static org.apache.kafka.common.utils.Utils.mkMap;
 import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.apache.kafka.streams.processor.internals.assignment.StreamsAssignmentProtocolVersions.LATEST_SUPPORTED_VERSION;
-
 import static org.apache.kafka.test.TestUtils.retryOnExceptionWithTimeout;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class StreamsUpgradeTestIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(3);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
         IntegrationTestUtils.cleanStateBeforeTest(CLUSTER, 1, "data");
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionDurabilityIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionDurabilityIntegrationTest.java
index d0e90e6882a..497b98ae354 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionDurabilityIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionDurabilityIntegrationTest.java
@@ -42,23 +42,19 @@ import org.apache.kafka.streams.kstream.Transformer;
 import org.apache.kafka.streams.kstream.TransformerSupplier;
 import org.apache.kafka.streams.processor.ProcessorContext;
 import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -83,11 +79,9 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 
-@RunWith(Parameterized.class)
-@Category({IntegrationTest.class})
+@Tag("integration")
+@Timeout(600)
 public class SuppressionDurabilityIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(
         3,
@@ -95,18 +89,17 @@ public class SuppressionDurabilityIntegrationTest {
         0L
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
+    public TestInfo testInfo;
 
     private static final StringDeserializer STRING_DESERIALIZER = new StringDeserializer();
     private static final StringSerializer STRING_SERIALIZER = new StringSerializer();
@@ -115,22 +108,10 @@ public class SuppressionDurabilityIntegrationTest {
     private static final long COMMIT_INTERVAL = 100L;
 
     @SuppressWarnings("deprecation")
-    @Parameterized.Parameters(name = "{0}")
-    public static Collection<String[]> data() {
-        return Arrays.asList(new String[][] {
-            {StreamsConfig.AT_LEAST_ONCE},
-            {StreamsConfig.EXACTLY_ONCE},
-            {StreamsConfig.EXACTLY_ONCE_V2}
-        });
-    }
-
-    @Parameterized.Parameter
-    public String processingGuaranteee;
-
-    @Test
-    @SuppressWarnings("deprecation")
-    public void shouldRecoverBufferAfterShutdown() {
-        final String testId = safeUniqueTestName(testName);
+    @ParameterizedTest
+    @ValueSource(strings = {StreamsConfig.AT_LEAST_ONCE, StreamsConfig.EXACTLY_ONCE, StreamsConfig.EXACTLY_ONCE_V2})
+    public void shouldRecoverBufferAfterShutdown(final String processingGuarantee, final TestInfo testInfo) {
+        final String testId = safeUniqueTestName(testInfo);
         final String appId = "appId_" + testId;
         final String input = "input" + testId;
         final String storeName = "counts";
@@ -172,7 +153,7 @@ public class SuppressionDurabilityIntegrationTest {
             mkEntry(StreamsConfig.APPLICATION_ID_CONFIG, appId),
             mkEntry(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers()),
             mkEntry(StreamsConfig.POLL_MS_CONFIG, Long.toString(COMMIT_INTERVAL)),
-            mkEntry(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, processingGuaranteee),
+            mkEntry(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, processingGuarantee),
             mkEntry(StreamsConfig.STATE_DIR_CONFIG, TestUtils.tempDirectory().getPath())
         ));
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionIntegrationTest.java
index 35eee4764d4..9b9722e8539 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/SuppressionIntegrationTest.java
@@ -42,15 +42,14 @@ import org.apache.kafka.streams.kstream.KTable;
 import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.kstream.Produced;
 import org.apache.kafka.streams.state.KeyValueStore;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
+
 import org.hamcrest.Matchers;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
+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.Timeout;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -81,10 +80,9 @@ import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.empty;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class SuppressionIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(
         1,
@@ -92,12 +90,12 @@ public class SuppressionIntegrationTest {
         0L
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/TableTableJoinIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/TableTableJoinIntegrationTest.java
index 24f4dc1face..a7cb0871286 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/TableTableJoinIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/TableTableJoinIntegrationTest.java
@@ -16,7 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.time.Duration;
 import org.apache.kafka.common.serialization.Serdes;
 import org.apache.kafka.common.utils.Bytes;
 import org.apache.kafka.streams.StreamsBuilder;
@@ -26,65 +25,55 @@ import org.apache.kafka.streams.kstream.Materialized;
 import org.apache.kafka.streams.state.KeyValueStore;
 import org.apache.kafka.streams.state.Stores;
 import org.apache.kafka.streams.test.TestRecord;
-import org.apache.kafka.test.IntegrationTest;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
 
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.Properties;
 
 /**
  * Tests all available joins of Kafka Streams DSL.
  */
-@Category({IntegrationTest.class})
-@RunWith(value = Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
-    private KTable<Long, String> leftTable;
-    private KTable<Long, String> rightTable;
-
-    public TableTableJoinIntegrationTest(final boolean cacheEnabled) {
-        super(cacheEnabled);
-    }
-
-    @Before
-    public void prepareTopology() throws InterruptedException {
-        super.prepareEnvironment();
-
-        appID = "table-table-join-integration-test";
-
-        builder = new StreamsBuilder();
-    }
-
-    private final TestRecord<Long, String> expectedFinalJoinResultUnversioned = new TestRecord<>(ANY_UNIQUE_KEY, "F-f", null, 4L);
-    private final TestRecord<Long, String> expectedFinalJoinResultLeftVersionedOnly = new TestRecord<>(ANY_UNIQUE_KEY, "E-f", null, 15L);
-    private final TestRecord<Long, String> expectedFinalJoinResultRightVersionedOnly = new TestRecord<>(ANY_UNIQUE_KEY, "F-e", null, 14L);
-    private final TestRecord<Long, String> expectedFinalMultiJoinResult = new TestRecord<>(ANY_UNIQUE_KEY, "F-f-f", null, 4L);
-    private final String storeName = appID + "-store";
-
-    private final Materialized<Long, String, KeyValueStore<Bytes, byte[]>> materialized = Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as(storeName)
+    private static final String APP_ID = "table-table-join-integration-test";
+    private static final String STORE_NAME = APP_ID + "-store";
+    private final TestRecord<Long, String> expectedFinalJoinResultUnversioned =
+            new TestRecord<>(ANY_UNIQUE_KEY, "F-f", null, 4L);
+    private final TestRecord<Long, String> expectedFinalJoinResultLeftVersionedOnly =
+            new TestRecord<>(ANY_UNIQUE_KEY, "E-f", null, 15L);
+    private final TestRecord<Long, String> expectedFinalJoinResultRightVersionedOnly =
+            new TestRecord<>(ANY_UNIQUE_KEY, "F-e", null, 14L);
+    private final TestRecord<Long, String> expectedFinalMultiJoinResult =
+            new TestRecord<>(ANY_UNIQUE_KEY, "F-f-f", null, 4L);
+
+    private final Materialized<Long, String, KeyValueStore<Bytes, byte[]>> materialized = Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as(STORE_NAME)
             .withKeySerde(Serdes.Long())
             .withValueSerde(Serdes.String())
             .withCachingDisabled()
             .withLoggingDisabled();
 
-    @Test
-    public void testInner() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftTable.join(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultUnversioned, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultUnversioned, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -112,20 +101,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "F-f", null, 4L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeft() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftTable.leftJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultUnversioned, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultUnversioned, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -153,20 +146,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "F-f", null, 4L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuter() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuter(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
         leftTable.outerJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultUnversioned, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultUnversioned, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -194,20 +191,20 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "F-f", null, 4L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testInnerWithVersionedStores() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerWithVersionedStores(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftTable.join(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         // versioned stores do not support caching, so we expect the same result regardless of whether caching is enabled or not
@@ -237,19 +234,19 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
             null
         );
 
-        runTestWithDriver(input, expectedResult, storeName);
+        runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testLeftWithVersionedStores() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftWithVersionedStores(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftTable.leftJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         // versioned stores do not support caching, so we expect the same result regardless of whether caching is enabled or not
@@ -279,19 +276,19 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
             null
         );
 
-        runTestWithDriver(input, expectedResult, storeName);
+        runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testOuterWithVersionedStores() {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterWithVersionedStores(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
         leftTable.outerJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         // versioned stores do not support caching, so we expect the same result regardless of whether caching is enabled or not
@@ -321,21 +318,23 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
             null
         );
 
-        runTestWithDriver(input, expectedResult, storeName);
+        runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
     }
 
-    @Test
-    public void testInnerWithLeftVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerWithLeftVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftTable.join(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -363,22 +362,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "E-f", null, 15L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeftWithLeftVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftWithLeftVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftTable.leftJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -406,22 +407,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "E-f", null, 15L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuterWithLeftVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterWithLeftVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("left", Duration.ofMinutes(5))).withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
         leftTable.outerJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultLeftVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -449,22 +452,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 Collections.singletonList(new TestRecord<>(ANY_UNIQUE_KEY, "E-f", null, 15L))
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testInnerWithRightVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerWithRightVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner");
         leftTable.join(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -492,22 +497,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeftWithRightVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftWithRightVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-left");
         leftTable.leftJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -535,22 +542,24 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuterWithRightVersionedOnly() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String>as(
-            Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))
-        ).withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterWithRightVersionedOnly(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String>as(Stores.persistentVersionedKeyValueStore("right", Duration.ofMinutes(5))).withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-outer");
         leftTable.outerJoin(rightTable, valueJoiner, materialized).toStream().to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, storeName);
+            runTestWithDriver(input, expectedFinalJoinResultRightVersionedOnly, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -578,23 +587,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(input, expectedResult, storeName);
+            runTestWithDriver(input, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testInnerInner() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-inner");
         leftTable.join(rightTable, valueJoiner)
                  .join(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             // TODO K6443: the duplicate below for all the multi-joins are due to
             //             KAFKA-6443, should be updated once it is fixed.
@@ -625,23 +638,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testInnerLeft() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-left");
         leftTable.join(rightTable, valueJoiner)
                  .leftJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -669,23 +686,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testInnerOuter() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testInnerOuter(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-outer");
         leftTable.join(rightTable, valueJoiner)
                  .outerJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -716,23 +737,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeftInner() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-inner");
         leftTable.leftJoin(rightTable, valueJoiner)
                  .join(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -760,23 +785,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeftLeft() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-left");
         leftTable.leftJoin(rightTable, valueJoiner)
                  .leftJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -806,23 +835,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testLeftOuter() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testLeftOuter(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-outer");
         leftTable.leftJoin(rightTable, valueJoiner)
                  .outerJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -852,23 +885,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuterInner() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-inner");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterInner(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-inner");
         leftTable.outerJoin(rightTable, valueJoiner)
                  .join(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -898,23 +935,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuterLeft() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-left");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterLeft(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-left");
         leftTable.outerJoin(rightTable, valueJoiner)
                  .leftJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -946,23 +987,27 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null
             );
 
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 
-    @Test
-    public void testOuterOuter() throws Exception {
-        STREAMS_CONFIG.put(StreamsConfig.APPLICATION_ID_CONFIG, appID + "-inner-outer");
-
-        leftTable = builder.table(INPUT_TOPIC_LEFT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
-        rightTable = builder.table(INPUT_TOPIC_RIGHT, Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+    @ParameterizedTest
+    @ValueSource(booleans = {true, false})
+    public void testOuterOuter(final boolean cacheEnabled) {
+        final StreamsBuilder builder = new StreamsBuilder();
+        final KTable<Long, String> leftTable = builder.table(INPUT_TOPIC_LEFT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("left").withLoggingDisabled());
+        final KTable<Long, String> rightTable = builder.table(INPUT_TOPIC_RIGHT,
+                Materialized.<Long, String, KeyValueStore<Bytes, byte[]>>as("right").withLoggingDisabled());
+        final Properties streamsConfig = setupConfigsAndUtils(cacheEnabled);
+        streamsConfig.put(StreamsConfig.APPLICATION_ID_CONFIG, APP_ID + "-inner-outer");
         leftTable.outerJoin(rightTable, valueJoiner)
                  .outerJoin(rightTable, valueJoiner, materialized)
                  .toStream()
                  .to(OUTPUT_TOPIC);
 
         if (cacheEnabled) {
-            runTestWithDriver(input, expectedFinalMultiJoinResult, storeName);
+            runTestWithDriver(input, expectedFinalMultiJoinResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         } else {
             final List<List<TestRecord<Long, String>>> expectedResult = Arrays.asList(
                 null,
@@ -995,7 +1040,7 @@ public class TableTableJoinIntegrationTest extends AbstractJoinIntegrationTest {
                 null,
                 null
             );
-            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, storeName);
+            runTestWithDriver(inputWithoutOutOfOrderData, expectedResult, STORE_NAME, streamsConfig, builder.build(streamsConfig));
         }
     }
 }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/TaskAssignorIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/TaskAssignorIntegrationTest.java
index 3e29773a151..4ffacb8357e 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/TaskAssignorIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/TaskAssignorIntegrationTest.java
@@ -31,15 +31,14 @@ import org.apache.kafka.streams.processor.internals.StreamsPartitionAssignor;
 import org.apache.kafka.streams.processor.internals.assignment.AssignorConfiguration.AssignmentListener;
 import org.apache.kafka.streams.processor.internals.assignment.HighAvailabilityTaskAssignor;
 import org.apache.kafka.streams.processor.internals.assignment.LegacyTaskAssignor;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+
+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.junit.jupiter.api.Timeout;
 
 import java.io.IOException;
 import java.lang.reflect.Field;
@@ -57,33 +56,29 @@ import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.sameInstance;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class TaskAssignorIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
-
     // Just a dummy implementation so we can check the config
     public static final class MyLegacyTaskAssignor extends HighAvailabilityTaskAssignor implements
         LegacyTaskAssignor { }
 
     @SuppressWarnings("unchecked")
     @Test
-    public void shouldProperlyConfigureTheAssignor() throws NoSuchFieldException, IllegalAccessException {
+    public void shouldProperlyConfigureTheAssignor(final TestInfo testInfo) throws NoSuchFieldException, IllegalAccessException {
         // This test uses reflection to check and make sure that all the expected configurations really
         // make it all the way to configure the task assignor. There's no other use case for being able
         // to extract all these fields, so reflection is a good choice until we find that the maintenance
@@ -93,7 +88,7 @@ public class TaskAssignorIntegrationTest {
         // ensure these configurations wind up where they belong, and any number of future code changes
         // could break this change.
 
-        final String testId = safeUniqueTestName(testName);
+        final String testId = safeUniqueTestName(testInfo);
         final String appId = "appId_" + testId;
         final String inputTopic = "input" + testId;
 
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/TaskMetadataIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/TaskMetadataIntegrationTest.java
index 62d3758c86c..0238dcae621 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/TaskMetadataIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/TaskMetadataIntegrationTest.java
@@ -30,17 +30,16 @@ import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.KStream;
 import org.apache.kafka.streams.processor.api.ContextualProcessor;
 import org.apache.kafka.streams.processor.api.Record;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+
+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.junit.jupiter.api.Timeout;
 
 import java.io.IOException;
 import java.util.Collections;
@@ -58,25 +57,23 @@ import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.sa
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.MatcherAssert.assertThat;
 
-@Category(IntegrationTest.class)
+@Tag("integration")
+@Timeout(600)
 public class TaskMetadataIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     public static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1, new Properties(), Collections.emptyList(), 0L, 0L);
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
 
-    @Rule
-    public TestName testName = new TestName();
+    public TestInfo testInfo;
 
     private String inputTopic;
     private static StreamsBuilder builder;
@@ -86,9 +83,9 @@ public class TaskMetadataIntegrationTest {
     private AtomicBoolean process;
     private AtomicBoolean commit;
 
-    @Before
-    public void setup() {
-        final String testId = safeUniqueTestName(testName);
+    @BeforeEach
+    public void setup(final TestInfo testInfo) {
+        final String testId = safeUniqueTestName(testInfo);
         appId = appIdPrefix + testId;
         inputTopic = "input" + testId;
         IntegrationTestUtils.cleanStateBeforeTest(CLUSTER, inputTopic);
@@ -170,7 +167,7 @@ public class TaskMetadataIntegrationTest {
         return taskMetadataList.get().get(0);
     }
 
-    @After
+    @AfterEach
     public void teardown() throws IOException {
         purgeLocalStreamsState(properties);
     }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/TimeWindowedKStreamIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/TimeWindowedKStreamIntegrationTest.java
index 6f5a2b09be6..38287d7556d 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/TimeWindowedKStreamIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/TimeWindowedKStreamIntegrationTest.java
@@ -16,8 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import java.util.Collection;
-import java.util.Optional;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.serialization.Deserializer;
 import org.apache.kafka.common.serialization.Serde;
@@ -26,14 +24,13 @@ import org.apache.kafka.common.serialization.Serdes.StringSerde;
 import org.apache.kafka.common.serialization.StringDeserializer;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.StreamsBuilder;
 import org.apache.kafka.streams.StreamsConfig;
-import org.apache.kafka.streams.KeyValueTimestamp;
 import org.apache.kafka.streams.StreamsConfig.InternalConfig;
 import org.apache.kafka.streams.integration.utils.EmbeddedKafkaCluster;
 import org.apache.kafka.streams.integration.utils.IntegrationTestUtils;
 import org.apache.kafka.streams.kstream.Consumed;
-import org.apache.kafka.streams.kstream.EmitStrategy;
 import org.apache.kafka.streams.kstream.EmitStrategy.StrategyType;
 import org.apache.kafka.streams.kstream.JoinWindows;
 import org.apache.kafka.streams.kstream.KStream;
@@ -47,29 +44,27 @@ import org.apache.kafka.streams.kstream.UnlimitedWindows;
 import org.apache.kafka.streams.kstream.Windowed;
 import org.apache.kafka.streams.kstream.WindowedSerdes;
 import org.apache.kafka.streams.kstream.internals.TimeWindow;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.MockAggregator;
 import org.apache.kafka.test.MockInitializer;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-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.TestInfo;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+import org.junit.jupiter.params.provider.EnumSource;
 
 import java.io.IOException;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
-import java.util.Collections;
-
-import org.junit.rules.Timeout;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameter;
 
 import static java.time.Duration.ofMillis;
 import static java.time.Instant.ofEpochMilli;
@@ -80,14 +75,12 @@ import static org.apache.kafka.common.utils.Utils.mkProperties;
 import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 @SuppressWarnings({"unchecked"})
-@Category({IntegrationTest.class})
-@RunWith(Parameterized.class)
+@Tag("integration")
+@Timeout(600)
 public class TimeWindowedKStreamIntegrationTest {
-    @Rule
-    public Timeout globalTimeout = Timeout.seconds(600);
 
     private static final int NUM_BROKERS = 1;
 
@@ -97,12 +90,12 @@ public class TimeWindowedKStreamIntegrationTest {
         )
     );
 
-    @BeforeClass
+    @BeforeAll
     public static void startCluster() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void closeCluster() {
         CLUSTER.stop();
     }
@@ -114,37 +107,12 @@ public class TimeWindowedKStreamIntegrationTest {
     private String streamOneInput;
     private String streamTwoInput;
     private String outputTopic;
-
-    @Rule
-    public TestName testName = new TestName();
-
-    @Parameter
-    public StrategyType type;
-
-    @Parameter(1)
-    public boolean withCache;
-
-    @Parameter(2)
-    public EmitStrategy emitStrategy;
-
-    private boolean emitFinal;
-
     private String safeTestName;
 
-    @Parameterized.Parameters(name = "{0}_{1}")
-    public static Collection<Object[]> getEmitStrategy() {
-        return asList(new Object[][] {
-            {StrategyType.ON_WINDOW_UPDATE, true, EmitStrategy.onWindowUpdate()},
-            {StrategyType.ON_WINDOW_UPDATE, false, EmitStrategy.onWindowUpdate()},
-            {StrategyType.ON_WINDOW_CLOSE, true, EmitStrategy.onWindowClose()},
-            {StrategyType.ON_WINDOW_CLOSE, false, EmitStrategy.onWindowClose()}
-        });
-    }
-
-    @Before
-    public void before() throws InterruptedException {
+    @BeforeEach
+    public void before(final TestInfo testInfo) throws InterruptedException {
         builder = new StreamsBuilder();
-        safeTestName = safeUniqueTestName(testName);
+        safeTestName = safeUniqueTestName(testInfo);
         createTopics();
         streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "app-" + safeTestName);
@@ -157,11 +125,9 @@ public class TimeWindowedKStreamIntegrationTest {
         streamsConfiguration.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
         streamsConfiguration.put(InternalConfig.EMIT_INTERVAL_MS_KSTREAMS_WINDOWED_AGGREGATION, 0); // Always process
         streamsConfiguration.put(StreamsConfig.WINDOW_STORE_CHANGE_LOG_ADDITIONAL_RETENTION_MS_CONFIG, Long.MAX_VALUE); // Don't expire changelog
-
-        emitFinal = emitStrategy.type() == StrategyType.ON_WINDOW_CLOSE;
     }
 
-    @After
+    @AfterEach
     public void whenShuttingDown() throws IOException {
         if (kafkaStreams != null) {
             kafkaStreams.close();
@@ -170,8 +136,9 @@ public class TimeWindowedKStreamIntegrationTest {
         IntegrationTestUtils.purgeLocalStreamsState(streamsConfiguration);
     }
 
-    @Test
-    public void shouldAggregateWindowedWithNoGrace() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldAggregateWindowedWithNoGrace(final StrategyType type, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "1", 0),
@@ -187,11 +154,11 @@ public class TimeWindowedKStreamIntegrationTest {
         builder.stream(streamOneInput, Consumed.with(Serdes.String(), Serdes.String()))
             .groupByKey()
             .windowedBy(TimeWindows.ofSizeWithNoGrace(ofMillis(10L)).advanceBy(ofMillis(5L)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(type))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
@@ -203,6 +170,7 @@ public class TimeWindowedKStreamIntegrationTest {
         // observedStreamTime : 15, retentionPeriod: 10, actualFrom: 5, timeTo: 5, timeFrom: 1
         // observedStreamTime : 25, retentionPeriod: 10, actualFrom: 15, timeTo: 15, timeFrom: 6
 
+        final boolean emitFinal = type == StrategyType.ON_WINDOW_CLOSE;
         final List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
                 new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
                 new StringDeserializer(),
@@ -238,8 +206,9 @@ public class TimeWindowedKStreamIntegrationTest {
         assertThat(windowedMessages, is(expectResult));
     }
 
-    @Test
-    public void shouldAggregateWindowedWithGrace() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldAggregateWindowedWithGrace(final StrategyType type, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "1", 0),
@@ -255,11 +224,11 @@ public class TimeWindowedKStreamIntegrationTest {
         builder.stream(streamOneInput, Consumed.with(Serdes.String(), Serdes.String()))
             .groupByKey()
             .windowedBy(TimeWindows.ofSizeAndGrace(ofMillis(10L), ofMillis(5)).advanceBy(ofMillis(5L)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(type))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
@@ -270,6 +239,7 @@ public class TimeWindowedKStreamIntegrationTest {
         // observedStreamTime : 15, retentionPeriod: 15, actualFrom: 0, timeTo: 0, timeFrom: 0
         // observedStreamTime : 25, retentionPeriod: 15, actualFrom: 10, timeTo: 10, timeFrom: 1
 
+        final boolean emitFinal = type == StrategyType.ON_WINDOW_CLOSE;
         final List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
             new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
             new StringDeserializer(),
@@ -306,8 +276,9 @@ public class TimeWindowedKStreamIntegrationTest {
         assertThat(windowedMessages, is(expectResult));
     }
 
-    @Test
-    public void shouldRestoreAfterJoinRestart() throws Exception {
+    @ParameterizedTest
+    @CsvSource({"ON_WINDOW_UPDATE, true", "ON_WINDOW_UPDATE, false", "ON_WINDOW_CLOSE, true", "ON_WINDOW_CLOSE, false"})
+    public void shouldRestoreAfterJoinRestart(final StrategyType type, final boolean withCache) throws Exception {
         produceMessages(
             streamOneInput,
             new KeyValueTimestamp<>("A", "L1", 0),
@@ -339,11 +310,11 @@ public class TimeWindowedKStreamIntegrationTest {
 
         joinedStream.groupByKey()
             .windowedBy(TimeWindows.ofSizeWithNoGrace(ofMillis(10L)).advanceBy(ofMillis(5L)))
-            .emitStrategy(emitStrategy)
+            .emitStrategy(StrategyType.forType(type))
             .aggregate(
                 MockInitializer.STRING_INIT,
                 MockAggregator.TOSTRING_ADDER,
-                getMaterialized()
+                getMaterialized(withCache)
             )
             .toStream()
             .to(outputTopic, Produced.with(windowedSerde, new StringSerde()));
@@ -351,6 +322,7 @@ public class TimeWindowedKStreamIntegrationTest {
         startStreams();
 
         // ON_WINDOW_CLOSE expires all records.
+        final boolean emitFinal = type == StrategyType.ON_WINDOW_CLOSE;
         List<KeyValueTimestamp<Windowed<String>, String>> windowedMessages = receiveMessagesWithTimestamp(
             new TimeWindowedDeserializer<>(new StringDeserializer(), 10L),
             new StringDeserializer(),
@@ -442,18 +414,20 @@ public class TimeWindowedKStreamIntegrationTest {
         assertThat(windowedMessages, is(expectResult));
     }
 
-    @Test
-    public void shouldThrowUnlimitedWindows() {
+    @ParameterizedTest
+    @EnumSource(StrategyType.class)
+    public void shouldThrowUnlimitedWindows(final StrategyType type) {
         final TimeWindowedKStream<String, String> windowedStream = builder.stream(streamOneInput, Consumed.with(Serdes.String(), Serdes.String()))
             .groupByKey()
             .windowedBy(
             UnlimitedWindows.of().startOn(ofEpochMilli(0))
         );
 
+        final boolean emitFinal = type == StrategyType.ON_WINDOW_CLOSE;
         if (emitFinal) {
-            assertThrows(IllegalArgumentException.class, () -> windowedStream.emitStrategy(emitStrategy));
+            assertThrows(IllegalArgumentException.class, () -> windowedStream.emitStrategy(StrategyType.forType(type)));
         } else {
-            windowedStream.emitStrategy(emitStrategy);
+            windowedStream.emitStrategy(StrategyType.forType(type));
         }
     }
 
@@ -471,7 +445,7 @@ public class TimeWindowedKStreamIntegrationTest {
         );
     }
 
-    private Materialized getMaterialized() {
+    private Materialized getMaterialized(final boolean withCache) {
         if (withCache) {
             return Materialized.with(null, new StringSerde()).withCachingEnabled();
         }
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/VersionedKeyValueStoreIntegrationTest.java b/streams/src/test/java/org/apache/kafka/streams/integration/VersionedKeyValueStoreIntegrationTest.java
index 15b1ae1ea80..6f22a234e42 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/VersionedKeyValueStoreIntegrationTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/VersionedKeyValueStoreIntegrationTest.java
@@ -16,20 +16,6 @@
  */
 package org.apache.kafka.streams.integration;
 
-import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import java.io.IOException;
-import java.time.Duration;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Properties;
 import org.apache.kafka.clients.consumer.ConsumerConfig;
 import org.apache.kafka.common.config.TopicConfig;
 import org.apache.kafka.common.serialization.IntegerDeserializer;
@@ -67,25 +53,38 @@ import org.apache.kafka.streams.state.VersionedBytesStoreSupplier;
 import org.apache.kafka.streams.state.VersionedKeyValueStore;
 import org.apache.kafka.streams.state.VersionedRecord;
 import org.apache.kafka.streams.state.internals.VersionedKeyValueToBytesStoreAdapter;
-import org.apache.kafka.test.IntegrationTest;
 import org.apache.kafka.test.TestUtils;
-import org.junit.After;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.rules.TestName;
-
-@Category({IntegrationTest.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.Test;
+import org.junit.jupiter.api.TestInfo;
+
+import java.io.IOException;
+import java.time.Duration;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Properties;
+
+import static org.apache.kafka.streams.integration.utils.IntegrationTestUtils.safeUniqueTestName;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+@Tag("integration")
 public class VersionedKeyValueStoreIntegrationTest {
 
     private static final String STORE_NAME = "versioned-store";
     private static final long HISTORY_RETENTION = 3600_000L;
 
     private String inputStream;
-    private String globalTableTopic;
     private String outputStream;
     private long baseTimestamp;
 
@@ -93,24 +92,23 @@ public class VersionedKeyValueStoreIntegrationTest {
 
     private static final EmbeddedKafkaCluster CLUSTER = new EmbeddedKafkaCluster(1);
 
-    @Rule
-    public TestName testName = new TestName();
+    public TestInfo testInfo;
 
-    @BeforeClass
+    @BeforeAll
     public static void before() throws IOException {
         CLUSTER.start();
     }
 
-    @AfterClass
+    @AfterAll
     public static void after() {
         CLUSTER.stop();
     }
 
-    @Before
-    public void beforeTest() throws InterruptedException {
-        final String uniqueTestName = safeUniqueTestName(testName);
+    @BeforeEach
+    public void beforeTest(final TestInfo testInfo) throws InterruptedException {
+        this.testInfo = testInfo;
+        final String uniqueTestName = safeUniqueTestName(testInfo);
         inputStream = "input-stream-" + uniqueTestName;
-        globalTableTopic = "global-table-" + uniqueTestName;
         outputStream = "output-stream-" + uniqueTestName;
         CLUSTER.createTopic(inputStream);
         CLUSTER.createTopic(outputStream);
@@ -118,7 +116,7 @@ public class VersionedKeyValueStoreIntegrationTest {
         baseTimestamp = CLUSTER.time.milliseconds();
     }
 
-    @After
+    @AfterEach
     public void afterTest() {
         if (kafkaStreams != null) {
             kafkaStreams.close(Duration.ofSeconds(30L));
@@ -429,7 +427,7 @@ public class VersionedKeyValueStoreIntegrationTest {
     }
 
     private Properties props() {
-        final String safeTestName = safeUniqueTestName(testName);
+        final String safeTestName = safeUniqueTestName(testInfo);
         final Properties streamsConfiguration = new Properties();
         streamsConfiguration.put(StreamsConfig.APPLICATION_ID_CONFIG, "app-" + safeTestName);
         streamsConfiguration.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, CLUSTER.bootstrapServers());
diff --git a/streams/src/test/java/org/apache/kafka/streams/integration/utils/IntegrationTestUtils.java b/streams/src/test/java/org/apache/kafka/streams/integration/utils/IntegrationTestUtils.java
index 7c5734d7b96..67102cdcc4e 100644
--- a/streams/src/test/java/org/apache/kafka/streams/integration/utils/IntegrationTestUtils.java
+++ b/streams/src/test/java/org/apache/kafka/streams/integration/utils/IntegrationTestUtils.java
@@ -16,8 +16,6 @@
  */
 package org.apache.kafka.streams.integration.utils;
 
-import kafka.server.KafkaServer;
-import kafka.server.MetadataCache;
 import org.apache.kafka.clients.admin.Admin;
 import org.apache.kafka.clients.admin.ConsumerGroupDescription;
 import org.apache.kafka.clients.consumer.Consumer;
@@ -61,6 +59,9 @@ import org.apache.kafka.streams.query.StateQueryResult;
 import org.apache.kafka.streams.state.QueryableStoreType;
 import org.apache.kafka.test.TestCondition;
 import org.apache.kafka.test.TestUtils;
+
+import kafka.server.KafkaServer;
+import kafka.server.MetadataCache;
 import org.junit.jupiter.api.TestInfo;
 import org.junit.rules.TestName;
 import org.slf4j.Logger;
@@ -97,6 +98,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.stream.Collectors;
 
+import static java.util.Collections.singletonList;
 import static org.apache.kafka.common.utils.Utils.sleep;
 import static org.apache.kafka.test.TestUtils.retryOnExceptionWithTimeout;
 import static org.apache.kafka.test.TestUtils.waitForCondition;
@@ -104,8 +106,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThanOrEqualTo;
 import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.fail;
-import static java.util.Collections.singletonList;
+import static org.junit.jupiter.api.Assertions.fail;
 
 /**
  * Utility functions to make integration testing more convenient.
diff --git a/streams/src/test/java/org/apache/kafka/streams/internals/ApiUtilsTest.java b/streams/src/test/java/org/apache/kafka/streams/internals/ApiUtilsTest.java
index e00f12b5554..3d5c438f9f9 100644
--- a/streams/src/test/java/org/apache/kafka/streams/internals/ApiUtilsTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/internals/ApiUtilsTest.java
@@ -29,7 +29,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.fail;
 
-
 public class ApiUtilsTest {
     // This is the maximum limit that Duration accepts but fails when it converts to milliseconds.
     private static final long MAX_ACCEPTABLE_DAYS_FOR_DURATION = 106751991167300L;
diff --git a/streams/src/test/java/org/apache/kafka/streams/internals/metrics/ClientMetricsTest.java b/streams/src/test/java/org/apache/kafka/streams/internals/metrics/ClientMetricsTest.java
index daaa737fc33..2fb876561aa 100644
--- a/streams/src/test/java/org/apache/kafka/streams/internals/metrics/ClientMetricsTest.java
+++ b/streams/src/test/java/org/apache/kafka/streams/internals/metrics/ClientMetricsTest.java
@@ -21,11 +21,8 @@ import org.apache.kafka.common.metrics.Sensor;
 import org.apache.kafka.common.metrics.Sensor.RecordingLevel;
 import org.apache.kafka.streams.KafkaStreams.State;
 import org.apache.kafka.streams.processor.internals.metrics.StreamsMetricsImpl;
+
 import org.junit.Test;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.eq;
 
 import java.util.Collections;
 import java.util.Map;
@@ -33,6 +30,10 @@ import java.util.Map;
 import static org.apache.kafka.streams.processor.internals.metrics.StreamsMetricsImpl.CLIENT_LEVEL_GROUP;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class ClientMetricsTest {
     private static final String COMMIT_ID = "test-commit-ID";