diff --git a/testing-modules/junit5-annotations/pom.xml b/testing-modules/junit5-annotations/pom.xml
index d0fba4d21b..9e51d0ab55 100644
--- a/testing-modules/junit5-annotations/pom.xml
+++ b/testing-modules/junit5-annotations/pom.xml
@@ -46,12 +46,19 @@
             ${junit.platform.version}
             test
         
+        
+            org.assertj
+            assertj-core
+            ${assertj-core.version}
+            test
+        
     
 
     
-        5.6.0
+        5.6.2
         1.6.0
         2.8.2
+        3.11.1
     
 
 
diff --git a/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGenerator.java b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGenerator.java
new file mode 100644
index 0000000000..f19adb13c8
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGenerator.java
@@ -0,0 +1,5 @@
+package com.baeldung.junit5.templates;
+
+public interface UserIdGenerator {
+    String generate(String firstName, String lastName);
+}
diff --git a/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGeneratorImpl.java b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGeneratorImpl.java
new file mode 100644
index 0000000000..b39b07bc4b
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/main/java/com/baeldung/junit5/templates/UserIdGeneratorImpl.java
@@ -0,0 +1,15 @@
+package com.baeldung.junit5.templates;
+
+public class UserIdGeneratorImpl implements UserIdGenerator {
+    private boolean isFeatureEnabled;
+
+    public UserIdGeneratorImpl(boolean isFeatureEnabled) {
+        this.isFeatureEnabled = isFeatureEnabled;
+    }
+
+    public String generate(String firstName, String lastName) {
+        String initialAndLastName = firstName.substring(0, 1)
+            .concat(lastName);
+        return isFeatureEnabled ? "bael".concat(initialAndLastName) : initialAndLastName;
+    }
+}
diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java
new file mode 100644
index 0000000000..cd8b7b677d
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/DisabledOnQAEnvironmentExtension.java
@@ -0,0 +1,27 @@
+package com.baeldung.junit5.templates;
+
+import org.junit.jupiter.api.extension.ConditionEvaluationResult;
+import org.junit.jupiter.api.extension.ExecutionCondition;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import java.io.IOException;
+import java.util.Properties;
+
+public class DisabledOnQAEnvironmentExtension implements ExecutionCondition {
+    @Override
+    public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
+        Properties properties = new Properties();
+        try {
+            properties.load(DisabledOnQAEnvironmentExtension.class.getClassLoader()
+                .getResourceAsStream("application.properties"));
+            if ("qa".equalsIgnoreCase(properties.getProperty("env"))) {
+                String reason = String.format("The test '%s' is disabled on QA environment", context.getDisplayName());
+                System.out.println(reason);
+                return ConditionEvaluationResult.disabled(reason);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return ConditionEvaluationResult.enabled("Test enabled");
+    }
+}
\ No newline at end of file
diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/GenericTypedParameterResolver.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/GenericTypedParameterResolver.java
new file mode 100644
index 0000000000..76321be101
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/GenericTypedParameterResolver.java
@@ -0,0 +1,26 @@
+package com.baeldung.junit5.templates;
+
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class GenericTypedParameterResolver implements ParameterResolver {
+    T data;
+
+    public GenericTypedParameterResolver(T data) {
+        this.data = data;
+    }
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return parameterContext.getParameter()
+            .getType()
+            .isInstance(data);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
+        return data;
+    }
+}
diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorImplUnitTest.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorImplUnitTest.java
new file mode 100644
index 0000000000..a2306154a6
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorImplUnitTest.java
@@ -0,0 +1,18 @@
+package com.baeldung.junit5.templates;
+
+import org.junit.jupiter.api.TestTemplate;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class UserIdGeneratorImplUnitTest {
+    @TestTemplate
+    @ExtendWith(UserIdGeneratorTestInvocationContextProvider.class)
+    public void whenUserIdRequested_thenUserIdIsReturnedInCorrectFormat(UserIdGeneratorTestCase testCase) {
+        UserIdGenerator userIdGenerator = new UserIdGeneratorImpl(testCase.isFeatureEnabled());
+
+        String actualUserId = userIdGenerator.generate(testCase.getFirstName(), testCase.getLastName());
+
+        assertThat(actualUserId).isEqualTo(testCase.getExpectedUserId());
+    }
+}
\ No newline at end of file
diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestCase.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestCase.java
new file mode 100644
index 0000000000..dd41dd5a27
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestCase.java
@@ -0,0 +1,37 @@
+package com.baeldung.junit5.templates;
+
+public class UserIdGeneratorTestCase {
+    private String displayName;
+    private boolean isFeatureEnabled;
+    private String firstName;
+    private String lastName;
+    private String expectedUserId;
+
+    public UserIdGeneratorTestCase(String displayName, boolean isFeatureEnabled, String firstName, String lastName, String expectedUserId) {
+        this.displayName = displayName;
+        this.isFeatureEnabled = isFeatureEnabled;
+        this.firstName = firstName;
+        this.lastName = lastName;
+        this.expectedUserId = expectedUserId;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public boolean isFeatureEnabled() {
+        return isFeatureEnabled;
+    }
+
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public String getLastName() {
+        return lastName;
+    }
+
+    public String getExpectedUserId() {
+        return expectedUserId;
+    }
+}
diff --git a/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java
new file mode 100644
index 0000000000..277ec03f05
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/java/com/baeldung/junit5/templates/UserIdGeneratorTestInvocationContextProvider.java
@@ -0,0 +1,87 @@
+package com.baeldung.junit5.templates;
+
+import org.junit.jupiter.api.extension.*;
+
+import java.util.List;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+
+public class UserIdGeneratorTestInvocationContextProvider implements TestTemplateInvocationContextProvider {
+
+    @Override
+    public boolean supportsTestTemplate(ExtensionContext extensionContext) {
+        return true;
+    }
+
+    @Override
+    public Stream provideTestTemplateInvocationContexts(ExtensionContext extensionContext) {
+        boolean featureDisabled = false;
+        boolean featureEnabled = true;
+        return Stream.of(
+            featureDisabledContext(
+                new UserIdGeneratorTestCase(
+                    "Given feature switch disabled When user name is John Smith Then generated userid is JSmith",
+                    featureDisabled, "John", "Smith", "JSmith")),
+            featureEnabledContext(
+                new UserIdGeneratorTestCase(
+                    "Given feature switch enabled When user name is John Smith Then generated userid is baelJSmith",
+                    featureEnabled, "John", "Smith", "baelJSmith"))
+        );
+    }
+
+    private TestTemplateInvocationContext featureDisabledContext(UserIdGeneratorTestCase userIdGeneratorTestCase) {
+        return new TestTemplateInvocationContext() {
+            @Override
+            public String getDisplayName(int invocationIndex) {
+                return userIdGeneratorTestCase.getDisplayName();
+            }
+
+            @Override
+            public List getAdditionalExtensions() {
+                return asList(
+                    new GenericTypedParameterResolver(userIdGeneratorTestCase), 
+                    new BeforeTestExecutionCallback() {
+                        @Override
+                        public void beforeTestExecution(ExtensionContext extensionContext) {
+                            System.out.println("BeforeTestExecutionCallback:Disabled context");
+                        }
+                    }, 
+                    new AfterTestExecutionCallback() {
+                        @Override
+                        public void afterTestExecution(ExtensionContext extensionContext) {
+                            System.out.println("AfterTestExecutionCallback:Disabled context");
+                        }
+                });
+            }
+        };
+    }
+
+    private TestTemplateInvocationContext featureEnabledContext(UserIdGeneratorTestCase userIdGeneratorTestCase) {
+        return new TestTemplateInvocationContext() {
+            @Override
+            public String getDisplayName(int invocationIndex) {
+                return userIdGeneratorTestCase.getDisplayName();
+            }
+
+            @Override
+            public List getAdditionalExtensions() {
+                return asList(
+                    new GenericTypedParameterResolver(userIdGeneratorTestCase), 
+                    new DisabledOnQAEnvironmentExtension(), 
+                    new BeforeEachCallback() {
+                        @Override
+                        public void beforeEach(ExtensionContext extensionContext) {
+                            System.out.println("BeforeEachCallback:Enabled context");
+                        }
+                    }, 
+                    new AfterEachCallback() {
+                        @Override
+                        public void afterEach(ExtensionContext extensionContext) {
+                            System.out.println("AfterEachCallback:Enabled context");
+                        }
+                    });
+            }
+        };
+    }
+}
diff --git a/testing-modules/junit5-annotations/src/test/resources/application.properties b/testing-modules/junit5-annotations/src/test/resources/application.properties
new file mode 100644
index 0000000000..bbfa14d866
--- /dev/null
+++ b/testing-modules/junit5-annotations/src/test/resources/application.properties
@@ -0,0 +1 @@
+env=qa
\ No newline at end of file