From fb945f1d4dd8cb53d28f707f0523c76d36438285 Mon Sep 17 00:00:00 2001
From: strangelookingnerd
 <49242855+strangelookingnerd@users.noreply.github.com>
Date: Wed, 20 Aug 2025 17:01:02 +0200
Subject: [PATCH 1/3] Migrate tests to JUnit5
* Migrate annotations and imports
* Migrate assertions
* Remove public visibility for test classes and methods
* Minor code cleanup
---
 pom.xml                                       |   9 +-
 .../kubernetes/AbstractGoldenFileTest.java    |  17 +-
 .../kubernetes/ConfigMapVolumeTest.java       |  13 +-
 .../kubernetes/ContainerTemplateTest.java     |  29 +-
 .../kubernetes/KubectlBuildWrapperTest.java   |  17 +-
 .../KubernetesClientProviderTest.java         |  21 +-
 .../kubernetes/KubernetesCloudFIPSTest.java   |  60 +-
 .../kubernetes/KubernetesCloudTest.java       | 102 ++--
 .../kubernetes/KubernetesCloudTraitTest.java  |  28 +-
 .../KubernetesFactoryAdapterTest.java         |  43 +-
 .../KubernetesFolderPropertyTest.java         |  18 +-
 .../KubernetesProvisioningLimitsTest.java     |  34 +-
 .../KubernetesQueueTaskDispatcherTest.java    |  75 +--
 .../kubernetes/KubernetesRestartTest.java     |  16 +-
 .../kubernetes/KubernetesSlaveTest.java       |  35 +-
 .../plugins/kubernetes/KubernetesTest.java    |  48 +-
 .../kubernetes/KubernetesTestUtil.java        |  28 +-
 .../plugins/kubernetes/MetricNamesTest.java   |  19 +-
 .../NonConfigurableKubernetesCloudTest.java   |  28 +-
 .../kubernetes/PodContainerSourceTest.java    |  26 +-
 .../plugins/kubernetes/PodEnvVarTest.java     |   8 +-
 .../kubernetes/PodTemplateBuilderTest.java    | 537 ++++++++++--------
 .../kubernetes/PodTemplateFilterTest.java     |  21 +-
 .../kubernetes/PodTemplateJenkinsTest.java    |  27 +-
 .../kubernetes/PodTemplateMapTest.java        |  29 +-
 .../plugins/kubernetes/PodTemplateTest.java   |  11 +-
 .../kubernetes/PodTemplateUtilsTest.java      | 192 +++----
 .../plugins/kubernetes/PodUtilsTest.java      |  14 +-
 .../RestrictedPssSecurityInjectorTest.java    |  20 +-
 .../TaskListenerEventWatcherTest.java         |  32 +-
 .../plugins/kubernetes/casc/CasCTest.java     |  18 +-
 .../kubernetes/casc/EnvVarCasCTest.java       |  47 +-
 .../kubernetes/casc/VolumeCasCTest.java       |  63 +-
 .../casc/WorkspaceVolumeCasCTest.java         |  63 +-
 .../AbstractKubernetesPipelineRJRTest.java    |  35 +-
 .../AbstractKubernetesPipelineTest.java       |  80 ++-
 .../ContainerExecDecoratorPipelineTest.java   |  30 +-
 .../pipeline/ContainerExecDecoratorTest.java  | 164 +++---
 .../ContainerExecDecoratorWindowsTest.java    |  89 +--
 .../pipeline/ContainerLogStepTest.java        |   8 +-
 .../pipeline/DirectConnectionTest.java        |  16 +-
 .../KubernetesAgentErrorConditionTest.java    |  44 +-
 .../KubernetesDeclarativeAgentRJRTest.java    |   9 +-
 .../KubernetesDeclarativeAgentTest.java       |  55 +-
 .../KubernetesDeclarativeAgentUnitTest.java   |  63 +-
 .../pipeline/KubernetesNodeContextTest.java   |  33 +-
 ...netesPipelineOverriddenNamespaceTest.java} |  12 +-
 .../pipeline/KubernetesPipelineRJRTest.java   |  14 +-
 .../pipeline/KubernetesPipelineTest.java      | 212 ++++---
 .../KubernetesPipelineWebsocketRJRTest.java   |   9 +-
 .../pipeline/KubernetesSamplesTest.java       |  29 +-
 .../NoDelayProvisionerStrategyTest.java       |  23 +-
 .../kubernetes/pipeline/PodNameTest.java      |  12 +-
 .../PodProvisioningStatusLogsTest.java        |  12 +-
 .../PodTemplateStepExecutionTest.java         |  29 +-
 .../pipeline/PodTemplateStepTest.java         |  21 +-
 .../kubernetes/pipeline/ResourcesTest.java    |  10 +-
 .../pipeline/RestartPipelineTest.java         | 114 ++--
 .../kubernetes/pipeline/WebSocketTest.java    |  12 +-
 .../pipeline/steps/AssertBuildLogMessage.java |   4 +-
 .../steps/AssertBuildStatusSuccess.java       |   4 +-
 .../CreateWorkflowJobThenScheduleRun.java     |   4 +-
 .../CreateWorkflowJobThenScheduleTask.java    |   4 +-
 .../kubernetes/pipeline/steps/SetupCloud.java |   9 +-
 .../pod/decorator/PodDecoratorTest.java       |  28 +-
 .../pod/retention/PodRetentionTest.java       |  23 +-
 .../kubernetes/pod/retention/ReaperTest.java  | 174 +++---
 .../volumes/GenericEphemeralVolumeTest.java   |   8 +-
 .../GenericEphemeralWorkspaceVolumeTest.java  |   8 +-
 69 files changed, 1620 insertions(+), 1529 deletions(-)
 rename src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/{KubernetesPipelineOverridenNamespaceTest.java => KubernetesPipelineOverriddenNamespaceTest.java} (84%)
diff --git a/pom.xml b/pom.xml
index e90b491d79..33fca001ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -51,6 +51,7 @@
     Max
     Low
     false
+    false
   
 
   
@@ -261,13 +262,7 @@
     
     
       org.mockito
-      mockito-core
-      test
-    
-    
-      pl.pragmatists
-      JUnitParams
-      1.1.1
+      mockito-junit-jupiter
       test
     
   
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java
index b07385b128..749c25468f 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/AbstractGoldenFileTest.java
@@ -1,40 +1,39 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.client.utils.Serialization;
-import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import org.apache.commons.io.IOUtils;
 import org.csanchez.jenkins.plugins.kubernetes.pod.decorator.PodDecorator;
-import org.junit.Before;
+import org.junit.jupiter.api.BeforeEach;
 
 abstract class AbstractGoldenFileTest {
 
     protected KubernetesCloud cloud;
     protected PodDecorator decorator;
 
-    @Before
-    public void setUpCloud() {
+    @BeforeEach
+    void beforeEach() {
         decorator = newDecorator();
         cloud = new KubernetesCloud("test");
     }
 
     protected abstract PodDecorator newDecorator();
 
-    protected void test(String name) throws IOException {
+    protected void test(String name) throws Exception {
         var beforeYAML = loadFileAsStream(name + "-before.yaml");
         var before = Serialization.unmarshal(beforeYAML, Pod.class);
-        assertEquals(name + "-before.yaml is not normalized", Serialization.asYaml(before), beforeYAML);
+        assertEquals(Serialization.asYaml(before), beforeYAML, name + "-before.yaml is not normalized");
         var afterYAML = loadFileAsStream(name + "-after.yaml");
         var after = decorator.decorate(cloud, before);
-        assertEquals(name + "-after.yaml processed", Serialization.asYaml(after), afterYAML);
+        assertEquals(Serialization.asYaml(after), afterYAML, name + "-after.yaml processed");
     }
 
     @NonNull
-    private String loadFileAsStream(String name) throws IOException {
+    private String loadFileAsStream(String name) throws Exception {
         var is = getClass().getResourceAsStream(getClass().getSimpleName() + "/" + name);
         if (is == null) {
             throw new IllegalStateException("Test file \"src/test/resources/"
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java
index 1c7b1fefe4..1da6639286 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ConfigMapVolumeTest.java
@@ -15,23 +15,24 @@
 
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 import org.csanchez.jenkins.plugins.kubernetes.volumes.ConfigMapVolume;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class ConfigMapVolumeTest {
+class ConfigMapVolumeTest {
 
     @Test
-    public void testNullSubPathValue() {
+    void testNullSubPathValue() {
         ConfigMapVolume configMapVolume = new ConfigMapVolume("oneMountPath", "Myvolume", false);
         assertNull(configMapVolume.getSubPath());
     }
 
     @Test
-    public void testValidSubPathValue() {
+    void testValidSubPathValue() {
         ConfigMapVolume configMapVolume = new ConfigMapVolume("oneMountPath", "Myvolume", false);
         configMapVolume.setSubPath("miSubpath");
-        assertEquals(configMapVolume.getSubPath(), "miSubpath");
+        assertEquals("miSubpath", configMapVolume.getSubPath());
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java
index a879f5d69e..7fe2a6cb3e 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ContainerTemplateTest.java
@@ -15,16 +15,17 @@
 
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import hudson.util.FormValidation;
 import java.util.Collections;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class ContainerTemplateTest {
+class ContainerTemplateTest {
 
     @Test
-    public void testCopyConstructorCreatesEqualInstance() {
+    void testCopyConstructorCreatesEqualInstance() {
         ContainerTemplate originalTemplate = new ContainerTemplate("myname", "myimage");
         originalTemplate.setPrivileged(true);
         originalTemplate.setAlwaysPullImage(true);
@@ -43,31 +44,31 @@ public void testCopyConstructorCreatesEqualInstance() {
 
         ContainerTemplate clonedTemplate = new ContainerTemplate(originalTemplate);
 
-        assertEquals("Cloned ContainerTemplate is not equal to the original one!", originalTemplate, clonedTemplate);
+        assertEquals(originalTemplate, clonedTemplate, "Cloned ContainerTemplate is not equal to the original one!");
         assertEquals(
-                "String representation (toString()) of the cloned and original ContainerTemplate is not equal!",
                 originalTemplate.toString(),
-                clonedTemplate.toString());
+                clonedTemplate.toString(),
+                "String representation (toString()) of the cloned and original ContainerTemplate is not equal!");
     }
 
     @SuppressWarnings("ResultOfObjectAllocationIgnored")
     @Test
-    public void badImage() throws Exception {
+    void badImage() {
         new ContainerTemplate("n", "something");
         assertEquals(FormValidation.Kind.OK, new ContainerTemplate.DescriptorImpl().doCheckImage("something").kind);
         for (String empty : new String[] {null, ""}) {
-            assertThrows("rejected " + empty, IllegalArgumentException.class, () -> new ContainerTemplate("n", empty));
+            assertThrows(IllegalArgumentException.class, () -> new ContainerTemplate("n", empty), "rejected " + empty);
             assertEquals(
-                    "tolerating " + empty + " during form validation",
                     FormValidation.Kind.OK,
-                    new ContainerTemplate.DescriptorImpl().doCheckImage(empty).kind);
+                    new ContainerTemplate.DescriptorImpl().doCheckImage(empty).kind,
+                    "tolerating " + empty + " during form validation");
         }
         for (String bad : new String[] {" ", " something"}) {
-            assertThrows("rejected " + bad, IllegalArgumentException.class, () -> new ContainerTemplate("n", bad));
+            assertThrows(IllegalArgumentException.class, () -> new ContainerTemplate("n", bad), "rejected " + bad);
             assertEquals(
-                    "rejected " + bad,
                     FormValidation.Kind.ERROR,
-                    new ContainerTemplate.DescriptorImpl().doCheckImage(bad).kind);
+                    new ContainerTemplate.DescriptorImpl().doCheckImage(bad).kind,
+                    "rejected " + bad);
         }
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java
index 140898bc80..45505a8a13 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubectlBuildWrapperTest.java
@@ -2,19 +2,20 @@
 
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import com.cloudbees.plugins.credentials.CredentialsScope;
 import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
 import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
 import hudson.model.Result;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.AbstractKubernetesPipelineTest;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
-public class KubectlBuildWrapperTest extends AbstractKubernetesPipelineTest {
-    @Before
-    public void setUp() throws Exception {
+class KubectlBuildWrapperTest extends AbstractKubernetesPipelineTest {
+
+    @BeforeEach
+    void beforeEach() throws Exception {
         deletePods(cloud.connect(), getLabels(cloud, this, name), false);
         assertNotNull(createJobThenScheduleRun());
         UsernamePasswordCredentialsImpl creds = new UsernamePasswordCredentialsImpl(
@@ -23,13 +24,13 @@ public void setUp() throws Exception {
     }
 
     @Test
-    public void kubectlBuildWrapper_missingCredentials() throws Exception {
+    void kubectlBuildWrapper_missingCredentials() throws Exception {
         r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b));
         r.assertLogContains("No credentials found for id \"abcd\"", b);
     }
 
     @Test
-    public void kubectlBuildWrapper_invalidCredentials() throws Exception {
+    void kubectlBuildWrapper_invalidCredentials() throws Exception {
         r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b));
         r.assertLogContains("Unable to connect to the server", b);
     }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java
index b732454ebb..a05a7cf228 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesClientProviderTest.java
@@ -23,17 +23,15 @@
  */
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
-
 import java.util.function.Consumer;
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.Always;
-import org.junit.Assert;
-import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
 
-public class KubernetesClientProviderTest {
+class KubernetesClientProviderTest {
 
     @Test
-    public void testGetValidity() {
+    void testGetValidity() {
         KubernetesCloud cloud = new KubernetesCloud("foo");
         // changes to these properties should trigger different validity value
         checkValidityChanges(
@@ -60,15 +58,16 @@ public void testGetValidity() {
                 c -> c.setDirectConnection(true));
 
         // verify stability
-        assertEquals(KubernetesClientProvider.getValidity(cloud), KubernetesClientProvider.getValidity(cloud));
+        Assertions.assertEquals(
+                KubernetesClientProvider.getValidity(cloud), KubernetesClientProvider.getValidity(cloud));
     }
 
     private void checkValidityChanges(KubernetesCloud cloud, Consumer... mutations) {
-        checkValidity(cloud, Assert::assertNotEquals, mutations);
+        checkValidity(cloud, Assertions::assertNotEquals, mutations);
     }
 
     private void checkValidityDoesNotChange(KubernetesCloud cloud, Consumer... mutations) {
-        checkValidity(cloud, Assert::assertEquals, mutations);
+        checkValidity(cloud, Assertions::assertEquals, mutations);
     }
 
     private void checkValidity(
@@ -78,12 +77,12 @@ private void checkValidity(
         for (Consumer mut : mutations) {
             mut.accept(cloud);
             int after = KubernetesClientProvider.getValidity(cloud);
-            validityAssertion.doAssert("change #" + count++ + " of " + mutations.length, v, after);
+            validityAssertion.doAssert(v, after, "change #" + count++ + " of " + mutations.length);
             v = after;
         }
     }
 
     interface ValidityAssertion {
-        void doAssert(String message, int before, int after);
+        void doAssert(int before, int after, String message);
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java
index e9c3797356..8602dd6543 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest.java
@@ -4,54 +4,72 @@
 import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.nullValue;
-import static org.junit.Assert.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import hudson.ExtensionList;
 import io.jenkins.cli.shaded.org.apache.commons.io.FileUtils;
-import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.file.Paths;
 import jenkins.security.FIPS140;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.jvnet.hudson.test.FlagRule;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.jvnet.hudson.test.recipes.LocalData;
 
-public class KubernetesCloudFIPSTest {
+@WithJenkins
+class KubernetesCloudFIPSTest {
 
-    @ClassRule
-    public static FlagRule fipsFlag = FlagRule.systemProperty(FIPS140.class.getName() + ".COMPLIANCE", "true");
+    private static String fipsFlag;
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    private JenkinsRule r;
+
+    @BeforeAll
+    static void beforeAll() {
+        fipsFlag = System.setProperty(FIPS140.class.getName() + ".COMPLIANCE", "true");
+    }
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
+    }
+
+    @AfterAll
+    static void afterAll() {
+        if (fipsFlag != null) {
+            System.setProperty(FIPS140.class.getName() + ".COMPLIANCE", fipsFlag);
+        } else {
+            System.clearProperty(FIPS140.class.getName() + ".COMPLIANCE");
+        }
+    }
 
     @Test
     @Issue("JENKINS-73460")
-    public void onlyFipsCompliantValuesAreAcceptedTest() throws IOException {
+    void onlyFipsCompliantValuesAreAcceptedTest() throws Exception {
         KubernetesCloud cloud = new KubernetesCloud("test-cloud");
         assertThrows(IllegalArgumentException.class, () -> cloud.setSkipTlsVerify(true));
         cloud.setSkipTlsVerify(false);
         assertThrows(IllegalArgumentException.class, () -> cloud.setServerUrl("http://example.org"));
         cloud.setServerUrl("https://example.org");
         assertThrows(
-                "Invalid certificates throw exception",
                 IllegalArgumentException.class,
-                () -> cloud.setServerCertificate(getCert("not-a-cert")));
+                () -> cloud.setServerCertificate(getCert("not-a-cert")),
+                "Invalid certificates throw exception");
         Throwable exception = assertThrows(
-                "Invalid length", IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("rsa1024")));
+                IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("rsa1024")), "Invalid length");
         assertThat(exception.getLocalizedMessage(), containsString("2048"));
         cloud.setServerCertificate(getCert("rsa2048"));
         exception = assertThrows(
-                "invalid length", IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("dsa1024")));
+                IllegalArgumentException.class, () -> cloud.setServerCertificate(getCert("dsa1024")), "invalid length");
         assertThat(exception.getLocalizedMessage(), containsString("2048"));
         cloud.setServerCertificate(getCert("dsa2048"));
         exception = assertThrows(
-                "Invalid field size",
                 IllegalArgumentException.class,
-                () -> cloud.setServerCertificate(getCert("ecdsa192")));
+                () -> cloud.setServerCertificate(getCert("ecdsa192")),
+                "Invalid field size");
         assertThat(exception.getLocalizedMessage(), containsString("224"));
         cloud.setServerCertificate(getCert("ecdsa224"));
     }
@@ -59,7 +77,7 @@ public void onlyFipsCompliantValuesAreAcceptedTest() throws IOException {
     @Test
     @Issue("JENKINS-73460")
     @LocalData
-    public void nonCompliantCloudsAreCleanedTest() {
+    void nonCompliantCloudsAreCleanedTest() {
         assertThat("compliant-cloud is loaded", r.jenkins.getCloud("compliant-cloud"), notNullValue());
         assertThat(
                 "no certificate is a valid cloud",
@@ -72,7 +90,7 @@ public void nonCompliantCloudsAreCleanedTest() {
 
     @Test
     @Issue("JENKINS-73460")
-    public void formValidationTest() throws IOException {
+    void formValidationTest() throws Exception {
         ExtensionList descriptors =
                 ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class);
         KubernetesCloud.DescriptorImpl descriptor = descriptors.stream()
@@ -109,7 +127,7 @@ public void formValidationTest() throws IOException {
                 notNullValue());
     }
 
-    private String getCert(String alg) throws IOException {
+    private String getCert(String alg) throws Exception {
         return FileUtils.readFileToString(
                 Paths.get("src/test/resources/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudFIPSTest/certs")
                         .resolve(alg)
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java
index 20a255fbc0..3032d6bf6d 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTest.java
@@ -2,11 +2,7 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.*;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
 import hudson.model.User;
@@ -14,7 +10,6 @@
 import hudson.security.ACLContext;
 import hudson.security.AccessDeniedException3;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -39,31 +34,37 @@
 import org.htmlunit.html.HtmlForm;
 import org.htmlunit.html.HtmlInput;
 import org.htmlunit.html.HtmlPage;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.function.ThrowingRunnable;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.function.Executable;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
 import org.jvnet.hudson.test.MockAuthorizationStrategy;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.jvnet.hudson.test.recipes.LocalData;
 
-public class KubernetesCloudTest {
+@WithJenkins
+class KubernetesCloudTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
 
-    @Rule
-    public LoggerRule logs = new LoggerRule()
+    @SuppressWarnings("unused")
+    private final LogRecorder logs = new LogRecorder()
             .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL);
 
-    @After
-    public void tearDown() {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
+
+    @AfterEach
+    void afterEach() {
         System.getProperties().remove("KUBERNETES_JENKINS_URL");
     }
 
     @Test
-    public void configRoundTrip() throws Exception {
+    void configRoundTrip() throws Exception {
         var cloud = new KubernetesCloud("kubernetes");
         var podTemplate = new PodTemplate();
         podTemplate.setName("test-template");
@@ -77,8 +78,7 @@ public void configRoundTrip() throws Exception {
     }
 
     @Test
-    public void testInheritance() {
-
+    void testInheritance() {
         ContainerTemplate jnlp = new ContainerTemplate("jnlp", "jnlp:1");
         ContainerTemplate maven = new ContainerTemplate("maven", "maven:1");
         maven.setTtyEnabled(true);
@@ -88,26 +88,25 @@ public void testInheritance() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setLabel("parent");
-        parent.setContainers(Arrays.asList(jnlp));
-        parent.setVolumes(Arrays.asList(podVolume));
+        parent.setContainers(List.of(jnlp));
+        parent.setVolumes(List.of(podVolume));
 
         ContainerTemplate maven2 = new ContainerTemplate("maven", "maven:2");
         PodTemplate withNewMavenVersion = new PodTemplate();
-        withNewMavenVersion.setContainers(Arrays.asList(maven2));
+        withNewMavenVersion.setContainers(List.of(maven2));
 
         PodTemplate result = PodTemplateUtils.combine(parent, withNewMavenVersion);
     }
 
-    @Test(expected = IllegalStateException.class)
-    public void getJenkinsUrlOrDie_NoJenkinsUrl() {
+    @Test
+    void getJenkinsUrlOrDie_NoJenkinsUrl() {
         JenkinsLocationConfiguration.get().setUrl(null);
         KubernetesCloud cloud = new KubernetesCloud("name");
-        String url = cloud.getJenkinsUrlOrDie();
-        fail("Should have thrown IllegalStateException at this point but got " + url + " instead.");
+        assertThrows(IllegalStateException.class, () -> cloud.getJenkinsUrlOrDie());
     }
 
     @Test
-    public void getJenkinsUrlOrDie_UrlInCloud() {
+    void getJenkinsUrlOrDie_UrlInCloud() {
         System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocationinsysprop");
         KubernetesCloud cloud = new KubernetesCloud("name");
         cloud.setJenkinsUrl("http://mylocation");
@@ -115,21 +114,21 @@ public void getJenkinsUrlOrDie_UrlInCloud() {
     }
 
     @Test
-    public void getJenkinsUrlOrDie_UrlInSysprop() {
+    void getJenkinsUrlOrDie_UrlInSysprop() {
         System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocation");
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals("http://mylocation/", cloud.getJenkinsUrlOrDie());
     }
 
     @Test
-    public void getJenkinsUrlOrDie_UrlInLocation() {
+    void getJenkinsUrlOrDie_UrlInLocation() {
         JenkinsLocationConfiguration.get().setUrl("http://mylocation");
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals("http://mylocation/", cloud.getJenkinsUrlOrDie());
     }
 
     @Test
-    public void getJenkinsUrlOrNull_NoJenkinsUrl() {
+    void getJenkinsUrlOrNull_NoJenkinsUrl() {
         JenkinsLocationConfiguration.get().setUrl(null);
         KubernetesCloud cloud = new KubernetesCloud("name");
         String url = cloud.getJenkinsUrlOrNull();
@@ -137,7 +136,7 @@ public void getJenkinsUrlOrNull_NoJenkinsUrl() {
     }
 
     @Test
-    public void getJenkinsUrlOrNull_UrlInCloud() {
+    void getJenkinsUrlOrNull_UrlInCloud() {
         System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocationinsysprop");
         KubernetesCloud cloud = new KubernetesCloud("name");
         cloud.setJenkinsUrl("http://mylocation");
@@ -145,27 +144,27 @@ public void getJenkinsUrlOrNull_UrlInCloud() {
     }
 
     @Test
-    public void getJenkinsUrlOrNull_UrlInSysprop() {
+    void getJenkinsUrlOrNull_UrlInSysprop() {
         System.setProperty("KUBERNETES_JENKINS_URL", "http://mylocation");
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals("http://mylocation/", cloud.getJenkinsUrlOrNull());
     }
 
     @Test
-    public void getJenkinsUrlOrNull_UrlInLocation() {
+    void getJenkinsUrlOrNull_UrlInLocation() {
         JenkinsLocationConfiguration.get().setUrl("http://mylocation");
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals("http://mylocation/", cloud.getJenkinsUrlOrNull());
     }
 
     @Test
-    public void testKubernetesCloudDefaults() {
+    void testKubernetesCloudDefaults() {
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals(PodRetention.getKubernetesCloudDefault(), cloud.getPodRetention());
     }
 
     @Test
-    public void testPodLabels() {
+    void testPodLabels() {
         List defaultPodLabelsList = PodLabel.fromMap(KubernetesCloud.DEFAULT_POD_LABELS);
         KubernetesCloud cloud = new KubernetesCloud("name");
         assertEquals(KubernetesCloud.DEFAULT_POD_LABELS, cloud.getPodLabelsMap());
@@ -192,7 +191,7 @@ public void testPodLabels() {
     }
 
     @Test
-    public void testLabels() {
+    void testLabels() {
         KubernetesCloud cloud = new KubernetesCloud("name");
 
         List labels = PodLabel.listOf("foo", "bar", "cat", "dog");
@@ -215,7 +214,7 @@ public void testLabels() {
     }
 
     @Test
-    public void copyConstructor() throws Exception {
+    void copyConstructor() throws Exception {
         PodTemplate pt = new PodTemplate();
         pt.setName("podTemplate");
 
@@ -236,7 +235,7 @@ public void copyConstructor() throws Exception {
                 } else if (propertyType == int.class) {
                     PropertyUtils.setProperty(cloud, property, RandomUtils.nextInt());
                 } else if (propertyType == Integer.class) {
-                    PropertyUtils.setProperty(cloud, property, Integer.valueOf(RandomUtils.nextInt()));
+                    PropertyUtils.setProperty(cloud, property, RandomUtils.nextInt());
                 } else if (propertyType == boolean.class) {
                     PropertyUtils.setProperty(cloud, property, RandomUtils.nextBoolean());
                 } else if (!objectProperties.contains(property)) {
@@ -253,12 +252,12 @@ public void copyConstructor() throws Exception {
         KubernetesCloud copy = new KubernetesCloud("copy", cloud);
         assertEquals("copy", copy.name);
         assertTrue(
-                "Expected cloud from copy constructor to be equal to the source except for name",
-                EqualsBuilder.reflectionEquals(cloud, copy, true, KubernetesCloud.class, "name"));
+                EqualsBuilder.reflectionEquals(cloud, copy, true, KubernetesCloud.class, "name"),
+                "Expected cloud from copy constructor to be equal to the source except for name");
     }
 
     @Test
-    public void defaultWorkspaceVolume() throws Exception {
+    void defaultWorkspaceVolume() throws Exception {
         KubernetesCloud cloud = new KubernetesCloud("kubernetes");
         j.jenkins.clouds.add(cloud);
         j.jenkins.save();
@@ -282,11 +281,11 @@ public void defaultWorkspaceVolume() throws Exception {
         assertEquals("default-workspace", podTemplate.getName());
         p = wc.goTo("cloud/kubernetes/templates");
         DomElement row = p.getElementById("template_" + podTemplate.getId());
-        assertTrue(row != null);
+        assertNotNull(row);
     }
 
     @Test
-    public void minRetentionTimeout() {
+    void minRetentionTimeout() {
         KubernetesCloud cloud = new KubernetesCloud("kubernetes");
         assertEquals(KubernetesCloud.DEFAULT_RETENTION_TIMEOUT_MINUTES, cloud.getRetentionTimeout());
         cloud.setRetentionTimeout(0);
@@ -295,7 +294,7 @@ public void minRetentionTimeout() {
 
     @Test
     @LocalData
-    public void emptyKubernetesCloudReadResolve() {
+    void emptyKubernetesCloudReadResolve() {
         KubernetesCloud cloud = j.jenkins.clouds.get(KubernetesCloud.class);
         assertEquals(KubernetesCloud.DEFAULT_RETENTION_TIMEOUT_MINUTES, cloud.getRetentionTimeout());
         assertEquals(Integer.MAX_VALUE, cloud.getContainerCap());
@@ -306,9 +305,9 @@ public void emptyKubernetesCloudReadResolve() {
 
     @Test
     @LocalData
-    public void readResolveContainerCapZero() {
+    void readResolveContainerCapZero() {
         KubernetesCloud cloud = j.jenkins.clouds.get(KubernetesCloud.class);
-        assertEquals(cloud.getContainerCap(), Integer.MAX_VALUE);
+        assertEquals(Integer.MAX_VALUE, cloud.getContainerCap());
     }
 
     public HtmlInput getInputByName(DomElement root, String name) {
@@ -322,7 +321,7 @@ public HtmlInput getInputByName(DomElement root, String name) {
     }
 
     @Test
-    public void authorization() throws Exception {
+    void authorization() {
         var securityRealm = j.createDummySecurityRealm();
         j.jenkins.setSecurityRealm(securityRealm);
         var authorizationStrategy = new MockAuthorizationStrategy();
@@ -348,10 +347,9 @@ public void authorization() throws Exception {
         }
     }
 
-    private static void assertAccessDenied(ThrowingRunnable throwingRunnable, String expectedMessage) {
+    private static void assertAccessDenied(Executable executable, String expectedMessage) {
         assertThat(
-                assertThrows(AccessDeniedException3.class, throwingRunnable).getMessage(),
-                containsString(expectedMessage));
+                assertThrows(AccessDeniedException3.class, executable).getMessage(), containsString(expectedMessage));
     }
 
     private static @NonNull ACLContext asUser(String admin) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java
index ee3e41dad1..20e2844706 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesCloudTraitTest.java
@@ -2,40 +2,44 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
 import hudson.ExtensionList;
 import java.util.List;
 import java.util.Optional;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.TestExtension;
 import org.jvnet.hudson.test.WithoutJenkins;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.kohsuke.stapler.DataBoundConstructor;
 
-public class KubernetesCloudTraitTest {
+@WithJenkins
+class KubernetesCloudTraitTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @Test
-    public void testKubernetesCloudAll() {
+    void testKubernetesCloudAll() {
         assertEquals(2, KubernetesCloudTrait.all().size());
     }
 
     @Test
-    public void testKubernetesCloudDescriptorAllTraits() {
+    void testKubernetesCloudDescriptorAllTraits() {
         var descriptors = ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class);
         assertThat(descriptors.size(), greaterThanOrEqualTo(1));
         assertEquals(2, descriptors.get(0).getAllTraits().size());
     }
 
     @Test
-    public void testKubernetesCloudDescriptorDefaultTraits() {
+    void testKubernetesCloudDescriptorDefaultTraits() {
         var descriptors = ExtensionList.lookup(KubernetesCloud.DescriptorImpl.class);
         assertThat(descriptors.size(), greaterThanOrEqualTo(1));
         var traits = descriptors.get(0).getDefaultTraits();
@@ -47,7 +51,7 @@ public void testKubernetesCloudDescriptorDefaultTraits() {
 
     @WithoutJenkins
     @Test
-    public void testKubernetesCloudTraits() {
+    void testKubernetesCloudTraits() {
         var cloud = new KubernetesCloud("Foo");
 
         // empty optional when trait instance not found
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java
index 63b1e0b5c9..21f13fdd9b 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFactoryAdapterTest.java
@@ -33,10 +33,7 @@
 import static io.fabric8.kubernetes.client.Config.KUBERNETES_PROXY_USERNAME;
 import static io.fabric8.kubernetes.client.Config.KUBERNETES_SERVICE_HOST_PROPERTY;
 import static io.fabric8.kubernetes.client.Config.KUBERNETES_SERVICE_PORT_PROPERTY;
-import static org.junit.Assert.assertArrayEquals;
-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.*;
 
 import com.cloudbees.plugins.credentials.CredentialsScope;
 import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
@@ -46,19 +43,19 @@
 import io.fabric8.kubernetes.client.KubernetesClient;
 import java.util.HashMap;
 import java.util.Map;
-import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
 /**
  * Test the creation of clients
  */
-public class KubernetesFactoryAdapterTest {
+@WithJenkins
+class KubernetesFactoryAdapterTest {
 
     private static final String[] SYSTEM_PROPERTY_NAMES = new String[] { //
         KUBERNETES_KUBECONFIG_FILE, //
@@ -79,13 +76,14 @@ public class KubernetesFactoryAdapterTest {
     private static final String KUBERNETES_PORT = "443";
     private static final String KUBERNETES_MASTER_URL = "https://" + KUBERNETES_HOST + ":" + KUBERNETES_PORT + "/";
 
-    private Map systemProperties = new HashMap<>();
+    private final Map systemProperties = new HashMap<>();
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
 
-    @Before
-    public void saveSystemProperties() {
         for (String key : SYSTEM_PROPERTY_NAMES) {
             systemProperties.put(key, System.getProperty(key));
             // use bogus values to avoid influence from environment
@@ -102,8 +100,8 @@ public void saveSystemProperties() {
         System.setProperty(KUBERNETES_SERVICE_PORT_PROPERTY, KUBERNETES_PORT);
     }
 
-    @After
-    public void restoreSystemProperties() {
+    @AfterEach
+    void afterEach() {
         for (String key : systemProperties.keySet()) {
             String s = systemProperties.get(key);
             if (s != null) {
@@ -115,7 +113,7 @@ public void restoreSystemProperties() {
     }
 
     @Test
-    public void defaultNamespace() throws Exception {
+    void defaultNamespace() throws Exception {
         KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter(null, null, null, false);
         KubernetesClient client = factory.createClient();
         assertEquals("default", client.getNamespace());
@@ -124,7 +122,7 @@ public void defaultNamespace() throws Exception {
     }
 
     @Test
-    public void autoConfig() throws Exception {
+    void autoConfig() throws Exception {
         System.setProperty(KUBERNETES_NAMESPACE_FILE, "src/test/resources/kubenamespace");
         KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter(null, null, null, false);
         KubernetesClient client = factory.createClient();
@@ -139,7 +137,7 @@ public void autoConfig() throws Exception {
     }
 
     @Test
-    public void autoConfigWithMasterUrl() throws Exception {
+    void autoConfigWithMasterUrl() throws Exception {
         KubernetesFactoryAdapter factory = new KubernetesFactoryAdapter("http://example.com", null, null, false);
         KubernetesClient client = factory.createClient();
         assertEquals(HTTP_PROXY, client.getConfiguration().getHttpProxy());
@@ -153,7 +151,7 @@ public void autoConfigWithMasterUrl() throws Exception {
 
     @Test
     @Issue("JENKINS-70416")
-    public void autoConfigWithAuth() throws Exception {
+    void autoConfigWithAuth() throws Exception {
         System.setProperty(KUBERNETES_NAMESPACE_FILE, "src/test/resources/kubenamespace");
         StringCredentialsImpl tokenCredential = new StringCredentialsImpl(
                 CredentialsScope.GLOBAL, "sa-token", "some credentials", Secret.fromString("sa-token"));
@@ -173,8 +171,7 @@ public void autoConfigWithAuth() throws Exception {
 
     @Test
     @Issue("JENKINS-70563")
-    public void jenkinsProxyConfiguration() throws KubernetesAuthException {
-
+    void jenkinsProxyConfiguration() throws Exception {
         j.jenkins.setProxy(new ProxyConfiguration(
                 "proxy.com", 123, PROXY_USERNAME, PROXY_PASSWORD, "*acme.com\n*acme*.com\n*.example.com|192.168.*"));
         KubernetesFactoryAdapter factory =
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java
index 188a3b233e..0a51a1fddd 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesFolderPropertyTest.java
@@ -8,17 +8,23 @@
 
 import com.cloudbees.hudson.plugins.folder.Folder;
 import java.util.Collections;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class KubernetesFolderPropertyTest {
+@WithJenkins
+class KubernetesFolderPropertyTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @Test
-    public void propertySavedOnFirstSaveTest() throws Exception {
+    void propertySavedOnFirstSaveTest() throws Exception {
         KubernetesCloud kube1 = new KubernetesCloud("kube1");
         kube1.setUsageRestricted(true);
         KubernetesCloud kube2 = new KubernetesCloud("kube2");
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java
index 6e42cb7974..6fe2a3981c 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesProvisioningLimitsTest.java
@@ -1,7 +1,7 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.util.List;
 import java.util.concurrent.CompletionService;
@@ -11,21 +11,27 @@
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class KubernetesProvisioningLimitsTest {
+@WithJenkins
+class KubernetesProvisioningLimitsTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    @SuppressWarnings("unused")
+    private final LogRecorder log = new LogRecorder().record(KubernetesProvisioningLimits.class, Level.FINEST);
 
-    @Rule
-    public LoggerRule log = new LoggerRule().record(KubernetesProvisioningLimits.class, Level.FINEST);
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @Test
-    public void lotsOfCloudsAndTemplates() throws InterruptedException {
+    void lotsOfCloudsAndTemplates() throws Exception {
         ThreadLocalRandom testRandom = ThreadLocalRandom.current();
         for (int i = 1; i < 4; i++) {
             KubernetesCloud cloud = new KubernetesCloud("kubernetes-" + i);
@@ -61,11 +67,7 @@ public void lotsOfCloudsAndTemplates() throws InterruptedException {
                             }
                         }
 
-                        ecs.submit(
-                                () -> {
-                                    kubernetesProvisioningLimits.unregister(cloud, podTemplate, 1);
-                                },
-                                null);
+                        ecs.submit(() -> kubernetesProvisioningLimits.unregister(cloud, podTemplate, 1), null);
                     },
                     null);
         }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java
index 9359711432..a9c6a919f8 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesQueueTaskDispatcherTest.java
@@ -1,6 +1,7 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.mockito.Mockito.when;
 
 import com.cloudbees.hudson.plugins.folder.Folder;
@@ -16,21 +17,18 @@
 import net.sf.json.JSONObject;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepExecution;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.kohsuke.stapler.StaplerRequest2;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
+import org.mockito.junit.jupiter.MockitoExtension;
 
-public class KubernetesQueueTaskDispatcherTest {
-
-    @Rule
-    public JenkinsRule jenkins = new JenkinsRule();
-
-    @Rule
-    public MockitoRule mockitoRule = MockitoJUnit.rule();
+@WithJenkins
+@ExtendWith(MockitoExtension.class)
+class KubernetesQueueTaskDispatcherTest {
 
     @Mock
     private ExecutorStepExecution.PlaceholderTask task;
@@ -40,11 +38,18 @@ public class KubernetesQueueTaskDispatcherTest {
     private KubernetesSlave slaveA;
     private KubernetesSlave slaveB;
 
-    public void setUpTwoClouds() throws Exception {
-        folderA = new Folder(jenkins.jenkins, "A");
-        folderB = new Folder(jenkins.jenkins, "B");
-        jenkins.jenkins.add(folderA, "Folder A");
-        jenkins.jenkins.add(folderB, "Folder B");
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
+
+    private void setUpTwoClouds() throws Exception {
+        folderA = new Folder(j.jenkins, "A");
+        folderB = new Folder(j.jenkins, "B");
+        j.jenkins.add(folderA, "Folder A");
+        j.jenkins.add(folderB, "Folder B");
 
         KubernetesCloud cloudA = new KubernetesCloud("A");
         cloudA.setUsageRestricted(true);
@@ -52,8 +57,8 @@ public void setUpTwoClouds() throws Exception {
         KubernetesCloud cloudB = new KubernetesCloud("B");
         cloudB.setUsageRestricted(true);
 
-        jenkins.jenkins.clouds.add(cloudA);
-        jenkins.jenkins.clouds.add(cloudB);
+        j.jenkins.clouds.add(cloudA);
+        j.jenkins.clouds.add(cloudB);
 
         KubernetesFolderProperty property1 = new KubernetesFolderProperty();
         folderA.addProperty(property1);
@@ -76,7 +81,7 @@ public void setUpTwoClouds() throws Exception {
     }
 
     @Test
-    public void checkRestrictedTwoClouds() throws Exception {
+    void checkRestrictedTwoClouds() throws Exception {
         setUpTwoClouds();
 
         FreeStyleProject projectA = folderA.createProject(FreeStyleProject.class, "buildJob");
@@ -86,23 +91,21 @@ public void checkRestrictedTwoClouds() throws Exception {
         assertNull(dispatcher.canTake(
                 slaveA,
                 new Queue.BuildableItem(new Queue.WaitingItem(Calendar.getInstance(), projectA, new ArrayList<>()))));
-        assertTrue(
-                canTake(dispatcher, slaveB, projectA)
-                        instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed);
-        assertTrue(
-                canTake(dispatcher, slaveA, projectB)
-                        instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed);
+        assertInstanceOf(
+                KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveB, projectA));
+        assertInstanceOf(
+                KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveA, projectB));
         assertNull(canTake(dispatcher, slaveB, projectB));
     }
 
     @Test
-    public void checkNotRestrictedClouds() throws Exception {
-        Folder folder = new Folder(jenkins.jenkins, "C");
+    void checkNotRestrictedClouds() throws Exception {
+        Folder folder = new Folder(j.jenkins, "C");
         FreeStyleProject project = folder.createProject(FreeStyleProject.class, "buildJob");
-        jenkins.jenkins.add(folder, "C");
+        j.jenkins.add(folder, "C");
         KubernetesCloud cloud = new KubernetesCloud("C");
         cloud.setUsageRestricted(false);
-        jenkins.jenkins.clouds.add(cloud);
+        j.jenkins.clouds.add(cloud);
         KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher();
         KubernetesSlave slave = new KubernetesSlave(
                 "C", new PodTemplate(), "testC", "C", "dockerC", new KubernetesLauncher(), RetentionStrategy.INSTANCE);
@@ -111,16 +114,16 @@ public void checkNotRestrictedClouds() throws Exception {
     }
 
     @Test
-    public void checkDumbSlave() throws Exception {
-        DumbSlave slave = jenkins.createOnlineSlave();
-        FreeStyleProject project = jenkins.createProject(FreeStyleProject.class);
+    void checkDumbSlave() throws Exception {
+        DumbSlave slave = j.createOnlineSlave();
+        FreeStyleProject project = j.createProject(FreeStyleProject.class);
         KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher();
 
         assertNull(canTake(dispatcher, slave, project));
     }
 
     @Test
-    public void checkPipelinesRestrictedTwoClouds() throws Exception {
+    void checkPipelinesRestrictedTwoClouds() throws Exception {
         setUpTwoClouds();
 
         WorkflowJob job = folderA.createProject(WorkflowJob.class, "pipeline");
@@ -128,8 +131,8 @@ public void checkPipelinesRestrictedTwoClouds() throws Exception {
         KubernetesQueueTaskDispatcher dispatcher = new KubernetesQueueTaskDispatcher();
 
         assertNull(canTake(dispatcher, slaveA, task));
-        assertTrue(
-                canTake(dispatcher, slaveB, task) instanceof KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed);
+        assertInstanceOf(
+                KubernetesQueueTaskDispatcher.KubernetesCloudNotAllowed.class, canTake(dispatcher, slaveB, task));
     }
 
     private CauseOfBlockage canTake(KubernetesQueueTaskDispatcher dispatcher, Slave slave, Project project) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java
index 8a7ed9a05a..2893f72f2a 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesRestartTest.java
@@ -25,23 +25,23 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
-import org.junit.Rule;
-import org.junit.Test;
-import org.jvnet.hudson.test.JenkinsSessionRule;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension;
 import org.jvnet.hudson.test.recipes.LocalData;
 
-public class KubernetesRestartTest {
+class KubernetesRestartTest {
 
-    @Rule
-    public JenkinsSessionRule s = new JenkinsSessionRule();
+    @RegisterExtension
+    private final JenkinsSessionExtension s = new JenkinsSessionExtension();
 
     @Test
     @LocalData
-    public void upgradeFrom_1_27_1() throws Throwable {
+    void upgradeFrom_1_27_1() throws Throwable {
         AtomicReference podTemplateId = new AtomicReference<>();
         AtomicReference toString = new AtomicReference<>();
         s.then(r -> {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
index 1d1f406455..508dd5a8db 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesSlaveTest.java
@@ -26,10 +26,9 @@
 
 import static java.util.Map.entry;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.assertRegex;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
-import hudson.model.Descriptor;
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.client.dsl.PodResource;
 import java.io.IOException;
@@ -46,23 +45,29 @@
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.PodRetention;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.PodVolume;
 import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.WithoutJenkins;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.mockito.Mockito;
 
 /**
  * @author Carlos Sanchez
  */
-public class KubernetesSlaveTest {
+@WithJenkins
+class KubernetesSlaveTest {
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    private JenkinsRule r;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
+    }
 
     @WithoutJenkins
     @Test
-    public void testGetSlaveName() {
+    void testGetSlaveName() {
         List extends PodVolume> volumes = Collections.emptyList();
         List containers = Collections.emptyList();
 
@@ -80,7 +85,7 @@ public void testGetSlaveName() {
     }
 
     @Test
-    public void testGetPod() throws Exception {
+    void testGetPod() throws Exception {
         Map testCases = Map.ofEntries(
                 entry("assigned", (KubernetesCloud cloud, KubernetesSlave slave, PodResource podResource) -> {
                     Pod p = new Pod();
@@ -165,8 +170,8 @@ private interface GetPodTestCase {
     }
 
     @Test
-    public void testGetPodRetention() {
-        try {
+    void testGetPodRetention() {
+        assertDoesNotThrow(() -> {
             List> cases = Arrays.asList(
                     createPodRetentionTestCase(new Never(), new Default(), new Default()),
                     createPodRetentionTestCase(new Never(), new Always(), new Always()),
@@ -191,9 +196,7 @@ public void testGetPodRetention() {
                 KubernetesSlave testSlave = testCase.buildSubject(cloud);
                 assertEquals(testCase.getExpectedResult(), testSlave.getPodRetention(cloud));
             }
-        } catch (IOException | Descriptor.FormException e) {
-            fail(e.getMessage());
-        }
+        });
     }
 
     private KubernetesSlaveTestCase createPodRetentionTestCase(
@@ -212,7 +215,7 @@ public static class KubernetesSlaveTestCase {
         private String podPhase;
         private T expectedResult;
 
-        public KubernetesSlave buildSubject(KubernetesCloud cloud) throws IOException, Descriptor.FormException {
+        public KubernetesSlave buildSubject(KubernetesCloud cloud) throws Exception {
             return new KubernetesSlave.Builder()
                     .cloud(cloud)
                     .podTemplate(podTemplate)
@@ -269,7 +272,7 @@ public KubernetesSlaveTestCase build() {
             testTemplate.setPodRetention(templatePodRetention);
             testTemplate.setName("test-template");
             testTemplate.setLabel("test-template");
-            testTemplate.setContainers(Arrays.asList(testContainer));
+            testTemplate.setContainers(List.of(testContainer));
 
             KubernetesSlaveTestCase testCase = new KubernetesSlaveTestCase<>();
             testCase.cloudPodRetention = cloudPodRetention;
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java
index 8a7d9a86f3..5494ad050b 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTest.java
@@ -26,11 +26,7 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 
 import com.cloudbees.plugins.credentials.Credentials;
 import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
@@ -55,12 +51,12 @@
 import org.csanchez.jenkins.plugins.kubernetes.volumes.HostPathVolume;
 import org.jenkinsci.plugins.kubernetes.credentials.FileSystemServiceAccountCredential;
 import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.jvnet.hudson.test.recipes.LocalData;
 
 /**
@@ -68,25 +64,25 @@
  * @since 0.9
  *
  */
-public class KubernetesTest {
+@WithJenkins
+class KubernetesTest {
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
-
-    @Rule
-    public LoggerRule log = new LoggerRule();
+    private final LogRecorder log = new LogRecorder();
 
     private KubernetesCloud cloud;
 
-    @Before
-    public void before() throws Exception {
+    private JenkinsRule r;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
         cloud = r.jenkins.clouds.get(KubernetesCloud.class);
         assertNotNull(cloud);
     }
 
     @Test
     @LocalData()
-    public void upgradeFrom_1_17_2() throws Exception {
+    void upgradeFrom_1_17_2() {
         Map labels = cloud.getPodLabelsMap();
         assertEquals(2, labels.size());
         assertThat(cloud.getPodLabelsMap(), hasEntry("jenkins", "slave"));
@@ -101,7 +97,7 @@ public void upgradeFrom_1_17_2() throws Exception {
 
     @Test
     @LocalData
-    public void upgradeFrom_1_15_9() {
+    void upgradeFrom_1_15_9() {
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
         PodTemplate template = templates.get(0);
@@ -112,7 +108,7 @@ public void upgradeFrom_1_15_9() {
 
     @Test
     @LocalData
-    public void upgradeFrom_1_15_9_invalid() {
+    void upgradeFrom_1_15_9_invalid() {
         log.record(PodTemplate.class, Level.WARNING).capture(1);
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
@@ -127,7 +123,7 @@ public void upgradeFrom_1_15_9_invalid() {
     @Test
     @LocalData()
     @Issue("JENKINS-57116")
-    public void upgradeFrom_1_15_1() throws Exception {
+    void upgradeFrom_1_15_1() {
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
         PodTemplate template = templates.get(0);
@@ -137,7 +133,7 @@ public void upgradeFrom_1_15_1() throws Exception {
 
     @Test
     @LocalData()
-    public void upgradeFrom_1_10() throws Exception {
+    void upgradeFrom_1_10() {
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
         assertEquals(new Never(), cloud.getPodRetention());
@@ -151,7 +147,7 @@ public void upgradeFrom_1_10() throws Exception {
 
     @Test
     @LocalData()
-    public void upgradeFrom_1_1() throws Exception {
+    void upgradeFrom_1_1() {
         List credentials = SystemCredentialsProvider.getInstance().getCredentials();
         assertEquals(3, credentials.size());
         UsernamePasswordCredentialsImpl cred0 = (UsernamePasswordCredentialsImpl) credentials.get(0);
@@ -166,7 +162,7 @@ public void upgradeFrom_1_1() throws Exception {
 
     @Test
     @LocalData()
-    public void upgradeFrom_0_12() throws Exception {
+    void upgradeFrom_0_12() {
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
         PodTemplate template = templates.get(0);
@@ -180,7 +176,7 @@ public void upgradeFrom_0_12() throws Exception {
 
     @Test
     @LocalData()
-    public void upgradeFrom_0_10() throws Exception {
+    void upgradeFrom_0_10() {
         List templates = cloud.getTemplates();
         PodTemplate template = templates.get(0);
         DescribableList, NodePropertyDescriptor> nodeProperties = template.getNodeProperties();
@@ -196,7 +192,7 @@ public void upgradeFrom_0_10() throws Exception {
 
     @Test
     @LocalData()
-    public void upgradeFrom_0_8() throws Exception {
+    void upgradeFrom_0_8() {
         List templates = cloud.getTemplates();
         assertPodTemplates(templates);
         assertEquals(cloud.DEFAULT_WAIT_FOR_POD_SEC, cloud.getWaitForPodSec());
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java
index 590bdb90fb..89a397eade 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/KubernetesTestUtil.java
@@ -26,10 +26,9 @@
 import static java.util.logging.Level.FINE;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeNoException;
-import static org.junit.Assume.assumeTrue;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import edu.umd.cs.findbugs.annotations.CheckForNull;
 import hudson.Util;
@@ -42,7 +41,6 @@
 import io.fabric8.kubernetes.client.KubernetesClientBuilder;
 import io.fabric8.kubernetes.client.KubernetesClientException;
 import io.fabric8.kubernetes.client.utils.Serialization;
-import java.io.IOException;
 import java.net.InetAddress;
 import java.net.URL;
 import java.util.Collections;
@@ -60,11 +58,9 @@
 import jenkins.model.JenkinsLocationConfiguration;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
-import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
-import org.junit.rules.TestName;
 import org.jvnet.hudson.test.JenkinsRule;
 
 public class KubernetesTestUtil {
@@ -83,7 +79,7 @@ public class KubernetesTestUtil {
 
     public static final String WINDOWS_1809_BUILD = "10.0.17763";
 
-    public static KubernetesCloud setupCloud(Object test, TestName name) throws KubernetesAuthException, IOException {
+    public static KubernetesCloud setupCloud(Object test, String name) throws Exception {
         KubernetesCloud cloud = new KubernetesCloud("kubernetes");
         // unique labels per test
         cloud.setPodLabels(PodLabel.fromMap(getLabels(cloud, test, name)));
@@ -141,11 +137,11 @@ public static void setupHost(KubernetesCloud cloud) throws Exception {
         }
     }
 
-    public static void assumeKubernetes() throws Exception {
+    public static void assumeKubernetes() {
         try (KubernetesClient client = new KubernetesClientBuilder().build()) {
             client.pods().list();
         } catch (Exception e) {
-            assumeNoException(e);
+            assumeTrue(false, e.toString());
         }
     }
 
@@ -156,7 +152,7 @@ public static void assumeKubernetes() throws Exception {
      * Note that running the controller on Windows is untested.
      */
     public static void assumeWindows(String buildNumber) {
-        assumeTrue("Cluster seems to contain no Windows nodes with build " + buildNumber, isWindows(buildNumber));
+        assumeTrue(isWindows(buildNumber), "Cluster seems to contain no Windows nodes with build " + buildNumber);
     }
 
     public static boolean isWindows(@CheckForNull String buildNumber) {
@@ -177,14 +173,14 @@ public static boolean isWindows(@CheckForNull String buildNumber) {
         return false;
     }
 
-    public static Map getLabels(Object o, TestName name) {
+    public static Map getLabels(Object o, String name) {
         return getLabels(null, o, name);
     }
 
     /**
      * Labels to add to the pods so we can match them to a specific build run, test class and method
      */
-    public static Map getLabels(KubernetesCloud cloud, Object o, TestName name) {
+    public static Map getLabels(KubernetesCloud cloud, Object o, String name) {
         Map l = new HashMap<>();
         l.put("BRANCH_NAME", BRANCH_NAME == null ? "undefined" : BRANCH_NAME);
         l.put("BUILD_NUMBER", BUILD_NUMBER == null ? "undefined" : BUILD_NUMBER);
@@ -192,7 +188,7 @@ public static Map getLabels(KubernetesCloud cloud, Object o, Tes
             l.putAll(cloud.getPodLabelsMap());
         }
         l.put("class", o.getClass().getSimpleName());
-        l.put("test", name.getMethodName());
+        l.put("test", name);
         return l;
     }
 
@@ -245,7 +241,7 @@ public static boolean deletePods(KubernetesClient client, Map la
             PodList list = client.pods().withLabels(labels).list();
             if (!list.getItems().isEmpty()) {
                 LOGGER.log(WARNING, "Deleting leftover pods: {0}", print(list));
-                return client.pods().withLabels(labels).delete().size() > 0;
+                return !client.pods().withLabels(labels).delete().isEmpty();
             }
         }
         return false;
@@ -320,6 +316,6 @@ public static String loadPipelineScript(Class> clazz, String name) {
 
     public static void assertRegex(String name, String regex) {
         assertNotNull(name);
-        assertTrue(String.format("Name does not match regex [%s]: '%s'", regex, name), name.matches(regex));
+        assertTrue(name.matches(regex), String.format("Name does not match regex [%s]: '%s'", regex, name));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java
index 6856045815..efc1f17629 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/MetricNamesTest.java
@@ -1,31 +1,32 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import org.junit.Assert;
-import org.junit.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-public class MetricNamesTest {
+import org.junit.jupiter.api.Test;
+
+class MetricNamesTest {
 
     @Test
-    public void metricNameForPodStatusAddsNullWhenStatusIsNull() {
+    void metricNameForPodStatusAddsNullWhenStatusIsNull() {
         String expected = "kubernetes.cloud.pods.launch.status.null";
         String actual = MetricNames.metricNameForPodStatus(null);
 
-        Assert.assertEquals(expected, actual);
+        assertEquals(expected, actual);
     }
 
     @Test
-    public void metricNameForPodStatusAddsStatusValueIfNotNull() {
+    void metricNameForPodStatusAddsStatusValueIfNotNull() {
         String expected = "kubernetes.cloud.pods.launch.status.running";
         String actual = MetricNames.metricNameForPodStatus("RUNNING");
 
-        Assert.assertEquals(expected, actual);
+        assertEquals(expected, actual);
     }
 
     @Test
-    public void metricNameForPodStatusChangeStatusToLowercase() {
+    void metricNameForPodStatusChangeStatusToLowercase() {
         String expected = "kubernetes.cloud.pods.launch.status.failed";
         String actual = MetricNames.metricNameForPodStatus("FaIlEd");
 
-        Assert.assertEquals(expected, actual);
+        assertEquals(expected, actual);
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java
index dbb00cbc44..4f4e946424 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/NonConfigurableKubernetesCloudTest.java
@@ -1,29 +1,35 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class NonConfigurableKubernetesCloudTest {
+@WithJenkins
+class NonConfigurableKubernetesCloudTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
-
-    @Rule
-    public LoggerRule logs = new LoggerRule()
+    @SuppressWarnings("unused")
+    private final LogRecorder logs = new LogRecorder()
             .record(
                     Logger.getLogger(NonConfigurableKubernetesCloudTest.class
                             .getPackage()
                             .getName()),
                     Level.ALL);
 
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
+
     @Test
-    public void configRoundTrip() throws Exception {
+    void configRoundTrip() throws Exception {
         // create a cloud with a template
         var cloud = new KubernetesCloud("kubernetes");
         var podTemplate = new PodTemplate();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java
index 34ad1bc0cd..dc899d41d6 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodContainerSourceTest.java
@@ -1,6 +1,6 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
 import io.fabric8.kubernetes.api.model.ContainerStatus;
@@ -10,19 +10,25 @@
 import io.fabric8.kubernetes.api.model.PodStatus;
 import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.TestExtension;
 import org.jvnet.hudson.test.WithoutJenkins;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodContainerSourceTest {
+@WithJenkins
+class PodContainerSourceTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @Test
-    public void lookupContainerWorkingDir() {
+    void lookupContainerWorkingDir() {
         Pod pod = new PodBuilder()
                 .withNewSpec()
                 .addNewContainer()
@@ -55,7 +61,7 @@ public void lookupContainerWorkingDir() {
     }
 
     @Test
-    public void lookupContainerStatus() {
+    void lookupContainerStatus() {
         Pod pod = new PodBuilder()
                 .withNewStatus()
                 .addNewContainerStatus()
@@ -91,7 +97,7 @@ public void lookupContainerStatus() {
 
     @WithoutJenkins
     @Test
-    public void defaultPodContainerSourceGetContainerWorkingDir() {
+    void defaultPodContainerSourceGetContainerWorkingDir() {
         Pod pod = new PodBuilder()
                 .withNewSpec()
                 .addNewContainer()
@@ -121,7 +127,7 @@ public void defaultPodContainerSourceGetContainerWorkingDir() {
 
     @WithoutJenkins
     @Test
-    public void defaultPodContainerSourceGetContainerStatus() {
+    void defaultPodContainerSourceGetContainerStatus() {
         Pod pod = new PodBuilder()
                 .withNewStatus()
                 .addNewContainerStatus()
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java
index a83457e8ed..126ca60ecb 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodEnvVarTest.java
@@ -24,15 +24,15 @@
 
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class PodEnvVarTest {
+class PodEnvVarTest {
 
     @Test
-    public void testEquals() {
+    void testEquals() {
         assertEquals(new PodEnvVar("a", "b"), new KeyValueEnvVar("a", "b"));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java
index 84b4fac6b5..9a79bbad71 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateBuilderTest.java
@@ -1,14 +1,10 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static java.util.stream.Collectors.toList;
 import static org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder.*;
 import static org.csanchez.jenkins.plugins.kubernetes.PodTemplateUtils.*;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
 import io.fabric8.kubernetes.api.model.Container;
@@ -20,7 +16,6 @@
 import io.fabric8.kubernetes.api.model.Volume;
 import io.fabric8.kubernetes.api.model.VolumeMount;
 import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -32,9 +27,6 @@
 import java.util.logging.Logger;
 import java.util.stream.Collectors;
 import jenkins.model.Jenkins;
-import junitparams.JUnitParamsRunner;
-import junitparams.Parameters;
-import junitparams.naming.TestCaseName;
 import org.apache.commons.io.IOUtils;
 import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar;
@@ -48,40 +40,39 @@
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume;
 import org.hamcrest.Matcher;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.jvnet.hudson.test.FlagRule;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.mockito.Mock;
 import org.mockito.Spy;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
 
-@RunWith(JUnitParamsRunner.class)
-public class PodTemplateBuilderTest {
+@WithJenkins
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class PodTemplateBuilderTest {
 
     private static final String AGENT_NAME = "jenkins-agent";
     private static final String AGENT_SECRET = "xxx";
     private static final String JENKINS_URL = "http://jenkins.example.com";
     private static final String JENKINS_PROTOCOLS = "JNLP4-connect";
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    private JenkinsRule r;
 
-    @Rule
-    public MockitoRule mockitoRule = MockitoJUnit.rule();
-
-    @Rule
-    public LoggerRule logs = new LoggerRule()
+    @SuppressWarnings("unused")
+    private final LogRecorder logs = new LogRecorder()
             .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL);
 
-    @Rule
-    public FlagRule dockerPrefix = new FlagRule<>(
-            () -> DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX, prefix -> DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = prefix);
+    private String dockerPrefix;
 
     @Spy
     private KubernetesCloud cloud = new KubernetesCloud("test");
@@ -92,15 +83,21 @@ public class PodTemplateBuilderTest {
     @Mock
     private KubernetesComputer computer;
 
-    @Before
-    public void setUp() {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
         when(slave.getKubernetesCloud()).thenReturn(cloud);
+        dockerPrefix = DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX;
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testBuildFromYaml(boolean directConnection) throws Exception {
+    @AfterEach
+    void afterEach() {
+        DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = dockerPrefix;
+    }
+
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testBuildFromYaml(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         PodTemplate template = new PodTemplate();
         template.setYaml(loadYamlFile("pod-busybox.yaml"));
@@ -121,7 +118,7 @@ public void testBuildFromYaml(boolean directConnection) throws Exception {
     }
 
     @Test
-    public void testBuildJnlpFromYamlWithNullEnv() throws Exception {
+    void testBuildJnlpFromYamlWithNullEnv() throws Exception {
         PodTemplate template = new PodTemplate();
         template.setYaml(loadYamlFile("pod-jnlp-nullenv.yaml"));
         Pod pod = new PodTemplateBuilder(template, slave).build();
@@ -134,7 +131,7 @@ public void testBuildJnlpFromYamlWithNullEnv() throws Exception {
 
     @Test
     @Issue("JENKINS-71639")
-    public void testInjectRestrictedPssSecurityContextInJnlp() throws Exception {
+    void testInjectRestrictedPssSecurityContextInJnlp() throws Exception {
         cloud.setRestrictedPssSecurityContext(true);
         PodTemplate template = new PodTemplate();
         template.setYaml(loadYamlFile("pod-busybox.yaml"));
@@ -156,7 +153,7 @@ public void testInjectRestrictedPssSecurityContextInJnlp() throws Exception {
     }
 
     @Test
-    public void testValidateDockerRegistryUIOverride() throws Exception {
+    void testValidateDockerRegistryUIOverride() throws Exception {
         final String jnlpregistry = "registry.example.com";
         cloud.setJnlpregistry(jnlpregistry);
         DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; // should be ignored
@@ -175,7 +172,7 @@ public void testValidateDockerRegistryUIOverride() throws Exception {
     }
 
     @Test
-    public void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Exception {
+    void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Exception {
         final String jnlpregistry = "registry.example.com/";
         cloud.setJnlpregistry(jnlpregistry);
         DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub"; // should be ignored
@@ -192,10 +189,9 @@ public void testValidateDockerRegistryUIOverrideWithSlashSuffix() throws Excepti
         assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave"));
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testValidateDockerRegistryPrefixOverride(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testValidateDockerRegistryPrefixOverride(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub";
         PodTemplate template = new PodTemplate();
@@ -213,10 +209,9 @@ public void testValidateDockerRegistryPrefixOverride(boolean directConnection) t
         assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave"));
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub/";
         PodTemplate template = new PodTemplate();
@@ -234,10 +229,9 @@ public void testValidateDockerRegistryPrefixOverrideWithSlashSuffix(boolean dire
         assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave"));
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         DEFAULT_JNLP_DOCKER_REGISTRY_PREFIX = "jenkins.docker.com/docker-hub";
         PodTemplate template = new PodTemplate();
@@ -264,7 +258,7 @@ public void testValidateDockerRegistryPrefixOverrideForInitContainer(boolean dir
 
     @Test
     @Issue("JENKINS-50525")
-    public void testBuildWithCustomWorkspaceVolume() throws Exception {
+    void testBuildWithCustomWorkspaceVolume() {
         PodTemplate template = new PodTemplate();
         var workspaceVolume = new EmptyDirWorkspaceVolume(true);
         workspaceVolume.setSizeLimit("1Gi");
@@ -293,7 +287,7 @@ public void testBuildWithCustomWorkspaceVolume() throws Exception {
     }
 
     @Test
-    public void testBuildWithDynamicPVCWorkspaceVolume() {
+    void testBuildWithDynamicPVCWorkspaceVolume() {
         PodTemplate template = new PodTemplate();
         template.setWorkspaceVolume(new DynamicPVCWorkspaceVolume());
         ContainerTemplate containerTemplate = new ContainerTemplate("name", "image");
@@ -316,10 +310,9 @@ public void testBuildWithDynamicPVCWorkspaceVolume() {
         assertNotNull(pod.getSpec().getVolumes().get(0).getPersistentVolumeClaim());
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testBuildFromTemplate(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testBuildFromTemplate(boolean directConnection) {
         cloud.setDirectConnection(directConnection);
         PodTemplate template = new PodTemplate();
         template.setRunAsUser("1000");
@@ -328,16 +321,16 @@ public void testBuildFromTemplate(boolean directConnection) throws Exception {
 
         template.setHostNetwork(false);
 
-        List volumes = new ArrayList();
+        List volumes = new ArrayList<>();
         volumes.add(new HostPathVolume("/host/data", "/container/data", false));
         volumes.add(new EmptyDirVolume("/empty/dir", false));
         template.setVolumes(volumes);
 
-        List containers = new ArrayList();
+        List containers = new ArrayList<>();
         ContainerTemplate busyboxContainer = new ContainerTemplate("busybox", "busybox");
         busyboxContainer.setCommand("cat");
         busyboxContainer.setTtyEnabled(true);
-        List envVars = new ArrayList();
+        List envVars = new ArrayList<>();
         envVars.add(new KeyValueEnvVar("CONTAINER_ENV_VAR", "container-env-var-value"));
         busyboxContainer.setEnvVars(envVars);
         busyboxContainer.setRunAsUser("2000");
@@ -349,7 +342,7 @@ public void testBuildFromTemplate(boolean directConnection) throws Exception {
         Pod pod = new PodTemplateBuilder(template, slave).build();
         pod.getMetadata().setLabels(Collections.singletonMap("some-label", "some-label-value"));
         validatePod(pod, false, directConnection);
-        ArrayList supplementalGroups = new ArrayList();
+        ArrayList supplementalGroups = new ArrayList<>();
         supplementalGroups.add(5001L);
         supplementalGroups.add(5002L);
 
@@ -452,7 +445,7 @@ private void validateContainers(Pod pod, KubernetesSlave slave, boolean directCo
                 validateJnlpContainer(c, slave, directConnection);
             } else {
                 List env = c.getEnv();
-                assertThat(env.stream().map(EnvVar::getName).collect(toList()), everyItem(not(isIn(exclusions))));
+                assertThat(env.stream().map(EnvVar::getName).toList(), everyItem(not(is(in(exclusions)))));
             }
         }
     }
@@ -484,11 +477,11 @@ private void validateJnlpContainer(Container jnlp, KubernetesSlave slave, boolea
         } else {
             assertThat(jnlp.getArgs(), empty());
         }
-        assertThat(jnlp.getEnv(), containsInAnyOrder(envVars.toArray(new EnvVar[envVars.size()])));
+        assertThat(jnlp.getEnv(), containsInAnyOrder(envVars.toArray(new EnvVar[0])));
     }
 
     @Test
-    public void namespaceFromCloud() {
+    void namespaceFromCloud() {
         when(cloud.getNamespace()).thenReturn("cloud-namespace");
         PodTemplate template = new PodTemplate();
         Pod pod = new PodTemplateBuilder(template, slave).build();
@@ -496,7 +489,7 @@ public void namespaceFromCloud() {
     }
 
     @Test
-    public void namespaceFromTemplate() {
+    void namespaceFromTemplate() {
         when(cloud.getNamespace()).thenReturn("cloud-namespace");
         PodTemplate template = new PodTemplate();
         template.setNamespace("template-namespace");
@@ -505,7 +498,7 @@ public void namespaceFromTemplate() {
     }
 
     @Test
-    public void defaultRequests() throws Exception {
+    void defaultRequests() {
         PodTemplate template = new PodTemplate();
         Pod pod = new PodTemplateBuilder(template, slave).build();
         ResourceRequirements resources = pod.getSpec().getContainers().get(0).getResources();
@@ -517,10 +510,9 @@ public void defaultRequests() throws Exception {
                 PodTemplateBuilder.DEFAULT_JNLP_CONTAINER_MEMORY_REQUEST, requests.get("memory"));
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testOverridesFromYaml(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testOverridesFromYaml(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         PodTemplate template = new PodTemplate();
         template.setNamespace("template-namespace");
@@ -548,10 +540,9 @@ public void testOverridesFromYaml(boolean directConnection) throws Exception {
      * child ones. Then the fields override what is defined in the yaml, so in effect the parent resource limits and
      * requests are used.
      */
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testInheritsFromWithYaml(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testInheritsFromWithYaml(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         PodTemplate parent = new PodTemplate();
         ContainerTemplate container1 = new ContainerTemplate("jnlp", "image1");
@@ -561,7 +552,7 @@ public void testInheritsFromWithYaml(boolean directConnection) throws Exception
         container1.setResourceRequestMemory("156Mi");
         container1.setRunAsUser("1000");
         container1.setRunAsGroup("2000");
-        parent.setContainers(Arrays.asList(container1));
+        parent.setContainers(List.of(container1));
 
         PodTemplate template = new PodTemplate();
         template.setYaml(loadYamlFile("pod-overrides.yaml"));
@@ -587,14 +578,17 @@ public void testInheritsFromWithYaml(boolean directConnection) throws Exception
     }
 
     @Test
-    public void inheritYamlMergeStrategy() throws Exception {
+    void inheritYamlMergeStrategy() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "spec:\n"
-                + "  tolerations:\n"
-                + "  - key: \"reservedFor\"\n"
-                + "    operator: Exists\n"
-                + "    effect: NoSchedule");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                spec:
+                  tolerations:
+                  - key: "reservedFor"
+                    operator: Exists
+                    effect: NoSchedule""");
 
         PodTemplate child = new PodTemplate();
         child.setYaml("spec:\n");
@@ -643,27 +637,35 @@ public void inheritYamlMergeStrategy() throws Exception {
     }
 
     @Test
-    public void yamlMergeContainers() throws Exception {
+    void yamlMergeContainers() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  containers:\n"
-                + "  - name: container1\n"
-                + "    image: busybox\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  containers:
+                  - name: container1
+                    image: busybox
+                    command:
+                    - cat
+                    tty: true
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  containers:\n"
-                + "  - name: container2\n"
-                + "    image: busybox\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        child.setYaml(
+                """
+                spec:
+                  containers:
+                  - name: container2
+                    image: busybox
+                    command:
+                    - cat
+                    tty: true
+                """);
         child.setYamlMergeStrategy(merge());
         child.setInheritFrom("parent");
         setupStubs();
@@ -682,27 +684,35 @@ public void yamlMergeContainers() throws Exception {
     }
 
     @Test
-    public void yamlOverrideContainer() throws Exception {
+    void yamlOverrideContainer() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  containers:\n"
-                + "  - name: container\n"
-                + "    image: busybox\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  containers:
+                  - name: container
+                    image: busybox
+                    command:
+                    - cat
+                    tty: true
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  containers:\n"
-                + "  - name: container\n"
-                + "    image: busybox2\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        child.setYaml(
+                """
+                spec:
+                  containers:
+                  - name: container
+                    image: busybox2
+                    command:
+                    - cat
+                    tty: true
+                """);
         child.setInheritFrom("parent");
         child.setYamlMergeStrategy(merge());
         setupStubs();
@@ -719,24 +729,32 @@ public void yamlOverrideContainer() throws Exception {
 
     @Issue("JENKINS-58374")
     @Test
-    public void yamlOverrideContainerEnvvar() throws Exception {
+    void yamlOverrideContainerEnvvar() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("kind: Pod\n" + "spec:\n"
-                + "  containers:\n"
-                + "  - name: jnlp\n"
-                + "    env:\n"
-                + "    - name: VAR1\n"
-                + "      value: \"1\"\n"
-                + "    - name: VAR2\n"
-                + "      value: \"1\"\n");
+        parent.setYaml(
+                """
+                kind: Pod
+                spec:
+                  containers:
+                  - name: jnlp
+                    env:
+                    - name: VAR1
+                      value: "1"
+                    - name: VAR2
+                      value: "1"
+                """);
         PodTemplate child = new PodTemplate();
         child.setYamlMergeStrategy(merge());
-        child.setYaml("kind: Pod\n" + "spec:\n"
-                + "  containers:\n"
-                + "  - name: jnlp\n"
-                + "    env:\n"
-                + "    - name: VAR1\n"
-                + "      value: \"2\"\n");
+        child.setYaml(
+                """
+                kind: Pod
+                spec:
+                  containers:
+                  - name: jnlp
+                    env:
+                    - name: VAR1
+                      value: "2"
+                """);
         setupStubs();
 
         PodTemplate result = combine(parent, child);
@@ -752,29 +770,37 @@ public void yamlOverrideContainerEnvvar() throws Exception {
     }
 
     @Test
-    public void yamlOverrideVolume() throws Exception {
+    void yamlOverrideVolume() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  containers:\n"
-                + "  - name: jnlp\n"
-                + "    volumeMounts:\n"
-                + "    - name: host-volume\n"
-                + "      mountPath: /etc/config\n"
-                + "      subPath: mypath\n"
-                + "  volumes:\n"
-                + "  - name: host-volume\n"
-                + "    hostPath:\n"
-                + "      path: /host/data\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  containers:
+                  - name: jnlp
+                    volumeMounts:
+                    - name: host-volume
+                      mountPath: /etc/config
+                      subPath: mypath
+                  volumes:
+                  - name: host-volume
+                    hostPath:
+                      path: /host/data
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  volumes:\n"
-                + "  - name: host-volume\n"
-                + "    hostPath:\n"
-                + "      path: /host/data2\n");
+        child.setYaml(
+                """
+                spec:
+                  volumes:
+                  - name: host-volume
+                    hostPath:
+                      path: /host/data2
+                """);
         child.setContainers(Collections.singletonList(new ContainerTemplate("jnlp", "image")));
         ConfigMapVolume cmVolume = new ConfigMapVolume("/etc/configmap", "my-configmap", false);
         cmVolume.setSubPath("subpath");
@@ -810,35 +836,43 @@ public void yamlOverrideVolume() throws Exception {
     }
 
     @Test
-    public void yamlOverrideHostNetwork() {
+    void yamlOverrideHostNetwork() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  hostNetwork: false\n"
-                + "  containers:\n"
-                + "  - name: container\n"
-                + "    securityContext:\n"
-                + "      runAsUser: 1000\n"
-                + "      runAsGroup: 1000\n"
-                + "    image: busybox\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  hostNetwork: false
+                  containers:
+                  - name: container
+                    securityContext:
+                      runAsUser: 1000
+                      runAsGroup: 1000
+                    image: busybox
+                    command:
+                    - cat
+                    tty: true
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  hostNetwork: true\n"
-                + "  containers:\n"
-                + "  - name: container\n"
-                + "    image: busybox2\n"
-                + "    securityContext:\n"
-                + "      runAsUser: 2000\n"
-                + "      runAsGroup: 2000\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        child.setYaml(
+                """
+                spec:
+                  hostNetwork: true
+                  containers:
+                  - name: container
+                    image: busybox2
+                    securityContext:
+                      runAsUser: 2000
+                      runAsGroup: 2000
+                    command:
+                    - cat
+                    tty: true
+                """);
         child.setInheritFrom("parent");
         child.setYamlMergeStrategy(merge());
         PodTemplate result = combine(parent, child);
@@ -847,17 +881,24 @@ public void yamlOverrideHostNetwork() {
     }
 
     @Test
-    public void yamlOverrideSchedulerName() {
+    void yamlOverrideSchedulerName() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  schedulerName: default-scheduler\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  schedulerName: default-scheduler
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  schedulerName: custom-scheduler\n");
+        child.setYaml("""
+                spec:
+                  schedulerName: custom-scheduler
+                """);
         child.setInheritFrom("parent");
         child.setYamlMergeStrategy(merge());
         PodTemplate result = combine(parent, child);
@@ -866,39 +907,47 @@ public void yamlOverrideSchedulerName() {
     }
 
     @Test
-    public void yamlOverrideSecurityContext() {
+    void yamlOverrideSecurityContext() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  securityContext:\n"
-                + "    runAsUser: 2000\n"
-                + "    runAsGroup: 2000\n"
-                + "  containers:\n"
-                + "  - name: container\n"
-                + "    securityContext:\n"
-                + "      runAsUser: 1000\n"
-                + "      runAsGroup: 1000\n"
-                + "    image: busybox\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  securityContext:
+                    runAsUser: 2000
+                    runAsGroup: 2000
+                  containers:
+                  - name: container
+                    securityContext:
+                      runAsUser: 1000
+                      runAsGroup: 1000
+                    image: busybox
+                    command:
+                    - cat
+                    tty: true
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  securityContext:\n"
-                + "    runAsUser: 3000\n"
-                + "    runAsGroup: 3000\n"
-                + "  containers:\n"
-                + "  - name: container\n"
-                + "    image: busybox2\n"
-                + "    securityContext:\n"
-                + "      runAsUser: 2000\n"
-                + "      runAsGroup: 2000\n"
-                + "    command:\n"
-                + "    - cat\n"
-                + "    tty: true\n");
+        child.setYaml(
+                """
+                spec:
+                  securityContext:
+                    runAsUser: 3000
+                    runAsGroup: 3000
+                  containers:
+                  - name: container
+                    image: busybox2
+                    securityContext:
+                      runAsUser: 2000
+                      runAsGroup: 2000
+                    command:
+                    - cat
+                    tty: true
+                """);
         child.setInheritFrom("parent");
         child.setYamlMergeStrategy(merge());
         setupStubs();
@@ -916,23 +965,31 @@ public void yamlOverrideSecurityContext() {
     }
 
     @Test
-    public void yamlMergeVolumes() throws Exception {
+    void yamlMergeVolumes() {
         PodTemplate parent = new PodTemplate();
-        parent.setYaml("apiVersion: v1\n" + "kind: Pod\n"
-                + "metadata:\n"
-                + "  labels:\n"
-                + "    some-label: some-label-value\n"
-                + "spec:\n"
-                + "  volumes:\n"
-                + "  - name: host-volume\n"
-                + "    hostPath:\n"
-                + "      path: /host/data\n");
+        parent.setYaml(
+                """
+                apiVersion: v1
+                kind: Pod
+                metadata:
+                  labels:
+                    some-label: some-label-value
+                spec:
+                  volumes:
+                  - name: host-volume
+                    hostPath:
+                      path: /host/data
+                """);
 
         PodTemplate child = new PodTemplate();
-        child.setYaml("spec:\n" + "  volumes:\n"
-                + "  - name: host-volume2\n"
-                + "    hostPath:\n"
-                + "      path: /host/data2\n");
+        child.setYaml(
+                """
+                spec:
+                  volumes:
+                  - name: host-volume2
+                    hostPath:
+                      path: /host/data2
+                """);
         child.setInheritFrom("parent");
         child.setYamlMergeStrategy(merge());
         setupStubs();
@@ -952,14 +1009,13 @@ public void yamlMergeVolumes() throws Exception {
         assertThat(hostVolume2.get().getHostPath().getPath(), equalTo("/host/data2")); // child value
     }
 
-    @Test
-    @TestCaseName("{method}(directConnection={0})")
-    @Parameters({"true", "false"})
-    public void testOverridesContainerSpec(boolean directConnection) throws Exception {
+    @ParameterizedTest(name = "directConnection={0}")
+    @ValueSource(booleans = {true, false})
+    void testOverridesContainerSpec(boolean directConnection) throws Exception {
         cloud.setDirectConnection(directConnection);
         PodTemplate template = new PodTemplate();
         ContainerTemplate cT = new ContainerTemplate("jnlp", "jenkinsci/jnlp-slave:latest");
-        template.setContainers(Arrays.asList(cT));
+        template.setContainers(List.of(cT));
         template.setYaml(loadYamlFile("pod-overrides.yaml"));
         setupStubs();
         Pod pod = new PodTemplateBuilder(template, slave).build();
@@ -967,15 +1023,12 @@ public void testOverridesContainerSpec(boolean directConnection) throws Exceptio
         Map containers = toContainerMap(pod);
         assertEquals(1, containers.size());
         Container jnlp = containers.get("jnlp");
-        assertEquals(
-                "Wrong number of volume mounts: " + jnlp.getVolumeMounts(),
-                1,
-                jnlp.getVolumeMounts().size());
+        assertEquals(1, jnlp.getVolumeMounts().size(), "Wrong number of volume mounts: " + jnlp.getVolumeMounts());
         validateContainers(pod, slave, directConnection);
     }
 
     @Test
-    public void whenRuntimeClassNameIsSetDoNotSetDefaultNodeSelector() {
+    void whenRuntimeClassNameIsSetDoNotSetDefaultNodeSelector() {
         setupStubs();
         PodTemplate template = new PodTemplate();
         template.setYaml("spec:\n" + "  runtimeClassName: windows");
@@ -994,7 +1047,7 @@ private Map toInitContainerMap(Pod pod) {
                 .collect(Collectors.toMap(Container::getName, Function.identity()));
     }
 
-    private String loadYamlFile(String s) throws IOException {
+    private String loadYamlFile(String s) throws Exception {
         return new String(IOUtils.toByteArray(getClass().getResourceAsStream(s)));
     }
 
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java
index 64a18fec25..6394654bbd 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateFilterTest.java
@@ -1,7 +1,7 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import edu.umd.cs.findbugs.annotations.CheckForNull;
 import edu.umd.cs.findbugs.annotations.NonNull;
@@ -9,14 +9,21 @@
 import java.util.ArrayList;
 import java.util.List;
 import org.hamcrest.Matchers;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.TestExtension;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodTemplateFilterTest {
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+@WithJenkins
+class PodTemplateFilterTest {
+
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @TestExtension
     public static class PodTemplateFilter1 extends PodTemplateFilter {
@@ -39,7 +46,7 @@ protected PodTemplate transform(
     }
 
     @Test
-    public void multipleFilters() {
+    void multipleFilters() {
         List podtemplates = new ArrayList<>();
         PodTemplate podTemplate = new PodTemplate();
         podTemplate.setLabel("label");
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java
index bc28dcd938..9fa00b4258 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateJenkinsTest.java
@@ -3,7 +3,7 @@
 import static org.csanchez.jenkins.plugins.kubernetes.PodTemplate.getLabelDigestFunction;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import hudson.model.Label;
 import java.math.BigInteger;
@@ -13,18 +13,25 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 import org.hamcrest.Matchers;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodTemplateJenkinsTest {
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+@WithJenkins
+class PodTemplateJenkinsTest {
+
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
 
     @Test
     @Issue({"JENKINS-59690", "JENKINS-60537"})
-    public void singleLabel() {
+    void singleLabel() {
         PodTemplate podTemplate = new PodTemplate();
         podTemplate.setLabel("foo");
         Map labelsMap = podTemplate.getLabelsMap();
@@ -38,7 +45,7 @@ public void singleLabel() {
 
     @Test
     @Issue({"JENKINS-59690", "JENKINS-60537"})
-    public void multiLabel() {
+    void multiLabel() {
         PodTemplate podTemplate = new PodTemplate();
         podTemplate.setLabel("foo bar");
         Map labelsMap = podTemplate.getLabelsMap();
@@ -52,7 +59,7 @@ public void multiLabel() {
 
     @Test
     @Issue({"JENKINS-59690", "JENKINS-60537"})
-    public void defaultLabel() {
+    void defaultLabel() {
         PodTemplate podTemplate = new PodTemplate();
         podTemplate.setLabel(null);
         Map labelsMap = podTemplate.getLabelsMap();
@@ -61,7 +68,7 @@ public void defaultLabel() {
     }
 
     @Test
-    public void jenkinsLabels() {
+    void jenkinsLabels() {
         KubernetesCloud kubernetesCloud = new KubernetesCloud("kubernetes");
         j.jenkins.clouds.add(kubernetesCloud);
         PodTemplate podTemplate = new PodTemplate();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java
index aa2b8cd056..13a1c32b5e 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateMapTest.java
@@ -1,23 +1,24 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import java.io.IOException;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.PodTemplateMap;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodTemplateMapTest {
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+@WithJenkins
+class PodTemplateMapTest {
 
     private PodTemplateMap instance;
     private KubernetesCloud cloud;
 
-    @Before
-    public void setUp() throws IOException {
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) throws Exception {
+        j = rule;
         this.instance = PodTemplateMap.get();
         this.cloud = new KubernetesCloud("kubernetes");
         j.jenkins.clouds.add(cloud);
@@ -25,7 +26,7 @@ public void setUp() throws IOException {
     }
 
     @Test
-    public void concurrentAdds() throws Exception {
+    void concurrentAdds() throws Exception {
         assertEquals(0, this.instance.getTemplates(cloud).size());
         int n = 10;
         Thread[] t = new Thread[n];
@@ -43,11 +44,7 @@ public void concurrentAdds() throws Exception {
 
     private Thread newThread(int i) {
         String name = "test-" + i;
-        return new Thread(
-                () -> {
-                    instance.addTemplate(cloud, buildPodTemplate(name));
-                },
-                name);
+        return new Thread(() -> instance.addTemplate(cloud, buildPodTemplate(name)), name);
     }
 
     private PodTemplate buildPodTemplate(String label) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java
index 33993670b4..75b7798380 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateTest.java
@@ -3,14 +3,15 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.empty;
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import hudson.util.XStream2;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
+
+class PodTemplateTest {
 
-public class PodTemplateTest {
     @Test
-    public void getYamlsExposesSingleYamlField() {
+    void getYamlsExposesSingleYamlField() {
         PodTemplate podTemplate = new PodTemplate();
         assertThat(podTemplate.getYamls(), empty());
         podTemplate.setYamls(null);
@@ -22,7 +23,7 @@ public void getYamlsExposesSingleYamlField() {
     }
 
     @Test
-    public void copyConstructor() throws Exception {
+    void copyConstructor() {
         XStream2 xs = new XStream2();
         PodTemplate pt = new PodTemplate();
         assertEquals(xs.toXML(pt), xs.toXML(new PodTemplate(pt)));
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java
index d9869f631a..78f65d1dd3 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodTemplateUtilsTest.java
@@ -41,12 +41,7 @@
 import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.*;
 
 import hudson.model.Node;
 import hudson.tools.ToolLocationNodeProperty;
@@ -64,7 +59,6 @@
 import io.fabric8.kubernetes.api.model.Toleration;
 import io.fabric8.kubernetes.api.model.VolumeMount;
 import io.fabric8.kubernetes.api.model.VolumeMountBuilder;
-import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -77,20 +71,18 @@
 import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.model.SecretEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.HostPathVolume;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.WithoutJenkins;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-@RunWith(Theories.class)
-public class PodTemplateUtilsTest {
-
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+@WithJenkins
+class PodTemplateUtilsTest {
 
     private static final PodImagePullSecret SECRET_1 = new PodImagePullSecret("secret1");
     private static final PodImagePullSecret SECRET_2 = new PodImagePullSecret("secret2");
@@ -106,21 +98,28 @@ public class PodTemplateUtilsTest {
     private static final ContainerTemplate MAVEN_1 = new ContainerTemplate("maven", "maven:1", "sh -c", "cat");
     private static final ContainerTemplate MAVEN_2 = new ContainerTemplate("maven", "maven:2");
 
+    private JenkinsRule j;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
+    }
+
     @Test
-    public void shouldReturnContainerTemplateWhenParentIsNull() {
+    void shouldReturnContainerTemplateWhenParentIsNull() {
         ContainerTemplate result = combine(null, JNLP_2);
-        assertEquals(result, JNLP_2);
+        assertEquals(JNLP_2, result);
     }
 
     @Test
-    public void shouldOverrideTheImageAndInheritTheRest() {
+    void shouldOverrideTheImageAndInheritTheRest() {
         ContainerTemplate result = combine(MAVEN_1, MAVEN_2);
         assertEquals("maven:2", result.getImage());
         assertEquals("cat", result.getArgs());
     }
 
     @Test
-    public void shouldReturnPodTemplateWhenParentIsNull() {
+    void shouldReturnPodTemplateWhenParentIsNull() {
         PodTemplate template = new PodTemplate();
         template.setName("template");
         template.setServiceAccount("sa1");
@@ -129,7 +128,7 @@ public void shouldReturnPodTemplateWhenParentIsNull() {
     }
 
     @Test
-    public void shouldOverrideServiceAccountIfSpecified() {
+    void shouldOverrideServiceAccountIfSpecified() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setServiceAccount("sa");
@@ -149,7 +148,7 @@ public void shouldOverrideServiceAccountIfSpecified() {
     }
 
     @Test
-    public void shouldOverrideNodeSelectorIfSpecified() {
+    void shouldOverrideNodeSelectorIfSpecified() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setNodeSelector("key:value");
@@ -169,11 +168,11 @@ public void shouldOverrideNodeSelectorIfSpecified() {
     }
 
     @Test
-    public void shouldCombineAllImagePullSecrets() {
+    void shouldCombineAllImagePullSecrets() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setNodeSelector("key:value");
-        parent.setImagePullSecrets(asList(SECRET_1));
+        parent.setImagePullSecrets(List.of(SECRET_1));
 
         PodTemplate template1 = new PodTemplate();
         template1.setName("template1");
@@ -197,7 +196,7 @@ public void shouldCombineAllImagePullSecrets() {
     }
 
     @Test
-    public void shouldCombineAllAnnotations() {
+    void shouldCombineAllAnnotations() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setNodeSelector("key:value");
@@ -205,35 +204,29 @@ public void shouldCombineAllAnnotations() {
 
         PodTemplate template1 = new PodTemplate();
         template1.setName("template");
-        template1.setAnnotations(asList(ANNOTATION_3));
+        template1.setAnnotations(List.of(ANNOTATION_3));
 
         PodTemplate result = combine(parent, template1);
         assertEquals(2, result.getAnnotations().size());
-        assertEquals("value3", result.getAnnotations().get(0).getValue().toString());
+        assertEquals("value3", result.getAnnotations().get(0).getValue());
     }
 
     @Test
-    public void shouldCombineAllLabels() {
-        Map labelsMap1 = new HashMap<>();
-        labelsMap1.put("label1", "pod1");
-        labelsMap1.put("label2", "pod1");
+    void shouldCombineAllLabels() {
         Pod pod1 = new PodBuilder()
                 .withNewMetadata()
                 .withLabels( //
-                        Collections.unmodifiableMap(labelsMap1) //
+                        Map.of("label1", "pod1", "label2", "pod1") //
                         )
                 .endMetadata()
                 .withNewSpec()
                 .endSpec()
                 .build();
 
-        Map labelsMap2 = new HashMap<>();
-        labelsMap2.put("label1", "pod2");
-        labelsMap2.put("label3", "pod2");
         Pod pod2 = new PodBuilder()
                 .withNewMetadata()
                 .withLabels( //
-                        Collections.unmodifiableMap(labelsMap2) //
+                        Map.of("label1", "pod2", "label3", "pod2") //
                         )
                 .endMetadata()
                 .withNewSpec()
@@ -247,13 +240,13 @@ public void shouldCombineAllLabels() {
     }
 
     @Test
-    public void shouldUnwrapParent() {
+    void shouldUnwrapParent() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setLabel("parent");
         parent.setServiceAccount("sa");
         parent.setNodeSelector("key:value");
-        parent.setImagePullSecrets(asList(SECRET_1));
+        parent.setImagePullSecrets(List.of(SECRET_1));
         parent.setYaml("Yaml");
         parent.setAgentContainer("agentContainer");
         parent.setAgentInjection(true);
@@ -278,7 +271,7 @@ public void shouldUnwrapParent() {
     }
 
     @Test
-    public void shouldDropNoDataWhenIdentical() {
+    void shouldDropNoDataWhenIdentical() {
         PodTemplate podTemplate = new PodTemplate();
         podTemplate.setName("Name");
         podTemplate.setNamespace("NameSpace");
@@ -286,7 +279,7 @@ public void shouldDropNoDataWhenIdentical() {
         podTemplate.setServiceAccount("ServiceAccount");
         podTemplate.setNodeSelector("NodeSelector");
         podTemplate.setNodeUsageMode(Node.Mode.EXCLUSIVE);
-        podTemplate.setImagePullSecrets(asList(SECRET_1));
+        podTemplate.setImagePullSecrets(List.of(SECRET_1));
         podTemplate.setInheritFrom("Inherit");
         podTemplate.setInstanceCap(99);
         podTemplate.setSlaveConnectTimeout(99);
@@ -303,7 +296,7 @@ public void shouldDropNoDataWhenIdentical() {
         assertEquals("ServiceAccount", selfCombined.getServiceAccount());
         assertEquals("NodeSelector", selfCombined.getNodeSelector());
         assertEquals(Node.Mode.EXCLUSIVE, selfCombined.getNodeUsageMode());
-        assertEquals(asList(SECRET_1), selfCombined.getImagePullSecrets());
+        assertEquals(List.of(SECRET_1), selfCombined.getImagePullSecrets());
         assertEquals("Inherit", selfCombined.getInheritFrom());
         assertEquals(99, selfCombined.getInstanceCap());
         assertEquals(99, selfCombined.getSlaveConnectTimeout());
@@ -314,13 +307,13 @@ public void shouldDropNoDataWhenIdentical() {
     }
 
     @Test
-    public void shouldUnwrapMultipleParents() {
+    void shouldUnwrapMultipleParents() {
         PodTemplate parent = new PodTemplate();
         parent.setName("parent");
         parent.setLabel("parent");
         parent.setServiceAccount("sa");
         parent.setNodeSelector("key:value");
-        parent.setImagePullSecrets(asList(SECRET_1));
+        parent.setImagePullSecrets(List.of(SECRET_1));
         parent.setContainers(asList(JNLP_1, MAVEN_2));
 
         PodTemplate template1 = new PodTemplate();
@@ -328,14 +321,14 @@ public void shouldUnwrapMultipleParents() {
         template1.setLabel("template1");
         template1.setInheritFrom("parent");
         template1.setServiceAccount("sa1");
-        template1.setImagePullSecrets(asList(SECRET_2));
-        template1.setContainers(asList(JNLP_2));
+        template1.setImagePullSecrets(List.of(SECRET_2));
+        template1.setContainers(List.of(JNLP_2));
 
         PodTemplate template2 = new PodTemplate();
         template2.setName("template2");
         template2.setLabel("template2");
-        template2.setImagePullSecrets(asList(SECRET_3));
-        template2.setContainers(asList(MAVEN_2));
+        template2.setImagePullSecrets(List.of(SECRET_3));
+        template2.setContainers(List.of(MAVEN_2));
 
         PodTemplate toUnwrap = new PodTemplate();
         toUnwrap.setName("toUnwrap");
@@ -356,7 +349,7 @@ public void shouldUnwrapMultipleParents() {
     }
 
     @Test
-    public void shouldCombineInitContainers() {
+    void shouldCombineInitContainers() {
         Pod parentPod = new PodBuilder()
                 .withNewMetadata()
                 .endMetadata()
@@ -382,7 +375,7 @@ public void shouldCombineInitContainers() {
     }
 
     @Test
-    public void childShouldOverrideParentInitContainer() {
+    void childShouldOverrideParentInitContainer() {
         Pod parentPod = new PodBuilder()
                 .withNewMetadata()
                 .endMetadata()
@@ -412,7 +405,7 @@ public void childShouldOverrideParentInitContainer() {
     }
 
     @Test
-    public void shouldCombineAllPodKeyValueEnvVars() {
+    void shouldCombineAllPodKeyValueEnvVars() {
         PodTemplate template1 = new PodTemplate();
         KeyValueEnvVar podEnvVar1 = new KeyValueEnvVar("key-1", "value-1");
         template1.setEnvVars(singletonList(podEnvVar1));
@@ -428,7 +421,7 @@ public void shouldCombineAllPodKeyValueEnvVars() {
     }
 
     @Test
-    public void childShouldOverrideParentActiveDeadlineSeconds() {
+    void childShouldOverrideParentActiveDeadlineSeconds() {
         Pod parentPod = new PodBuilder()
                 .withNewMetadata()
                 .endMetadata()
@@ -449,7 +442,7 @@ public void childShouldOverrideParentActiveDeadlineSeconds() {
     }
 
     @Test
-    public void shouldCombineActiveDeadlineSeconds() {
+    void shouldCombineActiveDeadlineSeconds() {
         Pod parentPod = new PodBuilder()
                 .withNewMetadata()
                 .endMetadata()
@@ -469,7 +462,7 @@ public void shouldCombineActiveDeadlineSeconds() {
     }
 
     @Test
-    public void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() {
+    void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() {
         PodTemplate template1 = new PodTemplate();
         KeyValueEnvVar podEnvVar1 = new KeyValueEnvVar("", "value-1");
         template1.setEnvVars(singletonList(podEnvVar1));
@@ -484,7 +477,7 @@ public void shouldFilterOutNullOrEmptyPodKeyValueEnvVars() {
     }
 
     @Test
-    public void shouldCombineAllPodSecretEnvVars() {
+    void shouldCombineAllPodSecretEnvVars() {
         PodTemplate template1 = new PodTemplate();
         SecretEnvVar podSecretEnvVar1 = new SecretEnvVar("key-1", "secret-1", "secret-key-1", false);
         template1.setEnvVars(singletonList(podSecretEnvVar1));
@@ -500,7 +493,7 @@ public void shouldCombineAllPodSecretEnvVars() {
     }
 
     @Test
-    public void shouldFilterOutNullOrEmptyPodSecretEnvVars() {
+    void shouldFilterOutNullOrEmptyPodSecretEnvVars() {
         PodTemplate template1 = new PodTemplate();
         SecretEnvVar podSecretEnvVar1 = new SecretEnvVar("", "secret-1", "secret-key-1", false);
         template1.setEnvVars(singletonList(podSecretEnvVar1));
@@ -515,7 +508,7 @@ public void shouldFilterOutNullOrEmptyPodSecretEnvVars() {
     }
 
     @Test
-    public void shouldCombineAllEnvVars() {
+    void shouldCombineAllEnvVars() {
         ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1");
         KeyValueEnvVar containerEnvVar1 = new KeyValueEnvVar("key-1", "value-1");
         template1.setEnvVars(singletonList(containerEnvVar1));
@@ -531,7 +524,7 @@ public void shouldCombineAllEnvVars() {
     }
 
     @Test
-    public void shouldFilterOutNullOrEmptyEnvVars() {
+    void shouldFilterOutNullOrEmptyEnvVars() {
         ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1");
         KeyValueEnvVar containerEnvVar1 = new KeyValueEnvVar("", "value-1");
         template1.setEnvVars(singletonList(containerEnvVar1));
@@ -546,7 +539,7 @@ public void shouldFilterOutNullOrEmptyEnvVars() {
     }
 
     @Test
-    public void shouldCombineAllSecretEnvVars() {
+    void shouldCombineAllSecretEnvVars() {
         ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1");
         SecretEnvVar containerSecretEnvVar1 = new SecretEnvVar("key-1", "secret-1", "secret-key-1", false);
         template1.setEnvVars(singletonList(containerSecretEnvVar1));
@@ -563,7 +556,7 @@ public void shouldCombineAllSecretEnvVars() {
     }
 
     @Test
-    public void shouldCombineAllEnvFromSourcesWithoutChangingOrder() {
+    void shouldCombineAllEnvFromSourcesWithoutChangingOrder() {
         EnvFromSource configMap1 = new EnvFromSource(new ConfigMapEnvSource("config-map-1", false), null, null);
         EnvFromSource secret1 = new EnvFromSource(null, null, new SecretEnvSource("secret-1", false));
         EnvFromSource configMap2 = new EnvFromSource(new ConfigMapEnvSource("config-map-2", true), null, null);
@@ -583,7 +576,7 @@ public void shouldCombineAllEnvFromSourcesWithoutChangingOrder() {
     }
 
     @Test
-    public void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() {
+    void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() {
         EnvFromSource noSource = new EnvFromSource(null, null, null);
         EnvFromSource noConfigMapKey = new EnvFromSource(new ConfigMapEnvSource(null, false), null, null);
         EnvFromSource emptyConfigMapKey = new EnvFromSource(new ConfigMapEnvSource("", false), null, null);
@@ -598,8 +591,9 @@ public void shouldFilterOutEnvFromSourcesWithNullOrEmptyKey() {
         assertEquals(0, result.getEnvFrom().size());
     }
 
-    @Theory
-    public void shouldTreatNullEnvFromSouresAsEmpty(boolean parentEnvNull, boolean templateEnvNull) {
+    @ParameterizedTest
+    @CsvSource({"true, true", "true, false", "false, true", "false, false"})
+    void shouldTreatNullEnvFromSourcesAsEmpty(boolean parentEnvNull, boolean templateEnvNull) {
         Container parent = new Container();
         if (parentEnvNull) {
             parent.setEnv(null);
@@ -616,7 +610,7 @@ public void shouldTreatNullEnvFromSouresAsEmpty(boolean parentEnvNull, boolean t
     }
 
     @Test
-    public void shouldCombineAllMounts() {
+    void shouldCombineAllMounts() {
         PodTemplate template1 = new PodTemplate();
         HostPathVolume hostPathVolume1 = new HostPathVolume("/host/mnt1", "/container/mnt1", false);
         HostPathVolume hostPathVolume2 = new HostPathVolume("/host/mnt2", "/container/mnt2", false);
@@ -650,7 +644,7 @@ private ContainerBuilder containerBuilder() {
     }
 
     @Test
-    public void shouldCombineAllPodMounts() {
+    void shouldCombineAllPodMounts() {
         VolumeMount vm1 = new VolumeMountBuilder()
                 .withMountPath("/host/mnt1")
                 .withName("volume-1")
@@ -698,7 +692,7 @@ public void shouldCombineAllPodMounts() {
     }
 
     @Test
-    public void shouldCombineAllTolerations() {
+    void shouldCombineAllTolerations() {
         PodSpec podSpec1 = new PodSpec();
         Pod pod1 = new Pod();
         Toleration toleration1 = new Toleration("effect1", "key1", "oper1", Long.parseLong("1"), "val1");
@@ -722,17 +716,17 @@ public void shouldCombineAllTolerations() {
     }
 
     @Test
-    public void shouldCombineAllPorts() {
+    void shouldCombineAllPorts() {
         ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1");
         PortMapping port1 = new PortMapping("port-1", 1000, 1000);
-        template1.setPorts(Arrays.asList(port1));
+        template1.setPorts(List.of(port1));
 
         ContainerTemplate template2 = new ContainerTemplate("name-2", "image-2");
 
         assertThat(combine(template1, template2).getPorts(), contains(port1));
 
         PortMapping port2 = new PortMapping("port-2", 2000, 2000);
-        template2.setPorts(Arrays.asList(port2));
+        template2.setPorts(List.of(port2));
         assertThat(combine(template1, template2).getPorts(), containsInAnyOrder(port1, port2));
 
         port2.setName("port-1");
@@ -740,7 +734,7 @@ public void shouldCombineAllPorts() {
     }
 
     @Test
-    public void shouldCombineAllResources() {
+    void shouldCombineAllResources() {
         Container container1 = new Container();
         container1.setResources(
                 new ResourceRequirementsBuilder() //
@@ -768,7 +762,7 @@ public void shouldCombineAllResources() {
     }
 
     @Test
-    public void shouldCombineContainersInOrder() {
+    void shouldCombineContainersInOrder() {
         Container container1 = containerBuilder().withName("mysql").build();
         Container container2 = containerBuilder().withName("jnlp").build();
         Pod pod1 = new PodBuilder()
@@ -799,7 +793,7 @@ public void shouldCombineContainersInOrder() {
     }
 
     /**
-     * Use instead of {@link org.junit.Assert#assertEquals(Object, Object)} on {@link Quantity}.
+     * Use instead of {@link Assertions#assertEquals(Object, Object)} on {@link Quantity}.
      * @see kubernetes-client #2034
      */
     public static void assertQuantity(String expected, Quantity actual) {
@@ -809,7 +803,7 @@ public static void assertQuantity(String expected, Quantity actual) {
     }
 
     @Test
-    public void shouldFilterOutNullOrEmptySecretEnvVars() {
+    void shouldFilterOutNullOrEmptySecretEnvVars() {
         ContainerTemplate template1 = new ContainerTemplate("name-1", "image-1");
         SecretEnvVar containerSecretEnvVar1 = new SecretEnvVar("", "secret-1", "secret-key-1", false);
         template1.setEnvVars(singletonList(containerSecretEnvVar1));
@@ -826,21 +820,21 @@ public void shouldFilterOutNullOrEmptySecretEnvVars() {
     // Substitute tests
 
     @Test
-    public void shouldIgnoreMissingProperties() {
+    void shouldIgnoreMissingProperties() {
         Map properties = new HashMap<>();
         properties.put("key1", "value1");
         assertEquals("${key2}", substitute("${key2}", properties));
     }
 
     @Test
-    public void shouldSubstituteSingleEnvVar() {
+    void shouldSubstituteSingleEnvVar() {
         Map properties = new HashMap<>();
         properties.put("key1", "value1");
         assertEquals("value1", substitute("${key1}", properties));
     }
 
     @Test
-    public void shouldSubstituteMultipleEnvVars() {
+    void shouldSubstituteMultipleEnvVars() {
         Map properties = new HashMap<>();
         properties.put("key1", "value1");
         properties.put("key2", "value2");
@@ -848,7 +842,7 @@ public void shouldSubstituteMultipleEnvVars() {
     }
 
     @Test
-    public void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() {
+    void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() {
         Map properties = new HashMap<>();
         properties.put("key1", "value1");
         properties.put("key2", "value2");
@@ -856,7 +850,7 @@ public void shouldSubstituteMultipleEnvVarsAndIgnoreMissing() {
     }
 
     @Test
-    public void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() {
+    void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() {
         Map properties = new HashMap<>();
         properties.put("key1", "value1");
         properties.put("key2", "value2");
@@ -865,64 +859,64 @@ public void shouldSubstituteMultipleEnvVarsAndNotUseDefaultsForMissing() {
     }
 
     @Test
-    public void testValidateLabelA() {
+    void testValidateLabelA() {
         assertTrue(validateLabel("1"));
         assertTrue(validateLabel("a"));
     }
 
     @Test
-    public void testValidateLabelAb() {
+    void testValidateLabelAb() {
         assertTrue(validateLabel("12"));
         assertTrue(validateLabel("ab"));
     }
 
     @Test
-    public void testValidateLabelAbc() {
+    void testValidateLabelAbc() {
         assertTrue(validateLabel("123"));
         assertTrue(validateLabel("abc"));
     }
 
     @Test
-    public void testValidateLabelAbcd() {
+    void testValidateLabelAbcd() {
         assertTrue(validateLabel("1234"));
         assertTrue(validateLabel("abcd"));
     }
 
     @Test
-    public void testValidateLabelMypod() {
+    void testValidateLabelMypod() {
         assertTrue(validateLabel("mypod"));
     }
 
     @Test
-    public void testValidateLabelMyPodNested() {
+    void testValidateLabelMyPodNested() {
         assertTrue(validateLabel("mypodNested"));
     }
 
     @Test
-    public void testValidateLabelSpecialChars() {
+    void testValidateLabelSpecialChars() {
         assertTrue(validateLabel("x-_.z"));
         assertFalse(validateLabel("one two"));
     }
 
     @Test
-    public void testValidateLabelStartWithSpecialChars() {
+    void testValidateLabelStartWithSpecialChars() {
         assertFalse(validateLabel("-x"));
     }
 
     @Test
-    public void testValidateLabelLong() {
+    void testValidateLabelLong() {
         assertTrue(validateLabel("123456789012345678901234567890123456789012345678901234567890123"));
         assertTrue(validateLabel("abcdefghijklmnopqrstuwxyzabcdefghijklmnopqrstuwxyzabcdefghijklm"));
     }
 
     @Test
-    public void testValidateLabelTooLong() {
+    void testValidateLabelTooLong() {
         assertFalse(validateLabel("1234567890123456789012345678901234567890123456789012345678901234"));
         assertFalse(validateLabel("abcdefghijklmnopqrstuwxyzabcdefghijklmnopqrstuwxyzabcdefghijklmn"));
     }
 
     @Test
-    public void shouldCombineAllToolLocations() {
+    void shouldCombineAllToolLocations() {
 
         PodTemplate podTemplate1 = new PodTemplate();
         List nodeProperties1 = new ArrayList<>();
@@ -947,14 +941,14 @@ public void shouldCombineAllToolLocations() {
 
     @Test
     @Issue("JENKINS-57116")
-    public void testParseYaml() {
+    void testParseYaml() {
         PodTemplateUtils.parseFromYaml("{}");
         PodTemplateUtils.parseFromYaml(null);
         PodTemplateUtils.parseFromYaml("");
     }
 
     @Test
-    public void octalParsing() throws IOException {
+    void octalParsing() throws Exception {
         var fileStream = getClass().getResourceAsStream(getClass().getSimpleName() + "/octal.yaml");
         assertNotNull(fileStream);
         var pod = parseFromYaml(IOUtils.toString(fileStream, StandardCharsets.UTF_8));
@@ -962,7 +956,7 @@ public void octalParsing() throws IOException {
     }
 
     @Test
-    public void decimalParsing() throws IOException {
+    void decimalParsing() throws Exception {
         var fileStream = getClass().getResourceAsStream(getClass().getSimpleName() + "/decimal.yaml");
         assertNotNull(fileStream);
         var pod = parseFromYaml(IOUtils.toString(fileStream, StandardCharsets.UTF_8));
@@ -1000,7 +994,7 @@ private static void checkParsed(Pod pod) {
 
     @Test
     @Issue("JENKINS-72886")
-    public void shouldIgnoreContainerEmptyArgs() {
+    void shouldIgnoreContainerEmptyArgs() {
         Container parent = new Container();
         parent.setArgs(List.of("arg1", "arg2"));
         parent.setCommand(List.of("parent command"));
@@ -1011,7 +1005,7 @@ public void shouldIgnoreContainerEmptyArgs() {
     }
 
     @Test
-    public void shouldSanitizeJenkinsLabel() {
+    void shouldSanitizeJenkinsLabel() {
         assertEquals("foo", sanitizeLabel("foo"));
         assertEquals("foo_bar__3", sanitizeLabel("foo bar #3"));
         assertEquals("This_Thing", sanitizeLabel("This/Thing"));
@@ -1032,7 +1026,7 @@ public void shouldSanitizeJenkinsLabel() {
     }
 
     @Test
-    public void shouldCombineCapabilities() {
+    void shouldCombineCapabilities() {
         Container container1 = containerBuilder()
                 .withNewSecurityContext()
                 .withNewCapabilities()
@@ -1075,7 +1069,7 @@ public void shouldCombineCapabilities() {
     }
 
     @Test
-    public void shouldOverrideCapabilitiesWithTemplate() {
+    void shouldOverrideCapabilitiesWithTemplate() {
         Container container1 = containerBuilder()
                 .withNewSecurityContext()
                 .withNewCapabilities()
@@ -1101,7 +1095,7 @@ public void shouldOverrideCapabilitiesWithTemplate() {
     }
 
     @Test
-    public void shouldRetainNullsWhenCombiningCapabilities() {
+    void shouldRetainNullsWhenCombiningCapabilities() {
 
         Container container1 = new ContainerBuilder().build();
         Container container2 = new ContainerBuilder().build();
@@ -1120,7 +1114,7 @@ public void shouldRetainNullsWhenCombiningCapabilities() {
     }
 
     @Test
-    public void shouldOverrideShareProcessNamespaceIfSpecified() {
+    void shouldOverrideShareProcessNamespaceIfSpecified() {
         Pod parent1 = new PodBuilder()
                 .withNewMetadata()
                 .endMetadata()
@@ -1166,7 +1160,7 @@ public void shouldOverrideShareProcessNamespaceIfSpecified() {
 
     @WithoutJenkins
     @Test
-    public void testSplitCommandLine() {
+    void testSplitCommandLine() {
         assertNull(PodTemplateUtils.splitCommandLine(""));
         assertNull(PodTemplateUtils.splitCommandLine(null));
         assertEquals(List.of("bash"), PodTemplateUtils.splitCommandLine("bash"));
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java
index b7ff7e66f4..713a4c1bdb 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/PodUtilsTest.java
@@ -1,20 +1,18 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-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.*;
 
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.IntStream;
 import org.apache.commons.lang.StringUtils;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class PodUtilsTest {
+class PodUtilsTest {
 
     @Test
-    public void generateRandomSuffix() {
+    void generateRandomSuffix() {
         List generated = IntStream.range(0, 100)
                 .mapToObj(i -> PodUtils.generateRandomSuffix())
                 .toList();
@@ -28,7 +26,7 @@ public void generateRandomSuffix() {
     }
 
     @Test
-    public void createNameWithRandomSuffix() {
+    void createNameWithRandomSuffix() {
         String name = PodUtils.createNameWithRandomSuffix("foo");
         assertEquals(9, name.length());
         assertTrue(name.startsWith("foo-"));
@@ -46,7 +44,7 @@ public void createNameWithRandomSuffix() {
     }
 
     @Test
-    public void isValidName() {
+    void isValidName() {
         assertTrue(PodUtils.isValidName("foo"));
         assertTrue(PodUtils.isValidName("foo-bar"));
         assertTrue(PodUtils.isValidName("foo.bar"));
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java
index b3188b98e9..b91970af04 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/RestrictedPssSecurityInjectorTest.java
@@ -1,13 +1,13 @@
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import java.io.IOException;
 import org.csanchez.jenkins.plugins.kubernetes.pod.decorator.PodDecorator;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
-public class RestrictedPssSecurityInjectorTest extends AbstractGoldenFileTest {
-    @Before
-    public void configureCloud() {
+class RestrictedPssSecurityInjectorTest extends AbstractGoldenFileTest {
+
+    @BeforeEach
+    void configureCloud() {
         cloud.setRestrictedPssSecurityContext(true);
     }
 
@@ -17,22 +17,22 @@ protected PodDecorator newDecorator() {
     }
 
     @Test
-    public void simple() throws IOException {
+    void simple() throws Exception {
         test("simple");
     }
 
     @Test
-    public void multiContainer() throws IOException {
+    void multiContainer() throws Exception {
         test("multiContainer");
     }
 
     @Test
-    public void existingSecurityContext() throws IOException {
+    void existingSecurityContext() throws Exception {
         test("existingSecurityContext");
     }
 
     @Test
-    public void agentInjection() throws IOException {
+    void agentInjection() throws Exception {
         test("agentInjection");
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java
index b934412fbd..6941bb646e 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/TaskListenerEventWatcherTest.java
@@ -23,7 +23,7 @@
  */
 package org.csanchez.jenkins.plugins.kubernetes;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.Mockito.*;
 
 import hudson.model.TaskListener;
@@ -32,38 +32,40 @@
 import io.fabric8.kubernetes.client.Watcher;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import java.nio.charset.StandardCharsets;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
 
-@RunWith(MockitoJUnitRunner.class)
-public class TaskListenerEventWatcherTest {
+@ExtendWith(MockitoExtension.class)
+class TaskListenerEventWatcherTest {
+
+    @Mock
+    private TaskListener listener;
 
-    private @Mock TaskListener listener;
     private TaskListenerEventWatcher watcher;
 
-    @Before
-    public void setup() {
+    @BeforeEach
+    void beforeEach() {
         watcher = new TaskListenerEventWatcher("foo", listener);
     }
 
     @Test
-    public void ignoreBookmarkAction() {
+    void ignoreBookmarkAction() {
         watcher.eventReceived(Watcher.Action.BOOKMARK, new Event());
         verifyNoInteractions(listener);
     }
 
     @Test
-    public void ignoreErrorAction() {
+    void ignoreErrorAction() {
         watcher.eventReceived(Watcher.Action.ERROR, null);
         verifyNoInteractions(listener);
     }
 
     @Test
-    public void logEventMessage() throws UnsupportedEncodingException {
+    void logEventMessage() {
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         PrintStream ps = new PrintStream(bos);
         when(listener.getLogger()).thenReturn(ps);
@@ -80,7 +82,7 @@ public void logEventMessage() throws UnsupportedEncodingException {
 
         verify(listener).getLogger();
         ps.flush();
-        String output = bos.toString("UTF-8");
+        String output = bos.toString(StandardCharsets.UTF_8);
         assertEquals("[Update][bar/foo-123][because] cat\n[Update][bar/foo-123][because] dog\n", output);
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java
index fc2aba252c..d34e9280a1 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/CasCTest.java
@@ -3,13 +3,9 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.isA;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
 
-import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
+import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest;
 import java.util.List;
 import org.csanchez.jenkins.plugins.kubernetes.ContainerLivenessProbe;
 import org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate;
@@ -19,13 +15,15 @@
 import org.csanchez.jenkins.plugins.kubernetes.pod.yaml.Overrides;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.WorkspaceVolume;
-import org.jvnet.hudson.test.RestartableJenkinsRule;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class CasCTest extends RoundTripAbstractTest {
+@WithJenkins
+class CasCTest extends AbstractRoundTripTest {
 
     @Override
-    protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) {
-        List all = r.j.jenkins.clouds.getAll(KubernetesCloud.class);
+    protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) {
+        List all = r.jenkins.clouds.getAll(KubernetesCloud.class);
         assertThat(all, hasSize(1));
         KubernetesCloud cloud = all.get(0);
         assertNotNull(cloud);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java
index 3fab7aa2c2..3a2d223c74 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/EnvVarCasCTest.java
@@ -2,41 +2,44 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
+import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest;
 import java.util.List;
+import java.util.stream.Stream;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.csanchez.jenkins.plugins.kubernetes.model.KeyValueEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.model.SecretEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.jvnet.hudson.test.RestartableJenkinsRule;
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-@RunWith(Parameterized.class)
-public class EnvVarCasCTest extends RoundTripAbstractTest {
-    final EnvVarStrategy strategy;
-    final String resource;
+@WithJenkins
+@ParameterizedClass(name = "{index}: {1}")
+@MethodSource("permutations")
+class EnvVarCasCTest extends AbstractRoundTripTest {
 
-    public EnvVarCasCTest(EnvVarStrategy strategy, String resource) {
-        this.strategy = strategy;
-        this.resource = resource;
-    }
+    @Parameter(0)
+    private EnvVarStrategy strategy;
+
+    @Parameter(1)
+    private String resource;
 
-    @Parameterized.Parameters(name = "{index}: {1}")
-    public static Object[] permutations() {
-        return new Object[][] {
-            {new KeyValueEnvVarStrategy(), "keyValue"},
-            {new SecretEnvVarStrategy(), "secret"},
-        };
+    static Stream permutations() {
+        return Stream.of(
+                Arguments.of(new KeyValueEnvVarStrategy(), "keyValue"),
+                Arguments.of(new SecretEnvVarStrategy(), "secret"));
     }
 
     @Override
-    protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) {
-        KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class);
+    protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) {
+        KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class);
         assertNotNull(cloud);
         List templates = cloud.getTemplates();
         assertNotNull(templates);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java
index 48b5ca1d19..82c5854280 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/VolumeCasCTest.java
@@ -2,44 +2,47 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
+import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest;
 import java.util.List;
+import java.util.stream.Stream;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.*;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.jvnet.hudson.test.RestartableJenkinsRule;
-
-@RunWith(Parameterized.class)
-public class VolumeCasCTest extends RoundTripAbstractTest {
-    final VolumeStrategy strategy;
-    final String resource;
-
-    public VolumeCasCTest(VolumeStrategy strategy, String resource) {
-        this.strategy = strategy;
-        this.resource = resource;
-    }
-
-    @Parameterized.Parameters(name = "{index}: {1}")
-    public static Object[] permutations() {
-        return new Object[][] {
-            {new EmptyDirVolumeStrategy(), "emptyDir"},
-            {new EmptyDirVolumeStrategy(Boolean.TRUE), "emptyDir_memory"},
-            {new ConfigMapVolumeStrategy(), "configMap"},
-            {new HostPathVolumeStrategy(), "hostPath"},
-            {new NfsVolumeStrategy(), "nfs"},
-            {new PVCVolumeStrategy(), "pvc"},
-            {new GenericEphemeralVolumeStrategy(), "genericEphemeral"},
-        };
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
+
+@WithJenkins
+@ParameterizedClass(name = "{index}: {1}")
+@MethodSource("permutations")
+class VolumeCasCTest extends AbstractRoundTripTest {
+
+    @Parameter(0)
+    private VolumeStrategy strategy;
+
+    @Parameter(1)
+    private String resource;
+
+    static Stream permutations() {
+        return Stream.of(
+                Arguments.of(new EmptyDirVolumeStrategy(), "emptyDir"),
+                Arguments.of(new EmptyDirVolumeStrategy(Boolean.TRUE), "emptyDir_memory"),
+                Arguments.of(new ConfigMapVolumeStrategy(), "configMap"),
+                Arguments.of(new HostPathVolumeStrategy(), "hostPath"),
+                Arguments.of(new NfsVolumeStrategy(), "nfs"),
+                Arguments.of(new PVCVolumeStrategy(), "pvc"),
+                Arguments.of(new GenericEphemeralVolumeStrategy(), "genericEphemeral"));
     }
 
     @Override
-    protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) {
-        KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class);
+    protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) {
+        KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class);
         assertNotNull(cloud);
         List templates = cloud.getTemplates();
         assertNotNull(templates);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java
index 4632953260..2ea9b7ae5b 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/casc/WorkspaceVolumeCasCTest.java
@@ -2,44 +2,47 @@
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import io.jenkins.plugins.casc.misc.RoundTripAbstractTest;
+import io.jenkins.plugins.casc.misc.junit.jupiter.AbstractRoundTripTest;
 import java.util.List;
+import java.util.stream.Stream;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.*;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.jvnet.hudson.test.RestartableJenkinsRule;
-
-@RunWith(Parameterized.class)
-public class WorkspaceVolumeCasCTest extends RoundTripAbstractTest {
-    final WorkspaceVolumeStrategy strategy;
-    final String resource;
-
-    public WorkspaceVolumeCasCTest(WorkspaceVolumeStrategy strategy, String resource) {
-        this.strategy = strategy;
-        this.resource = resource;
-    }
-
-    @Parameterized.Parameters(name = "{index}: {1}")
-    public static Object[] permutations() {
-        return new Object[][] {
-            {new DynamicPVCWorkspaceVolumeStrategy(), "dynamicPVC"},
-            {new EmptyDirWorkspaceVolumeStrategy(), "emptyDir"},
-            {new EmptyDirWorkspaceVolumeStrategy(Boolean.TRUE), "emptyDir_memory"},
-            {new HostPathWorkspaceVolumeStrategy(), "hostPath"},
-            {new NfsWorkspaceVolumeStrategy(), "nfs"},
-            {new PVCWorkspaceVolumeStrategy(), "pvc"},
-            {new GenericEphemeralWorkspaceVolumeStrategy(), "genericEphemeral"},
-        };
+import org.junit.jupiter.params.Parameter;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
+
+@WithJenkins
+@ParameterizedClass(name = "{index}: {1}")
+@MethodSource("permutations")
+public class WorkspaceVolumeCasCTest extends AbstractRoundTripTest {
+
+    @Parameter(0)
+    private WorkspaceVolumeStrategy strategy;
+
+    @Parameter(1)
+    private String resource;
+
+    static Stream permutations() {
+        return Stream.of(
+                Arguments.of(new DynamicPVCWorkspaceVolumeStrategy(), "dynamicPVC"),
+                Arguments.of(new EmptyDirWorkspaceVolumeStrategy(), "emptyDir"),
+                Arguments.of(new EmptyDirWorkspaceVolumeStrategy(Boolean.TRUE), "emptyDir_memory"),
+                Arguments.of(new HostPathWorkspaceVolumeStrategy(), "hostPath"),
+                Arguments.of(new NfsWorkspaceVolumeStrategy(), "nfs"),
+                Arguments.of(new PVCWorkspaceVolumeStrategy(), "pvc"),
+                Arguments.of(new GenericEphemeralWorkspaceVolumeStrategy(), "genericEphemeral"));
     }
 
     @Override
-    protected void assertConfiguredAsExpected(RestartableJenkinsRule r, String configContent) {
-        KubernetesCloud cloud = r.j.jenkins.clouds.get(KubernetesCloud.class);
+    protected void assertConfiguredAsExpected(JenkinsRule r, String configContent) {
+        KubernetesCloud cloud = r.jenkins.clouds.get(KubernetesCloud.class);
         assertNotNull(cloud);
         List templates = cloud.getTemplates();
         assertNotNull(templates);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java
index 6a9d862a45..92a98245df 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineRJRTest.java
@@ -7,22 +7,18 @@
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.CreateWorkflowJobThenScheduleRun;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
-public abstract class AbstractKubernetesPipelineRJRTest {
+abstract class AbstractKubernetesPipelineRJRTest {
 
-    @Rule
-    public TestName name = new TestName();
-
-    @Rule
-    public RealJenkinsRule rjr;
+    @RegisterExtension
+    protected RealJenkinsExtension rjr = new RealJenkinsExtension();
 
     {
-        rjr = new RealJenkinsRule();
         String port = System.getProperty("port");
         if (StringUtils.isNotBlank(port)) {
             System.err.println("Overriding port using system property: " + port);
@@ -30,25 +26,28 @@ public abstract class AbstractKubernetesPipelineRJRTest {
         }
     }
 
-    private SetupCloud setup;
+    protected final SetupCloud setup;
+
+    protected String name;
 
     public AbstractKubernetesPipelineRJRTest(SetupCloud setup) {
         this.setup = setup;
     }
 
-    @BeforeClass
-    public static void isKubernetesConfigured() throws Exception {
+    @BeforeAll
+    protected static void beforeAll() {
         assumeKubernetes();
     }
 
-    @Before
-    public void setUp() throws Throwable {
+    @BeforeEach
+    protected void beforeEach(TestInfo info) throws Throwable {
+        name = info.getTestMethod().orElseThrow().getName();
         rjr.startJenkins();
         rjr.runRemotely(setup);
     }
 
     protected RunId createWorkflowJobThenScheduleRun() throws Throwable {
         return rjr.runRemotely(new CreateWorkflowJobThenScheduleRun(
-                KubernetesTestUtil.loadPipelineScript(getClass(), name.getMethodName() + ".groovy")));
+                KubernetesTestUtil.loadPipelineScript(getClass(), name + ".groovy")));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java
index dc353d2019..cef6ba0bd6 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/AbstractKubernetesPipelineTest.java
@@ -54,43 +54,40 @@
 import org.csanchez.jenkins.plugins.kubernetes.model.TemplateEnvVar;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.rules.TestName;
-import org.jvnet.hudson.test.BuildWatcher;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.TestInfo;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
+@WithJenkins
 public abstract class AbstractKubernetesPipelineTest {
     protected static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value";
     protected static final String POD_ENV_VAR_VALUE = "pod-env-var-value";
     protected static final String GLOBAL = "GLOBAL";
 
-    @ClassRule
-    public static BuildWatcher buildWatcher = new BuildWatcher();
+    @SuppressWarnings("unused")
+    protected static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension();
 
     protected KubernetesCloud cloud;
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    protected JenkinsRule r;
 
-    @Rule
-    public LoggerRule logs = new LoggerRule()
+    protected final LogRecorder logs = new LogRecorder()
             .recordPackage(KubernetesCloud.class, Level.FINE)
             .recordPackage(NoDelayProvisionerStrategy.class, Level.FINE)
             .record(PodUtils.class, Level.FINE)
             .record(NodeProvisioner.class, Level.FINE)
             .record(KubernetesAgentErrorCondition.class, Level.FINE);
 
-    @BeforeClass
-    public static void isKubernetesConfigured() throws Exception {
+    @BeforeAll
+    protected static void beforeAll() {
         assumeKubernetes();
     }
 
-    @Rule
-    public TestName name = new TestName();
+    protected String name;
 
     private String projectName;
 
@@ -98,10 +95,29 @@ public static void isKubernetesConfigured() throws Exception {
 
     protected WorkflowRun b;
 
-    @Before
-    public void defineProjectName() {
+    @BeforeEach
+    protected void beforeEach(JenkinsRule rule, TestInfo info) throws Exception {
+        r = rule;
+        name = info.getTestMethod().orElseThrow().getName();
         // Add spaces before uppercases
-        this.projectName = generateProjectName(name.getMethodName());
+        projectName = generateProjectName(name);
+
+        cloud = setupCloud(this, name);
+        createSecret(cloud.connect(), cloud.getNamespace());
+        cloud.getTemplates().clear();
+        cloud.addTemplate(buildBusyboxTemplate("busybox"));
+
+        setupHost(cloud);
+
+        r.jenkins.clouds.add(cloud);
+
+        DescribableList, NodePropertyDescriptor> list = r.jenkins.getGlobalNodeProperties();
+        EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
+        list.add(newEnvVarsNodeProperty);
+        EnvVars envVars = newEnvVarsNodeProperty.getEnvVars();
+        envVars.put("GLOBAL", "GLOBAL");
+        envVars.put("JAVA_HOME_X", "java-home-x");
+        r.jenkins.save();
     }
 
     protected String getProjectName() {
@@ -132,33 +148,13 @@ protected final WorkflowRun createJobThenScheduleRun() throws Exception {
      * @return The scheduled pipeline run
      */
     protected final WorkflowRun createJobThenScheduleRun(Map env) throws Exception {
-        b = createPipelineJobThenScheduleRun(r, getClass(), name.getMethodName(), env);
+        b = createPipelineJobThenScheduleRun(r, getClass(), name, env);
         p = b.getParent();
         return b;
     }
 
     protected final String loadPipelineDefinition() {
-        return KubernetesTestUtil.loadPipelineDefinition(getClass(), name.getMethodName(), null);
-    }
-
-    @Before
-    public void configureCloud() throws Exception {
-        cloud = setupCloud(this, name);
-        createSecret(cloud.connect(), cloud.getNamespace());
-        cloud.getTemplates().clear();
-        cloud.addTemplate(buildBusyboxTemplate("busybox"));
-
-        setupHost(cloud);
-
-        r.jenkins.clouds.add(cloud);
-
-        DescribableList, NodePropertyDescriptor> list = r.jenkins.getGlobalNodeProperties();
-        EnvironmentVariablesNodeProperty newEnvVarsNodeProperty = new hudson.slaves.EnvironmentVariablesNodeProperty();
-        list.add(newEnvVarsNodeProperty);
-        EnvVars envVars = newEnvVarsNodeProperty.getEnvVars();
-        envVars.put("GLOBAL", "GLOBAL");
-        envVars.put("JAVA_HOME_X", "java-home-x");
-        r.jenkins.save();
+        return KubernetesTestUtil.loadPipelineDefinition(getClass(), name, null);
     }
 
     private PodTemplate buildBusyboxTemplate(String label) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java
index 5ecb69fdd2..519fbb013f 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorPipelineTest.java
@@ -16,7 +16,7 @@
 
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 
 import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey;
 import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey.PrivateKeySource;
@@ -28,21 +28,19 @@
 import java.util.logging.Logger;
 import org.apache.commons.io.IOUtils;
 import org.jenkinsci.plugins.durabletask.BourneShellScript;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
 
-public class ContainerExecDecoratorPipelineTest extends AbstractKubernetesPipelineTest {
+class ContainerExecDecoratorPipelineTest extends AbstractKubernetesPipelineTest {
 
-    @Rule
-    public LoggerRule containerExecLogs = new LoggerRule()
+    private final LogRecorder containerExecLogs = new LogRecorder()
             .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL)
             .record(BourneShellScript.class, Level.ALL);
 
     @Issue({"JENKINS-47225", "JENKINS-42582"})
     @Test
-    public void sshagent() throws Exception {
+    void sshagent() throws Exception {
         PrivateKeySource source = new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(
                 new String(IOUtils.toByteArray(getClass().getResourceAsStream("id_rsa"))));
         BasicSSHUserPrivateKey credentials = new BasicSSHUserPrivateKey(
@@ -68,7 +66,7 @@ public void sshagent() throws Exception {
     }
 
     @Test
-    public void docker() throws Exception {
+    void docker() throws Exception {
         StandardUsernamePasswordCredentials credentials = new UsernamePasswordCredentialsImpl(
                 CredentialsScope.GLOBAL,
                 "ContainerExecDecoratorPipelineTest-docker",
@@ -88,26 +86,26 @@ public void docker() throws Exception {
         r.assertLogNotContains("secret_password", b);
         // check that we don't accidentally start exporting sensitive info to the Jenkins log
         assertFalse(
-                "credential leaked to log",
-                containerExecLogs.getMessages().stream().anyMatch(msg -> msg.contains("secret_password")));
+                containerExecLogs.getMessages().stream().anyMatch(msg -> msg.contains("secret_password")),
+                "credential leaked to log");
     }
 
     @Issue("JENKINS-58290")
     @Test
-    public void closedWebSocketExit() throws Exception {
+    void closedWebSocketExit() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         containerExecLogs.capture(1000);
         r.waitForMessage("have started user process", b);
         assertTrue(
-                "WebSocket was closed in a timely fashion",
-                containerExecLogs.getMessages().stream().anyMatch(m -> m.startsWith("onClose : ")));
+                containerExecLogs.getMessages().stream().anyMatch(m -> m.startsWith("onClose : ")),
+                "WebSocket was closed in a timely fashion");
         b.getExecutor().interrupt();
         r.waitForCompletion(b);
     }
 
     @Issue("JENKINS-61950")
     @Test
-    public void envVarDollarSignEscaping() throws Exception {
+    void envVarDollarSignEscaping() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         containerExecLogs.capture(1000);
         r.waitForCompletion(b);
@@ -117,7 +115,7 @@ public void envVarDollarSignEscaping() throws Exception {
     }
 
     @Test
-    public void containerEnvironmentIsHonored() throws Exception {
+    void containerEnvironmentIsHonored() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.waitForCompletion(b);
         r.assertLogContains(
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java
index 937e20aec9..6988b73614 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorTest.java
@@ -28,11 +28,10 @@
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.setupCloud;
+import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.arrayContaining;
-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.*;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -51,6 +50,7 @@
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClientException;
 import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -70,28 +70,26 @@
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.jenkinsci.plugins.workflow.steps.StepContext;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TestName;
-import org.junit.rules.Timeout;
+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.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.Timeout;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
 /**
  * @author Carlos Sanchez
  */
-public class ContainerExecDecoratorTest {
-    @Rule
-    public ExpectedException exception = ExpectedException.none();
+@WithJenkins
+@Timeout(value = 3, unit = TimeUnit.MINUTES)
+class ContainerExecDecoratorTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
 
     private KubernetesCloud cloud;
     private static KubernetesClient client;
@@ -102,25 +100,23 @@ public class ContainerExecDecoratorTest {
     private KubernetesSlave agent;
     private DumbSlave dumbAgent;
 
-    @Rule
-    public Timeout timeout = new Timeout(3, TimeUnit.MINUTES);
-
-    @Rule
-    public LoggerRule containerExecLogs = new LoggerRule()
+    @SuppressWarnings("unused")
+    private final LogRecorder containerExecLogs = new LogRecorder()
             .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL) //
             .record(ContainerExecProc.class, Level.ALL) //
             .record(Logger.getLogger(KubernetesClientProvider.class.getName()), Level.ALL);
 
-    @Rule
-    public TestName name = new TestName();
+    private String name;
 
-    @BeforeClass
-    public static void isKubernetesConfigured() throws Exception {
+    @BeforeAll
+    static void beforeAll() {
         assumeKubernetes();
     }
 
-    @Before
-    public void configureCloud() throws Exception {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule, TestInfo info) throws Exception {
+        j = rule;
+        name = info.getTestMethod().orElseThrow().getName();
         cloud = setupCloud(this, name);
         client = cloud.connect();
         deletePods(client, getLabels(this, name), false);
@@ -172,8 +168,8 @@ public void configureCloud() throws Exception {
         decorator.setContainerName(image);
     }
 
-    @After
-    public void after() throws Exception {
+    @AfterEach
+    void afterEach() throws Exception {
         client.pods().delete(pod);
         deletePods(client, getLabels(this, name), true);
     }
@@ -181,9 +177,9 @@ public void after() throws Exception {
     /**
      * Test that multiple command execution in parallel works.
      */
-    @Ignore("TODO PID_PATTERN match flaky in CI")
+    @Disabled("TODO PID_PATTERN match flaky in CI")
     @Test
-    public void testCommandExecution() throws Exception {
+    void testCommandExecution() throws Exception {
         Thread[] t = new Thread[10];
         List results = Collections.synchronizedList(new ArrayList<>(t.length));
         for (int i = 0; i < t.length; i++) {
@@ -195,26 +191,21 @@ public void testCommandExecution() throws Exception {
         for (Thread thread : t) {
             thread.join();
         }
-        assertEquals("Not all threads finished successfully", t.length, results.size());
+        assertEquals(t.length, results.size(), "Not all threads finished successfully");
         for (ProcReturn r : results) {
-            assertEquals("Command didn't complete in time or failed", 0, r.exitCode);
-            assertTrue(
-                    "Output should contain pid: " + r.output,
-                    PID_PATTERN.matcher(r.output).find());
+            assertEquals(0, r.exitCode, "Command didn't complete in time or failed");
+            assertTrue(PID_PATTERN.matcher(r.output).find(), "Output should contain pid: " + r.output);
             assertFalse(r.proc.isAlive());
         }
     }
 
     private Thread newThread(int i, List results) {
         return new Thread(
-                new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            command(results, i);
-                        } finally {
-                            System.out.println("Thread " + i + " finished");
-                        }
+                () -> {
+                    try {
+                        command(results, i);
+                    } finally {
+                        System.out.println("Thread " + i + " finished");
                     }
                 },
                 "test-" + i);
@@ -231,42 +222,38 @@ private void command(List results, int i) {
     }
 
     @Test
-    public void testCommandExecutionFailure() throws Exception {
+    void testCommandExecutionFailure() throws Exception {
         ProcReturn r = execCommand(false, false, "false");
         assertEquals(1, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
-    public void testCommandExecutionFailureHighError() throws Exception {
+    void testCommandExecutionFailureHighError() throws Exception {
         ProcReturn r = execCommand(false, false, "sh", "-c", "return 127");
         assertEquals(127, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
-    public void testQuietCommandExecution() throws Exception {
+    void testQuietCommandExecution() throws Exception {
         ProcReturn r = execCommand(true, false, "echo", "pid is 9999");
-        assertFalse(
-                "Output should not contain command: " + r.output,
-                PID_PATTERN.matcher(r.output).find());
+        assertFalse(PID_PATTERN.matcher(r.output).find(), "Output should not contain command: " + r.output);
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
-    public void testCommandExecutionWithNohup() throws Exception {
+    void testCommandExecutionWithNohup() throws Exception {
         ProcReturn r = execCommand(
                 false, false, "nohup", "sh", "-c", "sleep 5; cd /tmp; echo pid is $$$$ > test; cat /tmp/test");
-        assertTrue(
-                "Output should contain pid: " + r.output,
-                PID_PATTERN.matcher(r.output).find());
+        assertTrue(PID_PATTERN.matcher(r.output).find(), "Output should contain pid: " + r.output);
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
-    public void commandsEscaping() {
+    void commandsEscaping() {
         DummyLauncher launcher = new DummyLauncher(null);
         assertThat(
                 ContainerExecDecorator.getCommands(launcher.launch().cmds("$$$$", "$$?"), null, true),
@@ -279,34 +266,34 @@ public void commandsEscaping() {
     }
 
     @Test
-    public void testCommandExecutionWithEscaping() throws Exception {
+    void testCommandExecutionWithEscaping() throws Exception {
         ProcReturn r =
                 execCommand(false, false, "sh", "-c", "cd /tmp; false; echo result is $$? > test; cat /tmp/test");
         assertTrue(
-                "Output should contain result: " + r.output,
                 Pattern.compile("^(result is 1)$", Pattern.MULTILINE)
                         .matcher(r.output)
-                        .find());
+                        .find(),
+                "Output should contain result: " + r.output);
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
     @Issue("JENKINS-62502")
-    public void testCommandExecutionEscapingDoubleQuotes() throws Exception {
+    void testCommandExecutionEscapingDoubleQuotes() throws Exception {
         ProcReturn r =
                 execCommand(false, false, "sh", "-c", "cd /tmp; false; echo \"result is 1\" > test; cat /tmp/test");
         assertTrue(
-                "Output should contain result: " + r.output,
                 Pattern.compile("^(result is 1)$", Pattern.MULTILINE)
                         .matcher(r.output)
-                        .find());
+                        .find(),
+                "Output should contain result: " + r.output);
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
-    public void testCommandExecutionOutput() throws Exception {
+    void testCommandExecutionOutput() throws Exception {
         String testString = "Should appear once";
 
         // Check output with quiet=false
@@ -333,7 +320,7 @@ public void testCommandExecutionOutput() throws Exception {
     }
 
     @Test
-    public void testCommandExecutionWithNohupAndError() throws Exception {
+    void testCommandExecutionWithNohupAndError() throws Exception {
         ProcReturn r = execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127");
         assertEquals(127, r.exitCode);
         assertFalse(r.proc.isAlive());
@@ -341,11 +328,12 @@ public void testCommandExecutionWithNohupAndError() throws Exception {
 
     @Test
     @Issue("JENKINS-46719")
-    public void testContainerDoesNotExist() throws Exception {
+    void testContainerDoesNotExist() {
         decorator.setContainerName("doesNotExist");
-        exception.expect(KubernetesClientException.class);
-        exception.expectMessage("container doesNotExist not found in pod");
-        execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127");
+        Throwable exception = assertThrows(
+                KubernetesClientException.class,
+                () -> execCommand(false, false, "nohup", "sh", "-c", "sleep 5; return 127"));
+        assertThat(exception.getMessage(), containsString("container doesNotExist not found in pod"));
     }
 
     /**
@@ -359,7 +347,7 @@ public void testContainerDoesNotExist() throws Exception {
      */
     @Test
     @Issue("JENKINS-55392")
-    public void testRejectedExecutionException() throws Exception {
+    void testRejectedExecutionException() throws Exception {
         List threads = new ArrayList<>();
         final AtomicInteger errors = new AtomicInteger(0);
         for (int i = 0; i < 10; i++) {
@@ -378,8 +366,8 @@ public void testRejectedExecutionException() throws Exception {
         // force expiration of client
         KubernetesClientProvider.invalidate(cloud.getDisplayName());
         cloud.connect();
-        threads.stream().forEach(t -> t.start());
-        threads.stream().forEach(t -> {
+        threads.forEach(Thread::start);
+        threads.forEach(t -> {
             try {
                 System.out.println("Waiting for " + t.getName());
                 t.join();
@@ -387,12 +375,12 @@ public void testRejectedExecutionException() throws Exception {
                 throw new RuntimeException(e);
             }
         });
-        assertEquals("Errors in threads", 0, errors.get());
+        assertEquals(0, errors.get(), "Errors in threads");
     }
 
     @Test
     @Issue("JENKINS-50429")
-    public void testContainerExecPerformance() throws Exception {
+    void testContainerExecPerformance() throws Exception {
         for (int i = 0; i < 10; i++) {
             ProcReturn r = execCommand(false, false, "ls");
         }
@@ -400,19 +388,19 @@ public void testContainerExecPerformance() throws Exception {
 
     @Test
     @Issue("JENKINS-58975")
-    public void testContainerExecOnCustomWorkingDir() throws Exception {
+    void testContainerExecOnCustomWorkingDir() throws Exception {
         doReturn(null).when((Node) agent).toComputer();
         ProcReturn r = execCommandInContainer("busybox1", agent, false, false, "env");
         assertTrue(
-                "Environment variable workingDir1 should be changed to /home/jenkins/agent1",
-                r.output.contains("workingDir1=/home/jenkins/agent1"));
+                r.output.contains("workingDir1=/home/jenkins/agent1"),
+                "Environment variable workingDir1 should be changed to /home/jenkins/agent1");
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
     @Test
     @Issue("JENKINS-58975")
-    public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Exception {
+    void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Exception {
         EnvVars computeEnvVars = new EnvVars();
         computeEnvVars.put("MyDir", "dir");
         computeEnvVars.put("MyCustomDir", "/home/jenkins/agent");
@@ -422,11 +410,11 @@ public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Excep
         doReturn(computer).when((Node) agent).toComputer();
         ProcReturn r = execCommandInContainer("busybox1", agent, false, false, "env");
         assertTrue(
-                "Environment variable workingDir1 should be changed to /home/jenkins/agent1",
-                r.output.contains("workingDir1=/home/jenkins/agent1"));
+                r.output.contains("workingDir1=/home/jenkins/agent1"),
+                "Environment variable workingDir1 should be changed to /home/jenkins/agent1");
         assertTrue(
-                "Environment variable MyCustomDir should be changed to /home/jenkins/agent1",
-                r.output.contains("MyCustomDir=/home/jenkins/agent1"));
+                r.output.contains("MyCustomDir=/home/jenkins/agent1"),
+                "Environment variable MyCustomDir should be changed to /home/jenkins/agent1");
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
@@ -440,9 +428,10 @@ public void testContainerExecOnCustomWorkingDirWithComputeEnvVars() throws Excep
      */
     @Test
     @Issue("JENKINS-66986")
-    public void testRunningANonKubernetesNodeInsideContainerClause() throws Exception {
+    void testRunningANonKubernetesNodeInsideContainerClause() throws Exception {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out)));
+        DummyLauncher dummyLauncher =
+                new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8));
         dumbAgent = j.createSlave("test", "", null);
         Launcher launcher = decorator.decorate(dummyLauncher, dumbAgent);
         assertEquals(dummyLauncher, launcher);
@@ -458,7 +447,8 @@ private ProcReturn execCommandInContainer(
             decorator.setContainerName(containerName);
         }
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out)));
+        DummyLauncher dummyLauncher =
+                new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8));
         Launcher launcher = decorator.decorate(dummyLauncher, node);
         Map envs = new HashMap<>(100);
         for (int i = 0; i < 50; i++) {
@@ -476,12 +466,12 @@ private ProcReturn execCommandInContainer(
         for (int i = 0; proc.isAlive() && i < 200; i++) {
             Thread.sleep(100);
         }
-        assertFalse("proc is alive", proc.isAlive());
+        assertFalse(proc.isAlive(), "proc is alive");
         int exitCode = proc.join();
         return new ProcReturn(proc, exitCode, out.toString());
     }
 
-    class ProcReturn {
+    static class ProcReturn {
         public int exitCode;
         public String output;
         public ContainerExecProc proc;
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java
index 4dd73abe8b..a5e8fb4e44 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerExecDecoratorWindowsTest.java
@@ -30,8 +30,8 @@
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.setupCloud;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -62,23 +62,20 @@
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.jenkinsci.plugins.workflow.steps.StepContext;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.junit.rules.TestName;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.jvnet.hudson.test.recipes.WithTimeout;
 
-public class ContainerExecDecoratorWindowsTest {
-    @Rule
-    public ExpectedException exception = ExpectedException.none();
+@WithJenkins
+class ContainerExecDecoratorWindowsTest {
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
 
     private KubernetesCloud cloud;
     private static KubernetesClient client;
@@ -88,22 +85,23 @@ public class ContainerExecDecoratorWindowsTest {
     private Pod pod;
     private KubernetesSlave agent;
 
-    @Rule
-    public LoggerRule containerExecLogs = new LoggerRule()
+    @SuppressWarnings("unused")
+    private final LogRecorder containerExecLogs = new LogRecorder()
             .record(Logger.getLogger(ContainerExecDecorator.class.getName()), Level.ALL)
             .record(Logger.getLogger(KubernetesClientProvider.class.getName()), Level.ALL);
 
-    @Rule
-    public TestName name = new TestName();
+    private String name;
 
-    @BeforeClass
-    public static void setUpClass() throws Exception {
+    @BeforeAll
+    static void beforeAll() {
         assumeKubernetes();
         assumeWindows(WINDOWS_1809_BUILD);
     }
 
-    @Before
-    public void configureCloud() throws Exception {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule, TestInfo info) throws Exception {
+        j = rule;
+        name = info.getTestMethod().orElseThrow().getName();
         cloud = setupCloud(this, name);
         client = cloud.connect();
         deletePods(client, getLabels(this, name), false);
@@ -147,39 +145,40 @@ public void configureCloud() throws Exception {
         decorator.setContainerName(image);
     }
 
-    @After
-    public void after() throws Exception {
+    @AfterEach
+    void afterEach() throws Exception {
         client.pods().delete(pod);
         deletePods(client, getLabels(this, name), true);
     }
 
+    // in case we need to pull windows docker image
     @Test
-    @WithTimeout(value = 900) // in case we need to pull windows docker image
-    public void testCommandExecution() throws Exception {
+    @WithTimeout(value = 900)
+    void testCommandExecution() throws Exception {
         ByteArrayOutputStream output = new ByteArrayOutputStream();
         ProcReturn r = execCommandInContainer("container", null, false, output, "where", "cmd.exe");
-        assertEquals("C:\\Windows\\System32\\cmd.exe\r\n", output.toString(StandardCharsets.UTF_8.name()));
+        assertEquals("C:\\Windows\\System32\\cmd.exe\r\n", output.toString(StandardCharsets.UTF_8));
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
+    // in case we need to pull windows docker image
     @Test
-    @WithTimeout(value = 900) // in case we need to pull windows docker image
-    public void testCommandExecutionNoOutput() throws Exception {
+    @WithTimeout(value = 900)
+    void testCommandExecutionNoOutput() throws Exception {
         ProcReturn r = execCommandInContainer("container", null, false, null, "where", "cmd.exe");
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
 
+    // in case we need to pull windows docker image
     @Test
-    @WithTimeout(value = 900) // in case we need to pull windows docker image
-    public void testQuietCommandExecution() throws Exception {
+    @WithTimeout(value = 900)
+    void testQuietCommandExecution() throws Exception {
         ByteArrayOutputStream output = new ByteArrayOutputStream();
         ProcReturn r = execCommandInContainer("container", null, true, output, "echo", "pid is 9999");
-        String out = output.toString(StandardCharsets.UTF_8.name());
-        assertFalse(
-                "Output should not contain command: " + out,
-                PID_PATTERN.matcher(out).find());
+        String out = output.toString(StandardCharsets.UTF_8);
+        assertFalse(PID_PATTERN.matcher(out).find(), "Output should not contain command: " + out);
         assertEquals(0, r.exitCode);
         assertFalse(r.proc.isAlive());
     }
@@ -189,12 +188,14 @@ private ProcReturn execCommandInContainer(
             throws Exception {
         decorator.setContainerName(containerName);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        DummyLauncher dummyLauncher = new DummyLauncher(new StreamTaskListener(new TeeOutputStream(out, System.out))) {
-            @Override
-            public boolean isUnix() {
-                return false;
-            }
-        };
+        DummyLauncher dummyLauncher =
+                new DummyLauncher(
+                        new StreamTaskListener(new TeeOutputStream(out, System.out), StandardCharsets.UTF_8)) {
+                    @Override
+                    public boolean isUnix() {
+                        return false;
+                    }
+                };
         Launcher launcher = decorator.decorate(dummyLauncher, node);
         Map envs = new HashMap<>(100);
         for (int i = 0; i < 50; i++) {
@@ -212,12 +213,12 @@ public boolean isUnix() {
         for (int i = 0; proc.isAlive() && i < 200; i++) {
             Thread.sleep(100);
         }
-        assertFalse("proc is alive", proc.isAlive());
+        assertFalse(proc.isAlive(), "proc is alive");
         int exitCode = proc.join();
         return new ProcReturn(proc, exitCode, out.toString());
     }
 
-    class ProcReturn {
+    static class ProcReturn {
         public int exitCode;
         public String output;
         public ContainerExecProc proc;
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java
index ba168814eb..04e8dce1d8 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ContainerLogStepTest.java
@@ -16,16 +16,16 @@
 
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 
-public class ContainerLogStepTest extends AbstractKubernetesPipelineTest {
+class ContainerLogStepTest extends AbstractKubernetesPipelineTest {
 
     @Issue("JENKINS-46085")
     @Test
-    public void getContainerLog() throws Exception {
+    void getContainerLog() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("INFO: Handshaking", b);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java
index 9713823cf8..32e30224ba 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/DirectConnectionTest.java
@@ -20,25 +20,29 @@
 import java.util.logging.Level;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.jvnet.hudson.test.JenkinsRule;
 
-public final class DirectConnectionTest extends AbstractKubernetesPipelineTest {
+class DirectConnectionTest extends AbstractKubernetesPipelineTest {
 
     static {
         System.setProperty(
                 TcpSlaveAgentListener.class.getName() + ".hostName", System.getProperty("jenkins.host.address"));
     }
 
-    @Before
-    public void setUp() throws Exception {
+    @Override
+    @BeforeEach
+    protected void beforeEach(JenkinsRule rule, TestInfo info) throws Exception {
+        super.beforeEach(rule, info);
         KubernetesTestUtil.deletePods(cloud.connect(), KubernetesTestUtil.getLabels(cloud, this, name), false);
         cloud.setDirectConnection(true);
         logs.record(PodTemplateBuilder.class, Level.FINEST);
     }
 
     @Test
-    public void directConnectionAgent() throws Exception {
+    void directConnectionAgent() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(createJobThenScheduleRun()));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java
index 20d114cf0f..d095035483 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesAgentErrorConditionTest.java
@@ -29,38 +29,44 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.jvnet.hudson.test.BuildWatcher;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
 @Issue("JENKINS-49707")
-public class KubernetesAgentErrorConditionTest {
+@WithJenkins
+class KubernetesAgentErrorConditionTest {
 
-    @ClassRule
-    public static BuildWatcher buildWatcher = new BuildWatcher();
+    @SuppressWarnings("unused")
+    private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension();
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    private JenkinsRule r;
 
-    @Rule
-    public LoggerRule logging = new LoggerRule().record(KubernetesAgentErrorCondition.class, Level.FINE);
+    @SuppressWarnings("unused")
+    private final LogRecorder logging = new LogRecorder().record(KubernetesAgentErrorCondition.class, Level.FINE);
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
+    }
 
     @Test
-    public void handleNonKubernetes() throws Exception {
+    void handleNonKubernetes() throws Exception {
         Slave s = r.createSlave(Label.get("remote")); // *not* a KubernetesSlave
         WorkflowJob p = r.createProject(WorkflowJob.class, "p");
         p.addProperty(new ParametersDefinitionProperty(new BooleanParameterDefinition("HNK")));
         p.setDefinition(new CpsFlowDefinition(
-                "retry(count: 2, conditions: [kubernetesAgent(handleNonKubernetes: params.HNK)]) {\n"
-                        + "  node('remote') {\n"
-                        + "    semaphore 'wait'\n"
-                        + "    pwd()\n"
-                        + "  }\n"
-                        + "}",
+                """
+                        retry(count: 2, conditions: [kubernetesAgent(handleNonKubernetes: params.HNK)]) {
+                          node('remote') {
+                            semaphore 'wait'
+                            pwd()
+                          }
+                        }""",
                 true));
         WorkflowRun b = p.scheduleBuild2(0, new ParametersAction(new BooleanParameterValue("HNK", false)))
                 .waitForStart();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java
index 5b41ad3864..4760ddb172 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentRJRTest.java
@@ -16,20 +16,19 @@
 
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import java.net.UnknownHostException;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public final class KubernetesDeclarativeAgentRJRTest extends AbstractKubernetesPipelineRJRTest {
+class KubernetesDeclarativeAgentRJRTest extends AbstractKubernetesPipelineRJRTest {
 
-    public KubernetesDeclarativeAgentRJRTest() throws UnknownHostException {
+    public KubernetesDeclarativeAgentRJRTest() throws Exception {
         super(new SetupCloud());
     }
 
     @Test
-    public void declarative() throws Throwable {
+    void declarative() throws Throwable {
         RunId runId = createWorkflowJobThenScheduleRun();
         rjr.runRemotely(new AssertBuildStatusSuccess(runId));
     }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java
index 098b0ee30b..92fb160d62 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentTest.java
@@ -27,7 +27,7 @@
 // Required for workflow-api graph analysis
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 
 import com.google.common.base.Predicates;
 import hudson.model.Result;
@@ -35,6 +35,7 @@
 import java.util.Map;
 import jenkins.plugins.git.GitSampleRepoRule;
 import jenkins.plugins.git.GitStep;
+import jenkins.plugins.git.junit.jupiter.WithGitSampleRepo;
 import org.csanchez.jenkins.plugins.kubernetes.pod.retention.OnFailure;
 import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable;
 import org.jenkinsci.plugins.workflow.actions.ArgumentsAction;
@@ -44,18 +45,23 @@
 import org.jenkinsci.plugins.workflow.graphanalysis.FlowScanningUtils;
 import org.jenkinsci.plugins.workflow.graphanalysis.NodeStepTypePredicate;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 
-public class KubernetesDeclarativeAgentTest extends AbstractKubernetesPipelineTest {
+@WithGitSampleRepo
+class KubernetesDeclarativeAgentTest extends AbstractKubernetesPipelineTest {
 
-    @Rule
-    public GitSampleRepoRule repoRule = new GitSampleRepoRule();
+    private GitSampleRepoRule repoRule;
+
+    @BeforeEach
+    void beforeEach(GitSampleRepoRule repo) {
+        repoRule = repo;
+    }
 
     @Issue({"JENKINS-41758", "JENKINS-57827", "JENKINS-60886"})
     @Test
-    public void declarative() throws Exception {
+    void declarative() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("Apache Maven 3.3.9", b);
@@ -67,7 +73,7 @@ public void declarative() throws Exception {
                         Predicates.and(
                                 new NodeStepTypePredicate("podTemplate"),
                                 FlowScanningUtils.hasActionPredicate(ArgumentsAction.class)));
-        assertNotNull("recorded arguments for podTemplate", podTemplateNode);
+        assertNotNull(podTemplateNode, "recorded arguments for podTemplate");
         Map arguments =
                 podTemplateNode.getAction(ArgumentsAction.class).getArguments();
         FlowNode nodeNode = new DepthFirstScanner()
@@ -76,7 +82,7 @@ public void declarative() throws Exception {
                         Predicates.and(
                                 new NodeStepTypePredicate("node"),
                                 FlowScanningUtils.hasActionPredicate(ArgumentsAction.class)));
-        assertNotNull("recorded arguments for node", nodeNode);
+        assertNotNull(nodeNode, "recorded arguments for node");
         Map nodeArguments =
                 nodeNode.getAction(ArgumentsAction.class).getArguments();
         assertEquals("labels && multiple", nodeArguments.get("label"));
@@ -84,24 +90,23 @@ public void declarative() throws Exception {
         List containers = (List) arguments.get("containers");
         assertNotNull(containers);
         assertFalse(
-                "no junk in arguments: " + arguments,
-                containers.get(0).getArguments().containsKey("alwaysPullImage"));
+                containers.get(0).getArguments().containsKey("alwaysPullImage"), "no junk in arguments: " + arguments);
         FlowNode containerNode = new DepthFirstScanner()
                 .findFirstMatch(
                         b.getExecution(),
                         Predicates.and(
                                 new NodeStepTypePredicate("container"),
                                 FlowScanningUtils.hasActionPredicate(ArgumentsAction.class)));
-        assertNotNull("recorded arguments for container", containerNode);
+        assertNotNull(containerNode, "recorded arguments for container");
         // JENKINS-60886
         UninstantiatedDescribable podRetention = (UninstantiatedDescribable) arguments.get("podRetention");
         assertNotNull(podRetention);
-        assertEquals(podRetention.getModel().getType(), OnFailure.class);
+        assertEquals(OnFailure.class, podRetention.getModel().getType());
     }
 
     @Issue("JENKINS-48135")
     @Test
-    public void declarativeFromYaml() throws Exception {
+    void declarativeFromYaml() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("Apache Maven 3.3.9", b);
@@ -112,7 +117,7 @@ public void declarativeFromYaml() throws Exception {
 
     @Issue("JENKINS-51610")
     @Test
-    public void declarativeWithNamespaceFromYaml() throws Exception {
+    void declarativeWithNamespaceFromYaml() throws Exception {
         createNamespaceIfNotExist(cloud.connect(), "kubernetes-plugin-test-overridden-namespace");
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
@@ -124,7 +129,7 @@ public void declarativeWithNamespaceFromYaml() throws Exception {
 
     @Issue("JENKINS-52259")
     @Test
-    public void declarativeFromYamlFile() throws Exception {
+    void declarativeFromYamlFile() throws Exception {
         repoRule.init();
         repoRule.write("Jenkinsfile", loadPipelineDefinition());
         repoRule.write("declarativeYamlFile.yml", loadPipelineScript("declarativeYamlFile.yml"));
@@ -144,7 +149,7 @@ public void declarativeFromYamlFile() throws Exception {
     }
 
     @Test
-    public void declarativeFromYamlWithNullEnv() throws Exception {
+    void declarativeFromYamlWithNullEnv() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("\njnlp container: OK\n", b);
@@ -153,7 +158,7 @@ public void declarativeFromYamlWithNullEnv() throws Exception {
 
     @Issue("JENKINS-52623")
     @Test
-    public void declarativeSCMVars() throws Exception {
+    void declarativeSCMVars() throws Exception {
         p = r.jenkins.createProject(WorkflowJob.class, "job with repo");
         // We can't use a local GitSampleRepoRule for this because the repo has to be accessible from within the
         // container.
@@ -166,7 +171,7 @@ public void declarativeSCMVars() throws Exception {
 
     @Issue("JENKINS-53817")
     @Test
-    public void declarativeCustomWorkspace() throws Exception {
+    void declarativeCustomWorkspace() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("Apache Maven 3.3.9", b);
@@ -175,7 +180,7 @@ public void declarativeCustomWorkspace() throws Exception {
 
     @Issue("JENKINS-58975")
     @Test
-    public void declarativeCustomWorkingDir() throws Exception {
+    void declarativeCustomWorkingDir() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains(
@@ -191,7 +196,7 @@ public void declarativeCustomWorkingDir() throws Exception {
 
     @Issue("JENKINS-57548")
     @Test
-    public void declarativeWithNestedExplicitInheritance() throws Exception {
+    void declarativeWithNestedExplicitInheritance() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("Apache Maven 3.3.9", b);
@@ -199,14 +204,14 @@ public void declarativeWithNestedExplicitInheritance() throws Exception {
     }
 
     @Test
-    public void declarativeWithNonexistentDockerImage() throws Exception {
+    void declarativeWithNonexistentDockerImage() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("ERROR: Unable to pull container image", b);
     }
 
     @Test
-    public void declarativeWithCreateContainerError() throws Exception {
+    void declarativeWithCreateContainerError() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("was terminated", b);
@@ -214,7 +219,7 @@ public void declarativeWithCreateContainerError() throws Exception {
 
     @Issue("JENKINS-61360")
     @Test
-    public void declarativeShowRawYamlFalse() throws Exception {
+    void declarativeShowRawYamlFalse() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         // check yaml metadata labels not logged
@@ -223,7 +228,7 @@ public void declarativeShowRawYamlFalse() throws Exception {
 
     @Issue("JENKINS-49707")
     @Test
-    public void declarativeRetries() throws Exception {
+    void declarativeRetries() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.waitForMessage("+ sleep", b);
         deletePods(cloud.connect(), getLabels(this, name), false);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java
index 13926cbec0..46f10185cf 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesDeclarativeAgentUnitTest.java
@@ -11,35 +11,42 @@
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume;
 import org.jenkinsci.plugins.pipeline.modeldefinition.generator.AgentDirective;
 import org.jenkinsci.plugins.pipeline.modeldefinition.generator.DirectiveGeneratorTester;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class KubernetesDeclarativeAgentUnitTest {
-    @ClassRule
-    public static JenkinsRule j = new JenkinsRule();
+@WithJenkins
+class KubernetesDeclarativeAgentUnitTest {
 
-    KubernetesDeclarativeAgent instance;
+    private static JenkinsRule j;
 
-    DirectiveGeneratorTester dg;
-    AgentDirective directive;
+    private KubernetesDeclarativeAgent instance;
 
-    @Before
-    public void setUp() {
+    private DirectiveGeneratorTester dg;
+    private AgentDirective directive;
+
+    @BeforeAll
+    static void beforeAll(JenkinsRule rule) {
+        j = rule;
+    }
+
+    @BeforeEach
+    void beforeEach() {
         instance = new KubernetesDeclarativeAgent();
         directive = new AgentDirective(instance);
         dg = new DirectiveGeneratorTester(j);
     }
 
     @Test
-    public void serializationNull() {
+    void serializationNull() {
         Map args = instance.getAsArgs();
         assertThat(args, equalTo(Collections.emptyMap()));
     }
 
     @Test
-    public void serialization() throws Exception {
+    void serialization() {
         instance.setCloud("cloud");
         instance.setLabel("label");
         instance.setYaml("yaml");
@@ -67,12 +74,16 @@ public void serialization() throws Exception {
     }
 
     @Test
-    public void simpleGenerator() throws Exception {
-        dg.assertGenerateDirective(directive, "agent {\n" + "  kubernetes true\n" + "}");
+    void simpleGenerator() throws Exception {
+        dg.assertGenerateDirective(
+                directive, """
+                agent {
+                  kubernetes true
+                }""");
     }
 
     @Test
-    public void complexGenerator() throws Exception {
+    void complexGenerator() throws Exception {
         instance.setCloud("cloud");
         instance.setYaml("yaml");
         instance.setYamlMergeStrategy(new Merge());
@@ -85,14 +96,16 @@ public void complexGenerator() throws Exception {
         instance.setInheritFrom("inheritFrom");
         dg.assertGenerateDirective(
                 directive,
-                "agent {\n" + "  kubernetes {\n"
-                        + "    cloud 'cloud'\n"
-                        + "    inheritFrom 'inheritFrom'\n"
-                        + "    podRetention never()\n"
-                        + "    workspaceVolume dynamicPVC(accessModes: 'ReadWrite', requestsSize: '1G', storageClassName: 'sc')\n"
-                        + "    yaml 'yaml'\n"
-                        + "    yamlMergeStrategy merge()\n"
-                        + "  }\n"
-                        + "}");
+                """
+                        agent {
+                          kubernetes {
+                            cloud 'cloud'
+                            inheritFrom 'inheritFrom'
+                            podRetention never()
+                            workspaceVolume dynamicPVC(accessModes: 'ReadWrite', requestsSize: '1G', storageClassName: 'sc')
+                            yaml 'yaml'
+                            yamlMergeStrategy merge()
+                          }
+                        }""");
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java
index f038893e4d..2eddf46762 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesNodeContextTest.java
@@ -1,6 +1,6 @@
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
@@ -10,14 +10,17 @@
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave;
 import org.jenkinsci.plugins.workflow.steps.StepContext;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
 
-@RunWith(MockitoJUnitRunner.class)
-public class KubernetesNodeContextTest {
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+class KubernetesNodeContextTest {
 
     @Mock
     private StepContext context;
@@ -31,15 +34,15 @@ public class KubernetesNodeContextTest {
     @Mock
     private PodResource podResource;
 
-    @Before
-    public void setup() {
+    @BeforeEach
+    void beforeEach() {
         when(slave.getKubernetesCloud()).thenReturn(cloud);
         when(slave.getPodName()).thenReturn("foo");
         when(slave.getNamespace()).thenReturn("bar");
     }
 
     @Test
-    public void createContext() throws Exception {
+    void createContext() throws Exception {
         when(cloud.getPodResource("bar", "foo")).thenReturn(podResource);
         when(context.get(Node.class)).thenReturn(slave);
         KubernetesNodeContext knc = new KubernetesNodeContext(context);
@@ -50,14 +53,10 @@ public void createContext() throws Exception {
     }
 
     @Test
-    public void notKubernetesSlaveInstance() throws Exception {
+    void notKubernetesSlaveInstance() throws Exception {
         Node node = mock(Node.class);
         when(context.get(Node.class)).thenReturn(node);
-        try {
-            new KubernetesNodeContext(context);
-            fail("expected abort exception");
-        } catch (AbortException ae) {
-            assertTrue(ae.getMessage().startsWith("Node is not a Kubernetes node"));
-        }
+        AbortException ae = assertThrows(AbortException.class, () -> new KubernetesNodeContext(context));
+        assertTrue(ae.getMessage().startsWith("Node is not a Kubernetes node"));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java
similarity index 84%
rename from src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java
rename to src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java
index b6ec70ae68..4b65548d9d 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverridenNamespaceTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineOverriddenNamespaceTest.java
@@ -1,19 +1,19 @@
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.testingNamespace;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.util.HashMap;
 import java.util.Map;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesComputer;
 import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class KubernetesPipelineOverridenNamespaceTest extends AbstractKubernetesPipelineTest {
+class KubernetesPipelineOverriddenNamespaceTest extends AbstractKubernetesPipelineTest {
 
     @Test
-    public void runWithCloudOverriddenNamespace() throws Exception {
+    void runWithCloudOverriddenNamespace() throws Exception {
         String overriddenNamespace = testingNamespace + "-overridden-namespace";
         cloud.setNamespace(overriddenNamespace);
         // Run in our own testing namespace
@@ -36,7 +36,7 @@ public void runWithCloudOverriddenNamespace() throws Exception {
      * Step namespace should have priority over anything else.
      */
     @Test
-    public void runWithStepOverriddenNamespace() throws Exception {
+    void runWithStepOverriddenNamespace() throws Exception {
         String overriddenNamespace = testingNamespace + "-overridden-namespace";
         String stepNamespace = testingNamespace + "-overridden-namespace2";
         cloud.setNamespace(overriddenNamespace);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java
index 71e4a484ef..5fa02969fe 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineRJRTest.java
@@ -3,31 +3,31 @@
 import io.fabric8.kubernetes.api.model.NodeBuilder;
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClientBuilder;
-import java.net.UnknownHostException;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildLogMessage;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.CreateWorkflowJobThenScheduleTask;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class KubernetesPipelineRJRTest extends AbstractKubernetesPipelineRJRTest {
-    public KubernetesPipelineRJRTest() throws UnknownHostException {
+class KubernetesPipelineRJRTest extends AbstractKubernetesPipelineRJRTest {
+
+    public KubernetesPipelineRJRTest() throws Exception {
         super(new SetupCloud());
     }
 
     @Test
-    public void basicPipeline() throws Throwable {
+    void basicPipeline() throws Throwable {
         RunId runId = createWorkflowJobThenScheduleRun();
         rjr.runRemotely(new AssertBuildStatusSuccess(runId));
     }
 
     @Test
-    public void restartDuringPodLaunch() throws Throwable {
+    void restartDuringPodLaunch() throws Throwable {
         // try to run something on a pod which is not schedulable (disktype=special)
         RunId build = rjr.runRemotely(new CreateWorkflowJobThenScheduleTask(
-                KubernetesTestUtil.loadPipelineScript(getClass(), name.getMethodName() + ".groovy")));
+                KubernetesTestUtil.loadPipelineScript(getClass(), name + ".groovy")));
         // the pod is created, but not connected yet
         rjr.runRemotely(new AssertBuildLogMessage("Created Pod", build));
         // restart
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java
index 9bf52f86d5..bf8afe805b 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineTest.java
@@ -39,13 +39,8 @@
 import static org.hamcrest.Matchers.hasSize;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.oneOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeNoException;
-import static org.junit.Assume.assumeNotNull;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assumptions.assumeTrue;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
 import hudson.model.Computer;
@@ -88,44 +83,34 @@
 import org.htmlunit.html.DomNodeUtil;
 import org.htmlunit.html.HtmlElement;
 import org.htmlunit.html.HtmlPage;
-import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
 import org.jenkinsci.plugins.workflow.flow.FlowDurabilityHint;
 import org.jenkinsci.plugins.workflow.flow.GlobalDefaultFlowDurabilityLevel;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep;
 import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.jvnet.hudson.test.FlagRule;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
 import org.jvnet.hudson.test.MockAuthorizationStrategy;
 import org.jvnet.hudson.test.TestExtension;
 
-public class KubernetesPipelineTest extends AbstractKubernetesPipelineTest {
+class KubernetesPipelineTest extends AbstractKubernetesPipelineTest {
 
     private static final Logger LOGGER = Logger.getLogger(KubernetesPipelineTest.class.getName());
     public static final String POD_DEADLINE_EXCEEDED_MESSAGE =
             "Pod just failed. Reason: DeadlineExceeded, Message: Pod was active on the node longer than the specified deadline.";
 
-    @Rule
-    public TemporaryFolder tmp = new TemporaryFolder();
+    private final LogRecorder warnings = new LogRecorder().quiet();
 
-    @Rule
-    public LoggerRule warnings = new LoggerRule().quiet();
+    private boolean substituteEnv;
 
-    @Rule
-    public FlagRule substituteEnv =
-            new FlagRule<>(() -> PodTemplateUtils.SUBSTITUTE_ENV, x -> PodTemplateUtils.SUBSTITUTE_ENV = x);
-
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void beforeEach() throws Exception {
+        substituteEnv = PodTemplateUtils.SUBSTITUTE_ENV;
         // Had some problems with FileChannel.close hangs from WorkflowRun.save:
         r.jenkins
                 .getDescriptorByType(GlobalDefaultFlowDurabilityLevel.DescriptorImpl.class)
@@ -137,8 +122,10 @@ public void setUp() throws Exception {
     /**
      * Ensure all builds are complete by the end of the test.
      */
-    @After
-    public void allDead() throws Exception {
+    @AfterEach
+    void afterEach() throws Exception {
+        PodTemplateUtils.SUBSTITUTE_ENV = substituteEnv;
+
         if (b != null && b.isLogUpdated()) {
             LOGGER.warning(() -> "Had to interrupt " + b);
             b.getExecutor().interrupt();
@@ -161,15 +148,15 @@ public void allDead() throws Exception {
 
     @Issue("JENKINS-57993")
     @Test
-    public void runInPod() throws Exception {
+    void runInPod() throws Exception {
         warnings.record("", Level.WARNING).capture(1000);
         SemaphoreStep.waitForStart("podTemplate/1", b);
-        List templates = podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates());
+        List templates = podTemplatesWithLabel(name, cloud.getAllTemplates());
         assertThat(templates, hasSize(1));
         SemaphoreStep.success("podTemplate/1", null);
 
         // check if build failed
-        assertTrue("Build has failed early: " + b.getResult(), b.isBuilding() || Result.SUCCESS.equals(b.getResult()));
+        assertTrue(b.isBuilding() || Result.SUCCESS.equals(b.getResult()), "Build has failed early: " + b.getResult());
 
         LOGGER.log(Level.INFO, "Found templates with label runInPod: {0}", templates);
         for (PodTemplate template : cloud.getAllTemplates()) {
@@ -204,7 +191,7 @@ public void runInPod() throws Exception {
         PodList pods = cloud.connect().pods().withLabels(labels).list();
         assertThat(
                 "Expected one pod with labels " + labels + " but got: "
-                        + pods.getItems().stream().map(pod -> pod.getMetadata()).collect(Collectors.toList()),
+                        + pods.getItems().stream().map(Pod::getMetadata).toList(),
                 pods.getItems(),
                 hasSize(1));
         SemaphoreStep.success("pod/1", null);
@@ -221,26 +208,23 @@ public void runInPod() throws Exception {
         }
         assertTrue(foundBuildUrl);
         assertEquals(Integer.MAX_VALUE, template.getInstanceCap());
-        assertThat(template.getLabelsMap(), hasEntry("jenkins/label", name.getMethodName()));
+        assertThat(template.getLabelsMap(), hasEntry("jenkins/label", name));
 
         Pod pod = pods.getItems().get(0);
         LOGGER.log(Level.INFO, "One pod found: {0}", pod);
         assertThat(pod.getMetadata().getLabels(), hasEntry("jenkins", "slave"));
-        assertThat(
-                "Pod labels are wrong: " + pod,
-                pod.getMetadata().getLabels(),
-                hasEntry("jenkins/label", name.getMethodName()));
+        assertThat("Pod labels are wrong: " + pod, pod.getMetadata().getLabels(), hasEntry("jenkins/label", name));
 
         SemaphoreStep.waitForStart("after-podtemplate/1", b);
-        assertThat(podTemplatesWithLabel(name.getMethodName(), cloud.getAllTemplates()), hasSize(0));
+        assertThat(podTemplatesWithLabel(name, cloud.getAllTemplates()), hasSize(0));
         SemaphoreStep.success("after-podtemplate/1", null);
 
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("container=busybox", b);
         r.assertLogContains("script file contents: ", b);
         assertFalse(
-                "There are pods leftover after test execution, see previous logs",
-                deletePods(cloud.connect(), getLabels(cloud, this, name), true));
+                deletePods(cloud.connect(), getLabels(cloud, this, name), true),
+                "There are pods leftover after test execution, see previous logs");
         assertThat(
                 "routine build should not issue warnings",
                 warnings.getRecords().stream()
@@ -254,9 +238,9 @@ public void runInPod() throws Exception {
     }
 
     @Test
-    public void runIn2Pods() throws Exception {
+    void runIn2Pods() throws Exception {
         SemaphoreStep.waitForStart("podTemplate1/1", b);
-        String label1 = name.getMethodName() + "-1";
+        String label1 = name + "-1";
         PodTemplate template1 =
                 podTemplatesWithLabel(label1, cloud.getAllTemplates()).get(0);
         SemaphoreStep.success("podTemplate1/1", null);
@@ -270,13 +254,13 @@ public void runIn2Pods() throws Exception {
         SemaphoreStep.success("pod1/1", null);
 
         SemaphoreStep.waitForStart("podTemplate2/1", b);
-        String label2 = name.getMethodName() + "-2";
+        String label2 = name + "-2";
         PodTemplate template2 =
                 podTemplatesWithLabel(label2, cloud.getAllTemplates()).get(0);
         SemaphoreStep.success("podTemplate2/1", null);
         assertEquals(Integer.MAX_VALUE, template2.getInstanceCap());
         assertThat(template2.getLabelsMap(), hasEntry("jenkins/label", label2));
-        assertNull(label2 + " should not inherit from anything", template2.getInheritFrom());
+        assertNull(template2.getInheritFrom(), label2 + " should not inherit from anything");
         SemaphoreStep.waitForStart("pod2/1", b);
         Map labels2 = getLabels(cloud, this, name);
         labels1.put("jenkins/label", label2);
@@ -286,13 +270,13 @@ public void runIn2Pods() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("script file contents: ", b);
         assertFalse(
-                "There are pods leftover after test execution, see previous logs",
-                deletePods(cloud.connect(), getLabels(cloud, this, name), true));
+                deletePods(cloud.connect(), getLabels(cloud, this, name), true),
+                "There are pods leftover after test execution, see previous logs");
     }
 
     @Issue({"JENKINS-57893", "SECURITY-3079"})
     @Test
-    public void runInPodFromYaml() throws Exception {
+    void runInPodFromYaml() throws Exception {
         List templates = cloud.getTemplates();
         while (templates.isEmpty()) {
             LOGGER.log(Level.INFO, "Waiting for template to be created");
@@ -310,8 +294,8 @@ public void runInPodFromYaml() throws Exception {
                         + CONTAINER_ENV_VAR_FROM_SECRET_VALUE.toUpperCase(Locale.ROOT) + "\n",
                 b);
         assertFalse(
-                "There are pods leftover after test execution, see previous logs",
-                deletePods(cloud.connect(), getLabels(cloud, this, name), true));
+                deletePods(cloud.connect(), getLabels(cloud, this, name), true),
+                "There are pods leftover after test execution, see previous logs");
 
         // SECURITY-3079
         DurableTaskStep.USE_WATCHING = true;
@@ -329,20 +313,20 @@ public void runInPodFromYaml() throws Exception {
     }
 
     @Test
-    public void runInPodWithDifferentShell() throws Exception {
+    void runInPodWithDifferentShell() throws Exception {
         r.assertBuildStatus(Result.FAILURE, r.waitForCompletion(b));
         r.assertLogContains("ERROR: Process exited immediately after creation", b);
         // r.assertLogContains("/bin/bash: no such file or directory", b); // Not printed in CI for an unknown reason.
     }
 
     @Test
-    public void bourneShellElsewhereInPath() throws Exception {
+    void bourneShellElsewhereInPath() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("/kaniko:/busybox", b);
     }
 
     @Test
-    public void inheritFrom() throws Exception {
+    void inheritFrom() throws Exception {
         PodTemplate standard = new PodTemplate();
         standard.setName("standard");
         cloud.addTemplate(standard);
@@ -350,7 +334,7 @@ public void inheritFrom() throws Exception {
     }
 
     @Test
-    public void runInPodWithMultipleContainers() throws Exception {
+    void runInPodWithMultipleContainers() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b);
         r.assertLogContains("image: \"golang:1.6.3-alpine\"", b);
@@ -360,7 +344,7 @@ public void runInPodWithMultipleContainers() throws Exception {
     }
 
     @Test
-    public void runInPodNested() throws Exception {
+    void runInPodNested() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b);
         r.assertLogContains("image: \"golang:1.6.3-alpine\"", b);
@@ -370,7 +354,7 @@ public void runInPodNested() throws Exception {
 
     @Issue("JENKINS-57548")
     @Test
-    public void runInPodNestedExplicitInherit() throws Exception {
+    void runInPodNestedExplicitInherit() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("image: \"maven:3.3.9-jdk-8-alpine\"", b);
         r.assertLogNotContains("image: \"golang:1.6.3-alpine\"", b);
@@ -380,7 +364,7 @@ public void runInPodNestedExplicitInherit() throws Exception {
 
     @Issue({"JENKINS-57893", "JENKINS-58540"})
     @Test
-    public void runInPodWithExistingTemplate() throws Exception {
+    void runInPodWithExistingTemplate() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("outside container", b);
         r.assertLogContains("inside container", b);
@@ -389,7 +373,7 @@ public void runInPodWithExistingTemplate() throws Exception {
 
     @Issue({"JENKINS-57893", "JENKINS-58540"})
     @Test
-    public void runWithEnvVariables() throws Exception {
+    void runWithEnvVariables() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         assertEnvVars(r, b);
         r.assertLogContains("OUTSIDE_CONTAINER_BUILD_NUMBER = 1\n", b);
@@ -414,7 +398,7 @@ public void runWithEnvVariables() throws Exception {
     }
 
     @Test
-    public void runWithEnvVariablesInContext() throws Exception {
+    void runWithEnvVariablesInContext() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("The initial value of POD_ENV_VAR is pod-env-var-value", b);
         r.assertLogContains("The value of POD_ENV_VAR outside container is /bin/mvn:pod-env-var-value", b);
@@ -461,7 +445,7 @@ private void assertEnvVars(JenkinsRule r2, WorkflowRun b) throws Exception {
     }
 
     @Test
-    public void runWithOverriddenEnvVariables() throws Exception {
+    void runWithOverriddenEnvVariables() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("OUTSIDE_CONTAINER_HOME_ENV_VAR = /home/jenkins\n", b);
         r.assertLogContains("INSIDE_CONTAINER_HOME_ENV_VAR = /root\n", b);
@@ -470,7 +454,7 @@ public void runWithOverriddenEnvVariables() throws Exception {
     }
 
     @Test
-    public void supportComputerEnvVars() throws Exception {
+    void supportComputerEnvVars() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("OPENJDK_BUILD_NUMBER: 1\n", b);
         r.assertLogContains("JNLP_BUILD_NUMBER: 1\n", b);
@@ -478,7 +462,7 @@ public void supportComputerEnvVars() throws Exception {
     }
 
     @Test
-    public void runDirContext() throws Exception {
+    void runDirContext() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         String workspace = "/home/jenkins/agent/workspace/" + getProjectName();
         r.assertLogContains("initpwd is -" + workspace + "-", b);
@@ -487,13 +471,13 @@ public void runDirContext() throws Exception {
     }
 
     @Test
-    public void runInPodWithLivenessProbe() throws Exception {
+    void runInPodWithLivenessProbe() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogContains("Still alive", b);
     }
 
     @Test
-    public void podTemplateWithMultipleLabels() throws Exception {
+    void podTemplateWithMultipleLabels() throws Exception {
         PodTemplate pt = new PodTemplate();
         pt.setName("podTemplate");
         pt.setLabel("label1 label2");
@@ -513,7 +497,7 @@ public void podTemplateWithMultipleLabels() throws Exception {
                         + pods.getItems().stream()
                                 .map(Pod::getMetadata)
                                 .map(ObjectMeta::getName)
-                                .collect(Collectors.toList()),
+                                .toList(),
                 pods.getItems(),
                 hasSize(1));
         SemaphoreStep.success("pod/1", null);
@@ -521,10 +505,10 @@ public void podTemplateWithMultipleLabels() throws Exception {
     }
 
     @Test
-    public void runWithActiveDeadlineSeconds() throws Exception {
+    void runWithActiveDeadlineSeconds() throws Exception {
         SemaphoreStep.waitForStart("podTemplate/1", b);
         PodTemplate deadlineTemplate = cloud.getAllTemplates().stream()
-                .filter(x -> name.getMethodName().equals(x.getLabel()))
+                .filter(x -> name.equals(x.getLabel()))
                 .findAny()
                 .orElse(null);
         assertNotNull(deadlineTemplate);
@@ -535,17 +519,17 @@ public void runWithActiveDeadlineSeconds() throws Exception {
     }
 
     @Test
-    public void runInPodWithRetention() throws Exception {
+    void runInPodWithRetention() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         System.out.println("Deleting leftover pods");
         KubernetesClient client = cloud.connect();
         Map labels = getLabels(this, name);
-        assertTrue(client.pods().withLabels(labels).delete().size() > 0);
+        assertFalse(client.pods().withLabels(labels).delete().isEmpty());
     }
 
     @Issue("JENKINS-49707")
     @Test
-    public void terminatedPod() throws Exception {
+    void terminatedPod() throws Exception {
         logs.record(KubernetesAgentErrorCondition.class, Level.FINE);
         r.waitForMessage("+ sleep", b);
         deletePods(cloud.connect(), getLabels(this, name), false);
@@ -558,7 +542,7 @@ public void terminatedPod() throws Exception {
 
     @Issue("JENKINS-59340")
     @Test
-    public void containerTerminated() throws Exception {
+    void containerTerminated() throws Exception {
         assertBuildStatus(r.waitForCompletion(b), Result.FAILURE, Result.ABORTED);
         r.waitForMessage("Container stress-ng was terminated", b);
         /* TODO sometimes instead get: Container stress-ng was terminated (Exit Code: 0, Reason: Completed)
@@ -567,7 +551,7 @@ public void containerTerminated() throws Exception {
     }
 
     @Test
-    public void errorPod() throws Exception {
+    void errorPod() throws Exception {
         r.waitForMessage("jnlp -- terminated (1)", b);
         r.waitForMessage("Foo", b);
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
@@ -575,13 +559,13 @@ public void errorPod() throws Exception {
 
     @Issue("JENKINS-59340")
     @Test
-    public void podDeadlineExceeded() throws Exception {
+    void podDeadlineExceeded() throws Exception {
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.waitForMessage(POD_DEADLINE_EXCEEDED_MESSAGE, b);
     }
 
     @Test
-    public void podDeadlineExceededGlobalTemplate() throws Exception {
+    void podDeadlineExceededGlobalTemplate() throws Exception {
         PodTemplate podTemplate = new PodTemplate("podDeadlineExceededGlobalTemplate");
         podTemplate.setLabel("podDeadlineExceededGlobalTemplate");
         podTemplate.setActiveDeadlineSeconds(30);
@@ -592,7 +576,7 @@ public void podDeadlineExceededGlobalTemplate() throws Exception {
     }
 
     @Test
-    public void interruptedPod() throws Exception {
+    void interruptedPod() throws Exception {
         r.waitForMessage("starting to sleep", b);
         b.getExecutor().interrupt();
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
@@ -601,18 +585,20 @@ public void interruptedPod() throws Exception {
 
     @Issue("JENKINS-58306")
     @Test
-    public void cascadingDelete() throws Exception {
+    void cascadingDelete() throws Exception {
         try {
             cloud.connect().apps().deployments().withName("cascading-delete").delete();
-            assumeNotNull(cloud.connect().serviceAccounts().withName("jenkins").get());
+            assumeTrue(cloud.connect().serviceAccounts().withName("jenkins").get() != null);
         } catch (KubernetesClientException x) {
             // Failure executing: DELETE at:
             // https://…/apis/apps/v1/namespaces/kubernetes-plugin-test/deployments/cascading-delete. Message:
             // Forbidden!Configured service account doesn't have access. Service account may have been revoked.
             // deployments.apps "cascading-delete" is forbidden: User "system:serviceaccount:…:…" cannot delete resource
             // "deployments" in API group "apps" in the namespace "kubernetes-plugin-test".
-            assumeNoException(
-                    "was not permitted to clean up any previous deployment, so presumably cannot run test either", x);
+            assumeTrue(
+                    false,
+                    "was not permitted to clean up any previous deployment, so presumably cannot run test either: "
+                            + x);
         }
         cloud.connect()
                 .apps()
@@ -624,8 +610,8 @@ public void cascadingDelete() throws Exception {
     }
 
     @Test
-    @Ignore
-    public void computerCantBeConfigured() throws Exception {
+    @Disabled
+    void computerCantBeConfigured() throws Exception {
         r.jenkins.setSecurityRealm(r.createDummySecurityRealm());
         r.jenkins.setAuthorizationStrategy(new MockAuthorizationStrategy()
                 .grant(Jenkins.MANAGE)
@@ -652,39 +638,39 @@ public void computerCantBeConfigured() throws Exception {
     private void assertNotXPath(HtmlPage page, String xpath) {
         HtmlElement documentElement = page.getDocumentElement();
         assertNull(
-                "There should not be an object that matches XPath:" + xpath,
-                DomNodeUtil.selectSingleNode(documentElement, xpath));
+                DomNodeUtil.selectSingleNode(documentElement, xpath),
+                "There should not be an object that matches XPath:" + xpath);
     }
 
     @Issue("JENKINS-57717")
     @Test
-    public void runInPodWithShowRawYamlFalse() throws Exception {
+    void runInPodWithShowRawYamlFalse() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogNotContains("value: \"container-env-var-value\"", b);
     }
 
     @Issue("JENKINS-58574")
     @Test
-    public void showRawYamlFalseInherited() throws Exception {
+    void showRawYamlFalseInherited() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         r.assertLogNotContains("value: \"container-env-var-value\"", b);
     }
 
     @Test
     @Issue("JENKINS-58405")
-    public void overrideYaml() throws Exception {
+    void overrideYaml() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
     }
 
     @Test
     @Issue("JENKINS-58405")
-    public void mergeYaml() throws Exception {
+    void mergeYaml() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
     }
 
     @Test
     @Issue("JENKINS-58602")
-    public void jenkinsSecretHidden() throws Exception {
+    void jenkinsSecretHidden() throws Exception {
         SemaphoreStep.waitForStart("pod/1", b);
         Optional scOptional = Arrays.stream(r.jenkins.getComputers())
                 .filter(SlaveComputer.class::isInstance)
@@ -698,19 +684,19 @@ public void jenkinsSecretHidden() throws Exception {
     }
 
     @Test
-    public void jnlpWorkingDir() throws Exception {
+    void jnlpWorkingDir() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
     }
 
     @Issue("JENKINS-61178")
     @Test
-    public void sidecarWorkingDir() throws Exception {
+    void sidecarWorkingDir() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
     }
 
     @Issue("JENKINS-60517")
     @Test
-    public void runInDynamicallyCreatedContainer() throws Exception {
+    void runInDynamicallyCreatedContainer() throws Exception {
         List templates = cloud.getTemplates();
         while (templates.isEmpty()) {
             LOGGER.log(Level.INFO, "Waiting for template to be created");
@@ -727,7 +713,7 @@ public void runInDynamicallyCreatedContainer() throws Exception {
 
     @Issue("JENKINS-57256")
     @Test
-    public void basicWindows() throws Exception {
+    void basicWindows() throws Exception {
         assumeWindows(WINDOWS_1809_BUILD);
         cloud.setDirectConnection(false); // not yet supported by
         // https://github.com/jenkinsci/docker-inbound-agent/blob/517ccd68fd1ce420e7526ca6a40320c9a47a2c18/jenkins-agent.ps1
@@ -738,7 +724,7 @@ public void basicWindows() throws Exception {
 
     @Issue("JENKINS-53500")
     @Test
-    public void windowsContainer() throws Exception {
+    void windowsContainer() throws Exception {
         assumeWindows(WINDOWS_1809_BUILD);
         cloud.setDirectConnection(false);
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
@@ -747,10 +733,10 @@ public void windowsContainer() throws Exception {
         r.assertLogContains("got stuff: some value", b);
     }
 
-    @Ignore(
+    @Disabled(
             "TODO aborts, but with “kill finished with exit code 9009” and “After 20s process did not stop” and no graceful shutdown")
     @Test
-    public void interruptedPodWindows() throws Exception {
+    void interruptedPodWindows() throws Exception {
         assumeWindows(WINDOWS_1809_BUILD);
         cloud.setDirectConnection(false);
         r.waitForMessage("starting to sleep", b);
@@ -760,7 +746,7 @@ public void interruptedPodWindows() throws Exception {
     }
 
     @Test
-    public void secretMaskingWindows() throws Exception {
+    void secretMaskingWindows() throws Exception {
         assumeWindows(WINDOWS_1809_BUILD);
         cloud.setDirectConnection(false);
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
@@ -776,12 +762,12 @@ public void secretMaskingWindows() throws Exception {
     }
 
     @Test
-    public void dynamicPVCWorkspaceVolume() throws Exception {
+    void dynamicPVCWorkspaceVolume() throws Exception {
         dynamicPVC();
     }
 
     @Test
-    public void dynamicPVCVolume() throws Exception {
+    void dynamicPVCVolume() throws Exception {
         dynamicPVC();
     }
 
@@ -822,26 +808,26 @@ private void dynamicPVC() throws Exception {
         return KubernetesTestUtil.getLabels(cloud, this, name);
     }
 
-    private void assumePvcAccess() throws KubernetesAuthException, IOException {
+    private void assumePvcAccess() throws Exception {
         try {
             cloud.connect().persistentVolumeClaims().list();
         } catch (KubernetesClientException x) {
             // Error from server (Forbidden): persistentvolumeclaims is forbidden: User
             // "system:serviceaccount:kubernetes-plugin-test:default" cannot list resource "persistentvolumeclaims" in
             // API group "" in the namespace "kubernetes-plugin-test"
-            assumeNoException("was not permitted to list pvcs, so presumably cannot run test either", x);
+            assumeTrue(false, "was not permitted to list pvcs, so presumably cannot run test either: " + x);
         }
     }
 
     @Test
-    public void invalidPodGetsCancelled() throws Exception {
+    void invalidPodGetsCancelled() throws Exception {
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("ERROR: Unable to create pod", b);
         r.assertLogContains("Queue task was cancelled", b);
     }
 
     @Test
-    public void invalidImageGetsCancelled() throws Exception {
+    void invalidImageGetsCancelled() throws Exception {
         Reaper.TerminateAgentOnImagePullBackOff.BACKOFF_EVENTS_LIMIT = 2;
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("Image pull backoff detected, waiting for image to be available.", b);
@@ -850,10 +836,10 @@ public void invalidImageGetsCancelled() throws Exception {
 
     @Issue("SECURITY-1646")
     @Test
-    public void substituteEnv() throws Exception {
+    void substituteEnv() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         String home = System.getenv("HOME");
-        assumeNotNull(home);
+        assumeTrue(home != null);
         r.assertLogContains("hack: \"xxx${HOME}xxx\"", b);
         r.assertLogNotContains("xxx" + home + "xxx", b);
         PodTemplateUtils.SUBSTITUTE_ENV = true;
@@ -862,7 +848,7 @@ public void substituteEnv() throws Exception {
     }
 
     @Test
-    public void octalPermissions() throws Exception {
+    void octalPermissions() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
     }
 
@@ -878,7 +864,7 @@ private  R assertBuildStatus(R run, Result... status) throws Exce
     }
 
     @Test
-    public void cancelOnlyRelevantQueueItem() throws Exception {
+    void cancelOnlyRelevantQueueItem() throws Exception {
         r.waitForMessage("cancelled pod item by now", b);
         r.createOnlineSlave(Label.get("special-agent"));
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
@@ -886,7 +872,7 @@ public void cancelOnlyRelevantQueueItem() throws Exception {
     }
 
     @Test
-    public void garbageCollection() throws Exception {
+    void garbageCollection() throws Exception {
         // Pod exists, need to kill the build, delete the agent without deleting the pod.
         // Wait for the timeout to expire and check that the pod is deleted.
         var garbageCollection = new GarbageCollection();
@@ -900,7 +886,7 @@ public void garbageCollection() throws Exception {
             if (c instanceof KubernetesComputer) {
                 var node = (KubernetesSlave) c.getNode();
                 pod = node.getPod().get();
-                Assert.assertNotNull(pod);
+                assertNotNull(pod);
                 b.doKill();
                 r.jenkins.removeNode(node);
                 break;
@@ -915,7 +901,7 @@ public void garbageCollection() throws Exception {
     }
 
     @Test
-    public void handleEviction() throws Exception {
+    void handleEviction() throws Exception {
         SemaphoreStep.waitForStart("pod/1", b);
         var client = cloud.connect();
         var pod = client.pods()
@@ -932,7 +918,7 @@ public void handleEviction() throws Exception {
     }
 
     @Test
-    public void decoratorFailure() throws Exception {
+    void decoratorFailure() throws Exception {
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("I always fail", b);
         assertThat("Node should have been removed", r.jenkins.getNodes(), empty());
@@ -948,12 +934,12 @@ public Pod decorate(@NonNull KubernetesCloud kubernetesCloud, @NonNull Pod pod)
     }
 
     @Test
-    public void imageWithoutAgent() throws Exception {
+    void imageWithoutAgent() throws Exception {
         r.assertBuildStatus(Result.SUCCESS, r.waitForCompletion(b));
     }
 
     @Test
-    public void imageWithoutAgentNoJava() throws Exception {
+    void imageWithoutAgentNoJava() throws Exception {
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         r.assertLogContains("java: not found", b);
     }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java
index 6536ee8e6a..3ae9ecd7e3 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesPipelineWebsocketRJRTest.java
@@ -1,19 +1,18 @@
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import java.net.UnknownHostException;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.AssertBuildStatusSuccess;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.RunId;
 import org.csanchez.jenkins.plugins.kubernetes.pipeline.steps.SetupCloud;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class KubernetesPipelineWebsocketRJRTest extends AbstractKubernetesPipelineRJRTest {
+class KubernetesPipelineWebsocketRJRTest extends AbstractKubernetesPipelineRJRTest {
 
-    public KubernetesPipelineWebsocketRJRTest() throws UnknownHostException {
+    public KubernetesPipelineWebsocketRJRTest() throws Exception {
         super(new SetupCloud(true));
     }
 
     @Test
-    public void basicPipeline() throws Throwable {
+    void basicPipeline() throws Throwable {
         RunId runId = createWorkflowJobThenScheduleRun();
         rjr.runRemotely(new AssertBuildStatusSuccess(runId));
     }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java
index c0916c85d2..a6ea80ed20 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/KubernetesSamplesTest.java
@@ -19,31 +19,26 @@
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*;
 
 import hudson.ExtensionList;
+import java.util.concurrent.TimeUnit;
 import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
 import org.jenkinsci.plugins.workflow.cps.GroovySample;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ErrorCollector;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
 
-public class KubernetesSamplesTest extends AbstractKubernetesPipelineTest {
+@Timeout(value = 2, unit = TimeUnit.MINUTES)
+class KubernetesSamplesTest extends AbstractKubernetesPipelineTest {
 
-    // TODO tried without success to use Parameterized here (need to construct parameters _after_ JenkinsRule starts)
-    @Rule
-    public ErrorCollector errors = new ErrorCollector();
-
-    {
-        r.timeout *= 2; // again, without Parameterized we are running a bunch of builds in one test case
-    }
-
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void beforeEach() throws Exception {
         deletePods(cloud.connect(), getLabels(cloud, this, name), false);
     }
 
     @Test
-    public void smokes() throws Exception {
+    void smokes() throws Exception {
+        // TODO tried without success to use Parameterized here (need to construct parameters _after_ JenkinsRule
+        // starts)
         for (GroovySample gs : ExtensionList.lookup(GroovySample.class)) {
             if (gs.name().equals("kubernetes-windows") && !isWindows(null)) {
                 System.err.println("==== Skipping " + gs.title() + " ====");
@@ -52,7 +47,7 @@ public void smokes() throws Exception {
             System.err.println("==== " + gs.title() + " ====");
             p = r.createProject(WorkflowJob.class, gs.name());
             p.setDefinition(new CpsFlowDefinition(gs.script(), true));
-            errors.checkSucceeds(() -> r.buildAndAssertSuccess(p));
+            r.buildAndAssertSuccess(p);
         }
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java
index 298f243ea9..9d6a8c12fd 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/NoDelayProvisionerStrategyTest.java
@@ -2,7 +2,7 @@
 
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.deletePods;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.getLabels;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
@@ -19,20 +19,21 @@
 import hudson.slaves.CloudProvisioningListener;
 import hudson.slaves.NodeProvisioner;
 import java.util.Collection;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.jvnet.hudson.test.TestExtension;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class NoDelayProvisionerStrategyTest extends AbstractKubernetesPipelineTest {
 
-@RunWith(MockitoJUnitRunner.class)
-public class NoDelayProvisionerStrategyTest extends AbstractKubernetesPipelineTest {
     @Mock
-    CloudProvisioningListener cloudProvisioningListener;
+    private CloudProvisioningListener cloudProvisioningListener;
 
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void beforeEach() throws Exception {
         CloudProvisionerListenerImpl instance = ExtensionList.lookupSingleton(CloudProvisionerListenerImpl.class);
         instance.setDelegate(cloudProvisioningListener);
         deletePods(cloud.connect(), getLabels(cloud, this, name), false);
@@ -80,7 +81,7 @@ public CauseOfBlockage canProvision(Cloud cloud, Label label, int numExecutors)
     }
 
     @Test
-    public void noDelayProvisionerCallsListener() throws Exception {
+    void noDelayProvisionerCallsListener() throws Exception {
         when(cloudProvisioningListener.canProvision(any(Cloud.class), any(Label.class), anyInt()))
                 .thenReturn(null);
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java
index db818ce901..8ba4ce0e9a 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodNameTest.java
@@ -21,18 +21,18 @@
 
 import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
-public class PodNameTest extends AbstractKubernetesPipelineTest {
+class PodNameTest extends AbstractKubernetesPipelineTest {
 
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void beforeEach() throws Exception {
         deletePods(cloud.connect(), getLabels(cloud, this, name), false);
     }
 
     @Test
-    public void multipleDots() throws Exception {
+    void multipleDots() throws Exception {
         WorkflowJob p = r.createProject(WorkflowJob.class, "whatever...man");
         p.setDefinition(new CpsFlowDefinition("podTemplate {node(POD_LABEL) {sh 'echo ok'}}", true));
         r.buildAndAssertSuccess(p);
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java
index 6a4be2d3ed..efe4200ced 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodProvisioningStatusLogsTest.java
@@ -1,14 +1,14 @@
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
-import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import hudson.model.Result;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class PodProvisioningStatusLogsTest extends AbstractKubernetesPipelineTest {
+class PodProvisioningStatusLogsTest extends AbstractKubernetesPipelineTest {
 
     @Test
-    public void podStatusErrorLogs() throws Exception {
+    void podStatusErrorLogs() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         // pod not schedulable
         // build never finishes, so just checking the message and killing
@@ -18,7 +18,7 @@ public void podStatusErrorLogs() throws Exception {
     }
 
     @Test
-    public void podStatusNoErrorLogs() throws Exception {
+    void podStatusNoErrorLogs() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatusSuccess(r.waitForCompletion(b));
         // regular logs when starting containers
@@ -27,7 +27,7 @@ public void podStatusNoErrorLogs() throws Exception {
     }
 
     @Test
-    public void containerStatusErrorLogs() throws Exception {
+    void containerStatusErrorLogs() throws Exception {
         assertNotNull(createJobThenScheduleRun());
         r.assertBuildStatus(Result.ABORTED, r.waitForCompletion(b));
         // error starting container
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java
index 04187d72e8..451536835d 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepExecutionTest.java
@@ -25,7 +25,7 @@
 package org.csanchez.jenkins.plugins.kubernetes.pipeline;
 
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import hudson.model.Result;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
@@ -34,27 +34,28 @@
 import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodTemplateStepExecutionTest {
+@WithJenkins
+class PodTemplateStepExecutionTest {
 
-    @Rule
-    public JenkinsRule r = new JenkinsRule();
+    private JenkinsRule r;
 
     protected KubernetesCloud cloud;
 
-    @Before
-    public void configureCloud() throws Exception {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
         cloud = new KubernetesCloud("kubernetes");
         r.jenkins.clouds.add(cloud);
     }
 
-    @BeforeClass
-    public static void isKubernetesConfigured() throws Exception {
+    @BeforeAll
+    static void beforeAll() {
         assumeKubernetes();
     }
 
@@ -63,7 +64,7 @@ private String loadPipelineScript(String name) {
     }
 
     @Test
-    public void testBadNameDetection() throws Exception {
+    void testBadNameDetection() throws Exception {
         WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "bad_container_name");
         p.setDefinition(new CpsFlowDefinition(loadPipelineScript("badcontainername.groovy"), true));
         WorkflowRun b = p.scheduleBuild2(0).waitForStart();
@@ -73,7 +74,7 @@ public void testBadNameDetection() throws Exception {
     }
 
     @Test
-    public void testBadNameYamlDetection() throws Exception {
+    void testBadNameYamlDetection() throws Exception {
         WorkflowJob p = r.jenkins.createProject(WorkflowJob.class, "bad_container_name_yaml");
         p.setDefinition(new CpsFlowDefinition(loadPipelineScript("badcontainernameyaml.groovy"), true));
         WorkflowRun b = p.scheduleBuild2(0).waitForStart();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java
index e8c26f737c..b8e963b099 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/PodTemplateStepTest.java
@@ -5,19 +5,26 @@
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.DynamicPVCWorkspaceVolume;
 import org.csanchez.jenkins.plugins.kubernetes.volumes.workspace.EmptyDirWorkspaceVolume;
 import org.jenkinsci.plugins.workflow.cps.SnippetizerTester;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class PodTemplateStepTest {
-    @Rule
-    public JenkinsRule rule = new JenkinsRule();
+@WithJenkins
+class PodTemplateStepTest {
+
+    private JenkinsRule r;
+
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        r = rule;
+    }
 
     @Issue("JENKINS-57828")
     @Test
-    public void configRoundTrip() throws Exception {
-        SnippetizerTester st = new SnippetizerTester(rule);
+    void configRoundTrip() throws Exception {
+        SnippetizerTester st = new SnippetizerTester(r);
         PodTemplateStep step = new PodTemplateStep();
 
         st.assertRoundTrip(step, "podTemplate {\n    // some block\n}");
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java
index 9be9ce3eff..d3fc5cfcd5 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/ResourcesTest.java
@@ -8,12 +8,12 @@
 import java.io.IOException;
 import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback;
 import org.jenkinsci.plugins.workflow.steps.StepContext;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class ResourcesTest {
+class ResourcesTest {
 
     @Test
-    public void testCloseQuietly() throws Exception {
+    void testCloseQuietly() throws Exception {
         StepContext ctx = mock(StepContext.class);
         TaskListener listener = mock(TaskListener.class);
         when(ctx.get(TaskListener.class))
@@ -42,7 +42,7 @@ public void testCloseQuietly() throws Exception {
     }
 
     @Test
-    public void testCloseQuietlyCallbackOnSuccess() throws Exception {
+    void testCloseQuietlyCallbackOnSuccess() throws Exception {
         StepContext ctx = mock(StepContext.class);
         Closeable c1 = mock(Closeable.class);
         doThrow(IOException.class).when(c1).close();
@@ -58,7 +58,7 @@ public void testCloseQuietlyCallbackOnSuccess() throws Exception {
     }
 
     @Test
-    public void testCloseQuietlyCallbackOnFailure() throws Exception {
+    void testCloseQuietlyCallbackOnFailure() throws Exception {
         StepContext ctx = mock(StepContext.class);
         Closeable c1 = mock(Closeable.class);
         doThrow(IOException.class).when(c1).close();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java
index c38f8add45..7908f24b57 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/RestartPipelineTest.java
@@ -26,12 +26,13 @@
 
 import static java.util.Arrays.*;
 import static org.csanchez.jenkins.plugins.kubernetes.KubernetesTestUtil.*;
-import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import hudson.model.Node;
 import hudson.model.Result;
 import hudson.slaves.DumbSlave;
 import hudson.slaves.JNLPLauncher;
+import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Optional;
@@ -39,7 +40,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import jenkins.model.Jenkins;
-import org.apache.commons.io.IOUtils;
 import org.csanchez.jenkins.plugins.kubernetes.ContainerEnvVar;
 import org.csanchez.jenkins.plugins.kubernetes.ContainerTemplate;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
@@ -53,50 +53,53 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jenkinsci.plugins.workflow.steps.durable_task.DurableTaskStep;
 import org.jenkinsci.plugins.workflow.support.steps.ExecutorStepDynamicContext;
-import org.junit.BeforeClass;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.junit.rules.TestName;
-import org.jvnet.hudson.test.BuildWatcher;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.io.TempDir;
 import org.jvnet.hudson.test.Issue;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.JenkinsSessionRule;
-import org.jvnet.hudson.test.LoggerRule;
+import org.jvnet.hudson.test.LogRecorder;
+import org.jvnet.hudson.test.junit.jupiter.BuildWatcherExtension;
+import org.jvnet.hudson.test.junit.jupiter.JenkinsSessionExtension;
 
-public class RestartPipelineTest {
-    protected static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value";
-    protected static final String POD_ENV_VAR_VALUE = "pod-env-var-value";
-    protected static final String SECRET_KEY = "password";
-    protected static final String CONTAINER_ENV_VAR_FROM_SECRET_VALUE = "container-pa55w0rd";
-    protected static final String POD_ENV_VAR_FROM_SECRET_VALUE = "pod-pa55w0rd";
-    protected KubernetesCloud cloud;
+class RestartPipelineTest {
 
-    @Rule
-    public JenkinsSessionRule story = new JenkinsSessionRule();
+    private static final String CONTAINER_ENV_VAR_VALUE = "container-env-var-value";
+    private static final String POD_ENV_VAR_VALUE = "pod-env-var-value";
+    private static final String SECRET_KEY = "password";
 
-    @Rule
-    public TemporaryFolder tmp = new TemporaryFolder();
+    private KubernetesCloud cloud;
 
-    @ClassRule
-    public static BuildWatcher buildWatcher = new BuildWatcher();
+    @RegisterExtension
+    private final JenkinsSessionExtension story = new JenkinsSessionExtension();
 
-    @Rule
-    public LoggerRule logs = new LoggerRule()
+    @TempDir
+    private File tmp;
+
+    @SuppressWarnings("unused")
+    private static final BuildWatcherExtension BUILD_WATCHER = new BuildWatcherExtension();
+
+    private final LogRecorder logs = new LogRecorder()
             .record(Logger.getLogger(KubernetesCloud.class.getPackage().getName()), Level.ALL);
     // .record("org.jenkinsci.plugins.durabletask",
     // Level.ALL).record("org.jenkinsci.plugins.workflow.support.concurrent",
     // Level.ALL).record("org.csanchez.jenkins.plugins.kubernetes.pipeline", Level.ALL);
 
-    @Rule
-    public TestName name = new TestName();
+    private String name;
 
-    @BeforeClass
-    public static void isKubernetesConfigured() throws Exception {
+    @BeforeAll
+    static void beforeAll() {
         assumeKubernetes();
     }
 
+    @BeforeEach
+    void beforeEach(TestInfo info) {
+        name = info.getTestMethod().orElseThrow().getName();
+    }
+
     private static void setEnvVariables(PodTemplate podTemplate) {
         TemplateEnvVar podSecretEnvVar = new SecretEnvVar("POD_ENV_VAR_FROM_SECRET", "pod-secret", SECRET_KEY, false);
         TemplateEnvVar podSimpleEnvVar = new KeyValueEnvVar("POD_ENV_VAR", POD_ENV_VAR_VALUE);
@@ -125,7 +128,7 @@ private PodTemplate buildBusyboxTemplate(String label) {
         return podTemplate;
     }
 
-    public void configureCloud() throws Exception {
+    private void configureCloud() throws Exception {
         cloud = setupCloud(this, name);
         createSecret(cloud.connect(), cloud.getNamespace());
         cloud.getTemplates().clear();
@@ -136,22 +139,14 @@ public void configureCloud() throws Exception {
         Jenkins.get().clouds.add(cloud);
     }
 
-    public void configureAgentListener() throws IOException {
+    private void configureAgentListener() throws Exception {
         // Take random port and fix it, to be the same after Jenkins restart
         int fixedPort = Jenkins.get().getTcpSlaveAgentListener().getAdvertisedPort();
         Jenkins.get().setSlaveAgentPort(fixedPort);
     }
 
-    protected String loadPipelineScript(String name) {
-        try {
-            return new String(IOUtils.toByteArray(getClass().getResourceAsStream(name)));
-        } catch (Throwable t) {
-            throw new RuntimeException("Could not read resource:[" + name + "].");
-        }
-    }
-
     @Test
-    public void nullLabelSupportsRestart() throws Throwable {
+    void nullLabelSupportsRestart() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
@@ -179,12 +174,12 @@ public void nullLabelSupportsRestart() throws Throwable {
     }
 
     @Test
-    public void runInPodWithRestartWithMultipleContainerCalls() throws Exception, Throwable {
+    void runInPodWithRestartWithMultipleContainerCalls() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
             configureCloud();
-            r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false)));
+            r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false)));
             WorkflowRun b = getPipelineJobThenScheduleRun(r);
             projectName.set(b.getParent().getFullName());
             // we need to wait until we are sure that the sh
@@ -200,12 +195,12 @@ public void runInPodWithRestartWithMultipleContainerCalls() throws Exception, Th
     }
 
     @Test
-    public void runInPodWithRestartWithLongSleep() throws Exception, Throwable {
+    void runInPodWithRestartWithLongSleep() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
             configureCloud();
-            r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false)));
+            r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false)));
             WorkflowRun b = getPipelineJobThenScheduleRun(r);
             projectName.set(b.getParent().getFullName());
             // we need to wait until we are sure that the sh
@@ -221,7 +216,7 @@ public void runInPodWithRestartWithLongSleep() throws Exception, Throwable {
     }
 
     @Test
-    public void windowsRestart() throws Throwable {
+    void windowsRestart() throws Throwable {
         assumeWindows(WINDOWS_1809_BUILD);
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
@@ -243,7 +238,7 @@ public void windowsRestart() throws Throwable {
 
     @Issue("JENKINS-49707")
     @Test
-    public void terminatedPodAfterRestart() throws Exception, Throwable {
+    void terminatedPodAfterRestart() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
@@ -268,7 +263,7 @@ public void terminatedPodAfterRestart() throws Exception, Throwable {
     }
 
     @Test
-    public void taskListenerAfterRestart() throws Throwable {
+    void taskListenerAfterRestart() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
@@ -284,7 +279,7 @@ public void taskListenerAfterRestart() throws Throwable {
             Optional first = r.jenkins.getNodes().stream()
                     .filter(KubernetesSlave.class::isInstance)
                     .findFirst();
-            assertTrue("Kubernetes node should be present after restart", first.isPresent());
+            assertTrue(first.isPresent(), "Kubernetes node should be present after restart");
             KubernetesSlave node = (KubernetesSlave) first.get();
             r.waitForMessage("Ready to run", b);
             waitForTemplate(node).getListener().getLogger().println("This got printed");
@@ -295,7 +290,7 @@ public void taskListenerAfterRestart() throws Throwable {
     }
 
     @Test
-    public void taskListenerAfterRestart_multipleLabels() throws Throwable {
+    void taskListenerAfterRestart_multipleLabels() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
@@ -311,7 +306,7 @@ public void taskListenerAfterRestart_multipleLabels() throws Throwable {
             Optional first = r.jenkins.getNodes().stream()
                     .filter(KubernetesSlave.class::isInstance)
                     .findFirst();
-            assertTrue("Kubernetes node should be present after restart", first.isPresent());
+            assertTrue(first.isPresent(), "Kubernetes node should be present after restart");
             KubernetesSlave node = (KubernetesSlave) first.get();
             r.waitForMessage("Ready to run", b);
             waitForTemplate(node).getListener().getLogger().println("This got printed");
@@ -321,7 +316,7 @@ public void taskListenerAfterRestart_multipleLabels() throws Throwable {
         });
     }
 
-    private PodTemplate waitForTemplate(KubernetesSlave node) throws InterruptedException {
+    private PodTemplate waitForTemplate(KubernetesSlave node) throws Exception {
         while (node.getTemplateOrNull() == null) {
             Thread.sleep(100L);
         }
@@ -329,12 +324,12 @@ private PodTemplate waitForTemplate(KubernetesSlave node) throws InterruptedExce
     }
 
     @Test
-    public void getContainerLogWithRestart() throws Exception, Throwable {
+    void getContainerLogWithRestart() throws Throwable {
         AtomicReference projectName = new AtomicReference<>();
         story.then(r -> {
             configureAgentListener();
             configureCloud();
-            r.jenkins.addNode(new DumbSlave("slave", tmp.newFolder("remoteFS").getPath(), new JNLPLauncher(false)));
+            r.jenkins.addNode(new DumbSlave("slave", newFolder(tmp, "remoteFS").getPath(), new JNLPLauncher(false)));
             WorkflowRun b = getPipelineJobThenScheduleRun(r);
             projectName.set(b.getParent().getFullName());
             // we need to wait until we are sure that the sh
@@ -352,6 +347,15 @@ public void getContainerLogWithRestart() throws Exception, Throwable {
     }
 
     private WorkflowRun getPipelineJobThenScheduleRun(JenkinsRule r) throws Exception {
-        return createPipelineJobThenScheduleRun(r, getClass(), name.getMethodName());
+        return createPipelineJobThenScheduleRun(r, getClass(), name);
+    }
+
+    private static File newFolder(File root, String... subDirs) throws Exception {
+        String subFolder = String.join("/", subDirs);
+        File result = new File(root, subFolder);
+        if (!result.mkdirs()) {
+            throw new IOException("Couldn't create folders " + root);
+        }
+        return result;
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java
index 207d44e502..affead33de 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/WebSocketTest.java
@@ -20,15 +20,15 @@
 
 import java.util.logging.Level;
 import jenkins.agents.WebSocketAgents;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 
 @Issue("JEP-222")
-public class WebSocketTest extends AbstractKubernetesPipelineTest {
+class WebSocketTest extends AbstractKubernetesPipelineTest {
 
-    @Before
-    public void setUp() throws Exception {
+    @BeforeEach
+    void beforeEach() throws Exception {
         deletePods(cloud.connect(), getLabels(cloud, this, name), false);
         r.jenkins.setSlaveAgentPort(-1);
         cloud.setWebSocket(true);
@@ -36,7 +36,7 @@ public void setUp() throws Exception {
     }
 
     @Test
-    public void webSocketAgent() throws Exception {
+    void webSocketAgent() throws Exception {
         r.assertBuildStatusSuccess(r.waitForCompletion(createJobThenScheduleRun()));
     }
 }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java
index 9adf22084c..577d06d0d0 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildLogMessage.java
@@ -3,9 +3,9 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
-public class AssertBuildLogMessage implements RealJenkinsRule.Step {
+public class AssertBuildLogMessage implements RealJenkinsExtension.Step {
 
     private final String message;
     private final RunId runId;
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java
index 496751a9a2..fbd70b0068 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/AssertBuildStatusSuccess.java
@@ -3,9 +3,9 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
-public class AssertBuildStatusSuccess implements RealJenkinsRule.Step {
+public class AssertBuildStatusSuccess implements RealJenkinsExtension.Step {
     private RunId runId;
 
     public AssertBuildStatusSuccess(RunId runId) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java
index b17f437f62..0210cfc0ca 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleRun.java
@@ -4,12 +4,12 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
 /**
  * Creates a workflow job using the specified script, then schedules it and returns a reference to the run.
  */
-public class CreateWorkflowJobThenScheduleRun implements RealJenkinsRule.Step2 {
+public class CreateWorkflowJobThenScheduleRun implements RealJenkinsExtension.Step2 {
     private String script;
 
     public CreateWorkflowJobThenScheduleRun(String script) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java
index 882fad33ef..69000abd20 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/CreateWorkflowJobThenScheduleTask.java
@@ -4,12 +4,12 @@
 import org.jenkinsci.plugins.workflow.job.WorkflowJob;
 import org.jenkinsci.plugins.workflow.job.WorkflowRun;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
 /**
  * Creates a workflow job using the specified script, then schedules it and returns a reference to the run.
  */
-public class CreateWorkflowJobThenScheduleTask implements RealJenkinsRule.Step2 {
+public class CreateWorkflowJobThenScheduleTask implements RealJenkinsExtension.Step2 {
     private String script;
 
     public CreateWorkflowJobThenScheduleTask(String script) {
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java
index 63da6fda7c..43adb8ceda 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pipeline/steps/SetupCloud.java
@@ -2,23 +2,22 @@
 
 import java.net.InetAddress;
 import java.net.URL;
-import java.net.UnknownHostException;
 import jenkins.model.JenkinsLocationConfiguration;
 import org.apache.commons.lang3.StringUtils;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
 import org.jvnet.hudson.test.JenkinsRule;
-import org.jvnet.hudson.test.RealJenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.RealJenkinsExtension;
 
 /**
  * Sets up a Kubernetes cloud instance named kubernetes.
  */
-public class SetupCloud implements RealJenkinsRule.Step {
+public class SetupCloud implements RealJenkinsExtension.Step {
     private String hostAddress;
     private Integer agentPort;
 
     private boolean websocket;
 
-    public SetupCloud(boolean websocket) throws UnknownHostException {
+    public SetupCloud(boolean websocket) throws Exception {
         hostAddress = StringUtils.defaultIfBlank(
                 System.getProperty("jenkins.host.address"),
                 InetAddress.getLocalHost().getHostAddress());
@@ -26,7 +25,7 @@ public SetupCloud(boolean websocket) throws UnknownHostException {
         this.websocket = websocket;
     }
 
-    public SetupCloud() throws UnknownHostException {
+    public SetupCloud() throws Exception {
         this(false);
     }
 
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java
index faea739150..0791ec87a2 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/decorator/PodDecoratorTest.java
@@ -1,6 +1,6 @@
 package org.csanchez.jenkins.plugins.kubernetes.pod.decorator;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.Mockito.when;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
@@ -10,29 +10,29 @@
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesSlave;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplateBuilder;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.jvnet.hudson.test.JenkinsRule;
 import org.jvnet.hudson.test.TestExtension;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
+import org.mockito.junit.jupiter.MockitoExtension;
 
-public class PodDecoratorTest {
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+@WithJenkins
+@ExtendWith(MockitoExtension.class)
+class PodDecoratorTest {
 
-    @Rule
-    public MockitoRule mockitoRule = MockitoJUnit.rule();
+    private JenkinsRule j;
 
     @Mock
     private KubernetesSlave slave;
 
     private KubernetesCloud cloud = new KubernetesCloud("test");
 
-    @Before
-    public void setUp() {
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
         when(slave.getKubernetesCloud()).thenReturn(cloud);
     }
 
@@ -52,7 +52,7 @@ public Pod decorate(@NonNull KubernetesCloud kubernetesCloud, @NonNull Pod pod)
     }
 
     @Test
-    public void activeDecorator() {
+    void activeDecorator() {
         PodTemplate podTemplate = new PodTemplate();
         PodTemplateBuilder podTemplateBuilder = new PodTemplateBuilder(podTemplate, slave);
         Pod pod = podTemplateBuilder.build();
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java
index 3e032f5e38..4ceafa6be9 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/PodRetentionTest.java
@@ -1,41 +1,42 @@
 package org.csanchez.jenkins.plugins.kubernetes.pod.retention;
 
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import io.fabric8.kubernetes.api.model.Pod;
 import io.fabric8.kubernetes.api.model.PodStatus;
 import io.fabric8.kubernetes.api.model.PodStatusBuilder;
 import java.util.function.Supplier;
 import org.csanchez.jenkins.plugins.kubernetes.KubernetesCloud;
-import org.junit.Before;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
-public class PodRetentionTest {
+class PodRetentionTest {
 
     private KubernetesCloud cloud;
     private Pod pod;
     private Supplier podS = () -> pod;
 
-    @Before
-    public void setUp() {
+    @BeforeEach
+    void beforeEach() {
         this.cloud = new KubernetesCloud("kubernetes");
         this.pod = new Pod();
     }
 
     @Test
-    public void testAlwaysPodRetention() {
+    void testAlwaysPodRetention() {
         PodRetention subject = new Always();
         assertFalse(subject.shouldDeletePod(cloud, podS));
     }
 
     @Test
-    public void testNeverPodRetention() {
+    void testNeverPodRetention() {
         PodRetention subject = new Never();
         assertTrue(subject.shouldDeletePod(cloud, podS));
     }
 
     @Test
-    public void testDefaultPodRetention() {
+    void testDefaultPodRetention() {
         PodRetention subject = new Default();
         cloud.setPodRetention(new Always());
         assertFalse(subject.shouldDeletePod(cloud, podS));
@@ -48,7 +49,7 @@ public void testDefaultPodRetention() {
     }
 
     @Test
-    public void testOnFailurePodRetention() {
+    void testOnFailurePodRetention() {
         PodRetention subject = new OnFailure();
         pod.setStatus(buildStatus("Failed"));
         assertFalse(subject.shouldDeletePod(cloud, podS));
@@ -61,7 +62,7 @@ public void testOnFailurePodRetention() {
     }
 
     @Test
-    public void testOnEvictedPodRetention() {
+    void testOnEvictedPodRetention() {
         PodRetention subject = new Evicted();
         pod.setStatus(buildStatus("Failed", "Evicted"));
         assertFalse(subject.shouldDeletePod(cloud, podS));
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
index 5aaebdb99f..d9bd297e8c 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
@@ -26,7 +26,7 @@
 import static org.awaitility.Awaitility.await;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.*;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.*;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
@@ -37,12 +37,11 @@
 import io.fabric8.kubernetes.api.model.*;
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.Watcher;
+import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
 import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
 import io.fabric8.kubernetes.client.utils.Utils;
 import io.fabric8.mockwebserver.http.RecordedRequest;
-import java.io.IOException;
 import java.net.HttpURLConnection;
-import java.net.InetAddress;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -53,43 +52,42 @@
 import jenkins.model.Jenkins;
 import org.csanchez.jenkins.plugins.kubernetes.*;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExternalResource;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.RegisterExtension;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
-public class ReaperTest {
+@WithJenkins
+@EnableKubernetesMockClient
+class ReaperTest {
 
     private static final Long EVENT_WAIT_PERIOD_MS = 10L;
 
-    @Rule
-    public JenkinsRule j = new JenkinsRule();
+    private JenkinsRule j;
 
-    @Rule
-    public CapturingReaperListener listener = new CapturingReaperListener();
+    @RegisterExtension
+    private final CapturingReaperListener listener = new CapturingReaperListener();
 
     private KubernetesMockServer server;
     private KubernetesClient client;
 
-    @Before
-    public void setUp() {
-        // TODO: remove when moving to junit 5
-        server = new KubernetesMockServer();
-        server.init(InetAddress.getLoopbackAddress(), 0);
-        client = server.createClient();
+    @BeforeEach
+    void beforeEach(JenkinsRule rule) {
+        j = rule;
     }
 
-    @After
-    public void tearDown() {
+    @AfterEach
+    void afterEach() {
         KubernetesClientProvider.invalidateAll();
-        server.destroy();
-        client.close();
     }
 
     @Test
-    public void testMaybeActivate() throws IOException, InterruptedException {
+    void testMaybeActivate() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
@@ -101,14 +99,14 @@ public void testMaybeActivate() throws IOException, InterruptedException {
 
         // add node that does not exist in k8s so it get's removed
         KubernetesSlave podNotRunning = addNode(cloud, "k8s-node-123", "k8s-node");
-        assertEquals("node added to jenkins", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "node added to jenkins");
 
         // activate reaper
         Reaper r = Reaper.getInstance();
         r.maybeActivate();
 
         // k8s node which no pod should be deleted on activation
-        assertEquals("node removed from jenkins", j.jenkins.getNodes().size(), 0);
+        assertEquals(0, j.jenkins.getNodes().size(), "node removed from jenkins");
 
         // watch was created
         assertShouldBeWatching(r, cloud);
@@ -122,18 +120,18 @@ public void testMaybeActivate() throws IOException, InterruptedException {
         // create new node to verify activate is not run again
         KubernetesSlave newNode = addNode(cloud, "new-123", "new");
         j.jenkins.addNode(newNode);
-        assertEquals("node added to jenkins", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "node added to jenkins");
         // call again should not add any more calls
         r.maybeActivate();
 
         kubeClientRequests()
                 // expect not to be called
                 .assertRequestCount("/api/v1/namespaces/foo/pods/new-123", 0);
-        assertEquals("node not removed from jenkins", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "node not removed from jenkins");
     }
 
     @Test
-    public void testWatchFailOnActivate() throws IOException, InterruptedException {
+    void testWatchFailOnActivate() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         // activate reaper
         Reaper r = Reaper.getInstance();
@@ -147,7 +145,7 @@ public void testWatchFailOnActivate() throws IOException, InterruptedException {
     }
 
     @Test
-    public void testActivateOnNewComputer() throws IOException, InterruptedException {
+    void testActivateOnNewComputer() throws Exception {
         server.expect()
                 .withPath("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true")
                 .andUpgradeToWebSocket()
@@ -176,8 +174,9 @@ public void testActivateOnNewComputer() throws IOException, InterruptedException
                 .assertRequestCountAtLeast("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true", 1);
     }
 
-    @Test(timeout = 10_000)
-    public void testReconnectOnNewComputer() throws InterruptedException, IOException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testReconnectOnNewComputer() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
@@ -229,8 +228,9 @@ public void testReconnectOnNewComputer() throws InterruptedException, IOExceptio
         System.out.println("Watch started");
     }
 
-    @Test(timeout = 10_000)
-    public void testAddWatchWhenCloudAdded() throws InterruptedException, IOException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testAddWatchWhenCloudAdded() throws Exception {
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
                 .withPath(watchPodsPath)
@@ -244,7 +244,7 @@ public void testAddWatchWhenCloudAdded() throws InterruptedException, IOExceptio
         r.maybeActivate();
 
         String cloudName = "k8s";
-        assertFalse("should not be watching cloud", r.isWatchingCloud(cloudName));
+        assertFalse(r.isWatchingCloud(cloudName), "should not be watching cloud");
 
         KubernetesCloud cloud = addCloud(cloudName, "foo");
 
@@ -256,8 +256,9 @@ public void testAddWatchWhenCloudAdded() throws InterruptedException, IOExceptio
         kubeClientRequests().assertRequestCountAtLeast(watchPodsPath, 1);
     }
 
-    @Test(timeout = 10_000)
-    public void testRemoveWatchWhenCloudRemoved() throws InterruptedException, IOException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testRemoveWatchWhenCloudRemoved() {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
@@ -283,8 +284,9 @@ public void testRemoveWatchWhenCloudRemoved() throws InterruptedException, IOExc
         assertShouldNotBeWatching(r, cloud);
     }
 
-    @Test(timeout = 10_000)
-    public void testReplaceWatchWhenCloudUpdated() throws InterruptedException, IOException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testReplaceWatchWhenCloudUpdated() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         Pod node123 = new PodBuilder()
                 .withNewStatus()
@@ -338,8 +340,9 @@ public void testReplaceWatchWhenCloudUpdated() throws InterruptedException, IOEx
         kubeClientRequests().assertRequestCountAtLeast(watchBarPodsPath, 1);
     }
 
-    @Test(timeout = 10_000)
-    public void testStopWatchingOnCloseException() throws InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testStopWatchingOnCloseException() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
@@ -371,8 +374,9 @@ public void testStopWatchingOnCloseException() throws InterruptedException {
         assertShouldNotBeWatching(r, cloud);
     }
 
-    @Test(timeout = 10_000)
-    public void testKeepWatchingOnKubernetesApiServerError() throws InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testKeepWatchingOnKubernetesApiServerError() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect()
@@ -412,8 +416,9 @@ public void testKeepWatchingOnKubernetesApiServerError() throws InterruptedExcep
         assertShouldBeWatching(r, cloud);
     }
 
-    @Test(timeout = 10_000)
-    public void testKeepWatchingOnStatusWatchEvent() throws InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testKeepWatchingOnStatusWatchEvent() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
         server.expect().withPath(watchPodsPath).andReturnChunked(200).once();
@@ -444,7 +449,7 @@ public void testKeepWatchingOnStatusWatchEvent() throws InterruptedException {
     }
 
     @Test
-    public void testCloseWatchersOnShutdown() throws InterruptedException {
+    void testCloseWatchersOnShutdown() {
         String watchPodsPath = "/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true";
 
         server.expect()
@@ -473,8 +478,9 @@ public void testCloseWatchersOnShutdown() throws InterruptedException {
         assertShouldNotBeWatching(r, cloud, cloud2, cloud3);
     }
 
-    @Test(timeout = 10_000)
-    public void testDeleteNodeOnPodDelete() throws IOException, InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testDeleteNodeOnPodDelete() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         KubernetesSlave node = addNode(cloud, "node-123", "node");
         Pod node123 = createPod(node);
@@ -500,7 +506,7 @@ public void testDeleteNodeOnPodDelete() throws IOException, InterruptedException
         r.maybeActivate();
 
         // verify node is still registered
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // wait for the delete event to be processed
         waitForKubeClientRequests(6)
@@ -513,11 +519,12 @@ public void testDeleteNodeOnPodDelete() throws IOException, InterruptedException
         verify(node.getComputer()).disconnect(isA(PodOfflineCause.class));
 
         // expect node to be removed
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 0);
+        assertEquals(0, j.jenkins.getNodes().size(), "jenkins nodes");
     }
 
-    @Test(timeout = 10_000)
-    public void testTerminateAgentOnContainerTerminated() throws IOException, InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testTerminateAgentOnContainerTerminated() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         KubernetesSlave node = addNode(cloud, "node-123", "node");
         Pod node123 = withContainerStatusTerminated(createPod(node));
@@ -559,7 +566,7 @@ public void testTerminateAgentOnContainerTerminated() throws IOException, Interr
         r.maybeActivate();
 
         // verify node is still registered
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // verify listener got notified
         listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node);
@@ -569,11 +576,12 @@ public void testTerminateAgentOnContainerTerminated() throws IOException, Interr
         // verify computer disconnected with offline cause
         verify(node.getComputer(), atLeastOnce()).disconnect(isA(PodOfflineCause.class));
         // verify node is still registered (will be removed when pod deleted)
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
     }
 
-    @Test(timeout = 10_000)
-    public void testTerminateAgentOnPodFailed() throws IOException, InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testTerminateAgentOnPodFailed() throws Exception {
         System.out.println(server.getPort());
         KubernetesCloud cloud = addCloud("k8s", "foo");
         KubernetesSlave node = addNode(cloud, "node-123", "node");
@@ -601,7 +609,7 @@ public void testTerminateAgentOnPodFailed() throws IOException, InterruptedExcep
         r.maybeActivate();
 
         // verify node is still registered
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // verify listener got notified
         listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node);
@@ -611,11 +619,12 @@ public void testTerminateAgentOnPodFailed() throws IOException, InterruptedExcep
         // verify computer disconnected with offline cause
         verify(node.getComputer()).disconnect(isA(PodOfflineCause.class));
         // verify node is still registered (will be removed when pod deleted)
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
     }
 
-    @Test(timeout = 10_000)
-    public void testTerminateAgentOnImagePullBackoff() throws IOException, InterruptedException {
+    @Test
+    @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
+    void testTerminateAgentOnImagePullBackoff() throws Exception {
         KubernetesCloud cloud = addCloud("k8s", "foo");
         KubernetesSlave node = addNode(cloud, "node-123", "node");
         Pod node123 = withContainerImagePullBackoff(createPod(node));
@@ -647,7 +656,7 @@ public void testTerminateAgentOnImagePullBackoff() throws IOException, Interrupt
         r.maybeActivate();
 
         // verify node is still registered
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // wait for the delete event to be processed
         waitForKubeClientRequests(6).assertRequestCountAtLeast(watchPodsPath, 3);
@@ -660,7 +669,7 @@ public void testTerminateAgentOnImagePullBackoff() throws IOException, Interrupt
         // verify computer disconnected with offline cause
         verify(node.getComputer(), atLeastOnce()).disconnect(isA(PodOfflineCause.class));
         // verify node is still registered (will be removed when pod deleted)
-        assertEquals("jenkins nodes", j.jenkins.getNodes().size(), 1);
+        assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
     }
 
     private Pod withContainerImagePullBackoff(Pod pod) {
@@ -708,7 +717,7 @@ private Pod createPod(KubernetesSlave node) {
                 .build();
     }
 
-    private KubernetesSlave addNode(KubernetesCloud cld, String podName, String nodeName) throws IOException {
+    private KubernetesSlave addNode(KubernetesCloud cld, String podName, String nodeName) throws Exception {
         KubernetesSlave node = mock(KubernetesSlave.class);
         when(node.getNodeName()).thenReturn(nodeName);
         when(node.getNamespace()).thenReturn(cld.getNamespace());
@@ -742,7 +751,7 @@ private KubernetesCloud addCloud(String name, String namespace) {
      * @return captured kube client requests so far
      * @throws InterruptedException interrupted exception
      */
-    private CapturedRequests kubeClientRequests() throws InterruptedException {
+    private CapturedRequests kubeClientRequests() throws Exception {
         int count = server.getRequestCount();
         List requests = new LinkedList<>();
         while (count-- > 0) {
@@ -760,7 +769,7 @@ private CapturedRequests kubeClientRequests() throws InterruptedException {
      * @return captured requests
      * @throws InterruptedException interrupted exception
      */
-    private CapturedRequests waitForKubeClientRequests(int count) throws InterruptedException {
+    private CapturedRequests waitForKubeClientRequests(int count) throws Exception {
         List requests = new LinkedList<>();
         while (count-- > 0) {
             requests.add(server.takeRequest());
@@ -768,23 +777,6 @@ private CapturedRequests waitForKubeClientRequests(int count) throws Interrupted
         return new CapturedRequests(requests);
     }
 
-    /**
-     * Wait until the specified request is captured.
-     * @param path number of requests to wait for
-     * @return captured requests
-     * @throws InterruptedException interrupted exception
-     */
-    private CapturedRequests waitForKubeClientRequests(String path) throws InterruptedException {
-        List requests = new LinkedList<>();
-        while (true) {
-            RecordedRequest rr = server.takeRequest();
-            requests.add(rr);
-            if (rr.getPath().equals(path)) {
-                return new CapturedRequests(requests);
-            }
-        }
-    }
-
     private static class CapturedRequests {
 
         private final Map countByPath;
@@ -795,7 +787,7 @@ private static class CapturedRequests {
         }
 
         CapturedRequests assertRequestCount(String path, long count) {
-            assertEquals(path + " count", count, (long) countByPath.getOrDefault(path, 0L));
+            assertEquals(count, (long) countByPath.getOrDefault(path, 0L), path + " count");
             return this;
         }
 
@@ -806,7 +798,7 @@ CapturedRequests assertRequestCountAtLeast(String path, long count) {
     }
 
     @Extension
-    public static class CapturingReaperListener extends ExternalResource implements Reaper.Listener {
+    public static class CapturingReaperListener implements Reaper.Listener, AfterEachCallback {
 
         private static final List CAPTURED_EVENTS = new LinkedList<>();
 
@@ -815,8 +807,7 @@ public synchronized void onEvent(
                 @NonNull Watcher.Action action,
                 @NonNull KubernetesSlave node,
                 @NonNull Pod pod,
-                @NonNull Set terminationReaons)
-                throws IOException, InterruptedException {
+                @NonNull Set terminationReasons) {
             CAPTURED_EVENTS.add(new ReaperListenerWatchEvent(action, node, pod));
             notifyAll();
         }
@@ -824,8 +815,7 @@ public synchronized void onEvent(
         /**
          * Test should use {@link #waitForEvents()}, not this method
          */
-        private synchronized CapturingReaperListener waitForEventsOnJenkinsExtensionInstance()
-                throws InterruptedException {
+        private synchronized CapturingReaperListener waitForEventsOnJenkinsExtensionInstance() throws Exception {
             while (CAPTURED_EVENTS.isEmpty()) {
                 wait();
             }
@@ -837,7 +827,7 @@ private synchronized CapturingReaperListener waitForEventsOnJenkinsExtensionInst
          * @return jenkins extension instance
          * @throws InterruptedException if wait was interrupted
          */
-        public CapturingReaperListener waitForEvents() throws InterruptedException {
+        public CapturingReaperListener waitForEvents() throws Exception {
             // find the instance that Jenkins created and wait on that one
             CapturingReaperListener l =
                     Jenkins.get().getExtensionList(Reaper.Listener.class).get(CapturingReaperListener.class);
@@ -855,18 +845,18 @@ public CapturingReaperListener waitForEvents() throws InterruptedException {
          */
         public synchronized void expectEvent(Watcher.Action action, KubernetesSlave node) {
             boolean found = CAPTURED_EVENTS.stream().anyMatch(e -> e.action == action && e.node == node);
-            assertTrue("expected event: " + action + ", " + node, found);
+            assertTrue(found, "expected event: " + action + ", " + node);
         }
 
         /**
          * Expect not event to have been received.
          */
         public synchronized void expectNoEvents() {
-            assertEquals("no watcher events", 0, CAPTURED_EVENTS.size());
+            assertEquals(0, CAPTURED_EVENTS.size(), "no watcher events");
         }
 
         @Override
-        protected void after() {
+        public void afterEach(ExtensionContext context) {
             CAPTURED_EVENTS.clear();
         }
     }
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java
index 2d62083a96..18b771e623 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/GenericEphemeralVolumeTest.java
@@ -1,14 +1,14 @@
 package org.csanchez.jenkins.plugins.kubernetes.volumes;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import io.fabric8.kubernetes.api.model.Volume;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class GenericEphemeralVolumeTest {
+class GenericEphemeralVolumeTest {
 
     @Test
-    public void testCreatesVolumeCorrectly() {
+    void testCreatesVolumeCorrectly() {
 
         GenericEphemeralVolume genericEphemeralVolume = new GenericEphemeralVolume();
         genericEphemeralVolume.setAccessModes("ReadWriteOnce");
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java
index 3652732275..9d30e75a5e 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace/GenericEphemeralWorkspaceVolumeTest.java
@@ -1,14 +1,14 @@
 package org.csanchez.jenkins.plugins.kubernetes.volumes.workspace;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import io.fabric8.kubernetes.api.model.Volume;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 
-public class GenericEphemeralWorkspaceVolumeTest {
+class GenericEphemeralWorkspaceVolumeTest {
 
     @Test
-    public void testCreatesVolumeCorrectly() {
+    void testCreatesVolumeCorrectly() {
 
         GenericEphemeralWorkspaceVolume genericEphemeralWorkspaceVolume = new GenericEphemeralWorkspaceVolume();
         genericEphemeralWorkspaceVolume.setStorageClassName("test-storageclass");
From 9edb524d49f5addf2da97f258959d38cdd0c657c Mon Sep 17 00:00:00 2001
From: Vincent Latombe 
Date: Mon, 25 Aug 2025 13:27:42 +0200
Subject: [PATCH 2/3] Fixing ReaperTest
* ReaperListenerWatchEvent converted to record
* CapturingReaperListener#CAPTURED_EVENTS not static anymore. Removed Junit extension as it was not actually needed.
* Use await() instead of relying on java monitor and synchronized.
---
 .../kubernetes/pod/retention/ReaperTest.java  | 129 ++++++++----------
 1 file changed, 56 insertions(+), 73 deletions(-)
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
index d9bd297e8c..76bd480f3d 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/pod/retention/ReaperTest.java
@@ -30,7 +30,7 @@
 import static org.mockito.Mockito.*;
 
 import edu.umd.cs.findbugs.annotations.NonNull;
-import hudson.Extension;
+import hudson.ExtensionList;
 import hudson.model.TaskListener;
 import hudson.slaves.ComputerLauncher;
 import hudson.util.StreamTaskListener;
@@ -47,19 +47,20 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
 import java.util.stream.Collectors;
-import jenkins.model.Jenkins;
 import org.csanchez.jenkins.plugins.kubernetes.*;
 import org.csanchez.jenkins.plugins.kubernetes.PodTemplate;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
-import org.junit.jupiter.api.extension.AfterEachCallback;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.api.extension.RegisterExtension;
 import org.jvnet.hudson.test.JenkinsRule;
+import org.jvnet.hudson.test.TestExtension;
 import org.jvnet.hudson.test.junit.jupiter.WithJenkins;
 
 @WithJenkins
@@ -70,9 +71,6 @@ class ReaperTest {
 
     private JenkinsRule j;
 
-    @RegisterExtension
-    private final CapturingReaperListener listener = new CapturingReaperListener();
-
     private KubernetesMockServer server;
     private KubernetesClient client;
 
@@ -209,7 +207,7 @@ void testReconnectOnNewComputer() throws Exception {
         waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2);
 
         // error status event should be filtered out
-        listener.expectNoEvents();
+        getReaperListener().expectNoEvents();
 
         // wait until watch is removed
         System.out.println("Waiting for watch to be removed");
@@ -228,6 +226,10 @@ void testReconnectOnNewComputer() throws Exception {
         System.out.println("Watch started");
     }
 
+    private CapturingReaperListener getReaperListener() {
+        return ExtensionList.lookupSingleton(CapturingReaperListener.class);
+    }
+
     @Test
     @Timeout(value = 10_000, unit = TimeUnit.MILLISECONDS)
     void testAddWatchWhenCloudAdded() throws Exception {
@@ -336,7 +338,7 @@ void testReplaceWatchWhenCloudUpdated() throws Exception {
         // watch is still active
         assertShouldBeWatching(r, cloud);
 
-        listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node);
+        getReaperListener().expectEvent(Watcher.Action.MODIFIED, node);
         kubeClientRequests().assertRequestCountAtLeast(watchBarPodsPath, 1);
     }
 
@@ -368,7 +370,7 @@ void testStopWatchingOnCloseException() throws Exception {
         waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2);
 
         // error status event should be filtered out
-        listener.expectNoEvents();
+        getReaperListener().expectNoEvents();
 
         // watch is removed
         assertShouldNotBeWatching(r, cloud);
@@ -410,7 +412,7 @@ void testKeepWatchingOnKubernetesApiServerError() throws Exception {
         waitForKubeClientRequests(3).assertRequestCount(watchPodsPath, 3);
 
         // error status event should be filtered out
-        listener.expectNoEvents();
+        getReaperListener().expectNoEvents();
 
         // watch is still active
         assertShouldBeWatching(r, cloud);
@@ -442,7 +444,7 @@ void testKeepWatchingOnStatusWatchEvent() throws Exception {
         waitForKubeClientRequests(2).assertRequestCount(watchPodsPath, 2);
 
         // error status event should be filtered out
-        listener.expectNoEvents();
+        getReaperListener().expectNoEvents();
 
         // watch is still active
         assertShouldBeWatching(r, cloud);
@@ -513,7 +515,7 @@ void testDeleteNodeOnPodDelete() throws Exception {
                 .assertRequestCountAtLeast("/api/v1/namespaces/foo/pods?allowWatchBookmarks=true&watch=true", 3);
 
         // verify listener got notified
-        listener.expectEvent(Watcher.Action.DELETED, node);
+        getReaperListener().expectEvent(Watcher.Action.DELETED, node);
 
         // verify computer disconnected with offline cause
         verify(node.getComputer()).disconnect(isA(PodOfflineCause.class));
@@ -569,7 +571,7 @@ void testTerminateAgentOnContainerTerminated() throws Exception {
         assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // verify listener got notified
-        listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node);
+        getReaperListener().expectEvent(Watcher.Action.MODIFIED, node);
 
         // expect node to be terminated
         verify(node, atLeastOnce()).terminate();
@@ -612,7 +614,7 @@ void testTerminateAgentOnPodFailed() throws Exception {
         assertEquals(1, j.jenkins.getNodes().size(), "jenkins nodes");
 
         // verify listener got notified
-        listener.waitForEvents().expectEvent(Watcher.Action.MODIFIED, node);
+        getReaperListener().expectEvent(Watcher.Action.MODIFIED, node);
 
         // expect node to be terminated
         verify(node, atLeastOnce()).terminate();
@@ -662,7 +664,7 @@ void testTerminateAgentOnImagePullBackoff() throws Exception {
         waitForKubeClientRequests(6).assertRequestCountAtLeast(watchPodsPath, 3);
 
         // verify listener got notified
-        listener.expectEvent(Watcher.Action.MODIFIED, node);
+        getReaperListener().expectEvent(Watcher.Action.MODIFIED, node);
 
         // expect node to be terminated
         verify(node, atLeastOnce()).terminate();
@@ -797,10 +799,12 @@ CapturedRequests assertRequestCountAtLeast(String path, long count) {
         }
     }
 
-    @Extension
-    public static class CapturingReaperListener implements Reaper.Listener, AfterEachCallback {
+    @TestExtension
+    public static class CapturingReaperListener implements Reaper.Listener {
+
+        private final List capturedEvents = new CopyOnWriteArrayList<>();
 
-        private static final List CAPTURED_EVENTS = new LinkedList<>();
+        private static final Logger LOGGER = Logger.getLogger(CapturingReaperListener.class.getName());
 
         @Override
         public synchronized void onEvent(
@@ -808,75 +812,54 @@ public synchronized void onEvent(
                 @NonNull KubernetesSlave node,
                 @NonNull Pod pod,
                 @NonNull Set terminationReasons) {
-            CAPTURED_EVENTS.add(new ReaperListenerWatchEvent(action, node, pod));
-            notifyAll();
+            LOGGER.info(this + " capturing event: " + action + " for node: " + node + " pod: " + pod);
+            capturedEvents.add(new ReaperListenerWatchEvent(action, node, pod));
         }
 
-        /**
-         * Test should use {@link #waitForEvents()}, not this method
-         */
-        private synchronized CapturingReaperListener waitForEventsOnJenkinsExtensionInstance() throws Exception {
-            while (CAPTURED_EVENTS.isEmpty()) {
-                wait();
+        private static class ReaperListenerWatchEventMatcher extends TypeSafeMatcher {
+            private final Watcher.Action action;
+            private final KubernetesSlave node;
+
+            public ReaperListenerWatchEventMatcher(Watcher.Action action, KubernetesSlave node) {
+                this.action = action;
+                this.node = node;
             }
-            return this;
-        }
 
-        /**
-         * Tests should use this method to wait for events to be processed by the Reaper cloud watcher.
-         * @return jenkins extension instance
-         * @throws InterruptedException if wait was interrupted
-         */
-        public CapturingReaperListener waitForEvents() throws Exception {
-            // find the instance that Jenkins created and wait on that one
-            CapturingReaperListener l =
-                    Jenkins.get().getExtensionList(Reaper.Listener.class).get(CapturingReaperListener.class);
-            if (l == null) {
-                throw new RuntimeException("CapturingReaperListener not registered in Jenkins");
+            @Override
+            protected boolean matchesSafely(ReaperListenerWatchEvent event) {
+                return event.action == action && event.node == node;
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description
+                        .appendText("event with action ")
+                        .appendValue(action)
+                        .appendText(" and node ")
+                        .appendValue(node);
             }
 
-            return l.waitForEventsOnJenkinsExtensionInstance();
+            @Override
+            protected void describeMismatchSafely(ReaperListenerWatchEvent item, Description mismatchDescription) {
+                mismatchDescription.appendText("was ").appendValue(item);
+            }
         }
 
-        /**
-         * Verify that the watcher received an event of the given action and target node.
-         * @param action action to match
-         * @param node target node
-         */
-        public synchronized void expectEvent(Watcher.Action action, KubernetesSlave node) {
-            boolean found = CAPTURED_EVENTS.stream().anyMatch(e -> e.action == action && e.node == node);
-            assertTrue(found, "expected event: " + action + ", " + node);
+        public void expectEvent(Watcher.Action action, KubernetesSlave node) {
+            await().until(
+                            () -> capturedEvents,
+                            hasItem(new CapturingReaperListener.ReaperListenerWatchEventMatcher(action, node)));
         }
 
         /**
          * Expect not event to have been received.
          */
-        public synchronized void expectNoEvents() {
-            assertEquals(0, CAPTURED_EVENTS.size(), "no watcher events");
-        }
-
-        @Override
-        public void afterEach(ExtensionContext context) {
-            CAPTURED_EVENTS.clear();
+        public void expectNoEvents() {
+            assertThat("no watcher events", capturedEvents, empty());
         }
     }
 
-    private static class ReaperListenerWatchEvent {
-        final Watcher.Action action;
-        final KubernetesSlave node;
-        final Pod pod;
-
-        private ReaperListenerWatchEvent(Watcher.Action action, KubernetesSlave node, Pod pod) {
-            this.action = action;
-            this.node = node;
-            this.pod = pod;
-        }
-
-        @Override
-        public String toString() {
-            return "[" + action + ", " + node + ", " + pod + "]";
-        }
-    }
+    private record ReaperListenerWatchEvent(Watcher.Action action, KubernetesSlave node, Pod pod) {}
 
     private static WatchEvent outdatedEvent() {
         return new WatchEventBuilder()
From 27f306a08a5413ff4f937dcf85c3ad1ef39b17a6 Mon Sep 17 00:00:00 2001
From: strangelookingnerd
 <49242855+strangelookingnerd@users.noreply.github.com>
Date: Mon, 8 Sep 2025 15:34:35 +0200
Subject: [PATCH 3/3] Fix merge
---
 .../plugins/kubernetes/ClientAuthenticationTest.java     | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java
index f55cfa7c76..63d0aed2b2 100644
--- a/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java
+++ b/src/test/java/org/csanchez/jenkins/plugins/kubernetes/ClientAuthenticationTest.java
@@ -32,19 +32,16 @@
 
 import io.fabric8.kubernetes.client.KubernetesClient;
 import java.net.URL;
-import java.util.logging.Logger;
 import org.jenkinsci.plugins.kubernetes.auth.KubernetesAuthException;
-import org.junit.Test;
+import org.junit.jupiter.api.Test;
 import org.jvnet.hudson.test.Issue;
 import org.mockito.MockedStatic;
 
-public class ClientAuthenticationTest {
-
-    private static final Logger LOGGER = Logger.getLogger(ClientAuthenticationTest.class.getName());
+class ClientAuthenticationTest {
 
     @Issue("JENKINS-76047")
     @Test
-    public void testConnectCallsCreateClient() throws Exception {
+    void testConnectCallsCreateClient() throws Exception {
         KubernetesClient mockClient = mock(KubernetesClient.class);
         when(mockClient.getMasterUrl()).thenReturn(new URL("http://localhost:9999/"));