Repository: authorjapps/zerocode
Pull request #234 (2019-04-26 21:53:53)

ISS-226 # JUnit5 Jupiter Load Extension for Performance Testing
Passed now - https://travis-ci.org/authorjapps/zerocode/builds/525296505
_It was the pom issue_

This runs Jupiter tests in parallel for generating Load/Stress on the target system.
Extension name: `ZeroCodeParallelExtension`

Examples and usage are in this PR-
https://github.com/authorjapps/performance-tests/pull/3/files

Please have a look at the below parallel load examples(in the above PR)-

JUnit5LoadTest.java
JUnit5LoadCommonLoadTest.java
JUnit5LoadDifferentLoadTest.java



Patch:
diff --git a/.gitignore b/.gitignore
index 302c16c4..1b257ebf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,7 @@ hs_err_pid*
 *.idea
 /target
 .DS_Store
-
+package.properties
 
 #for eclipse
 .classpath
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/LoadWith.java b/core/src/main/java/org/jsmart/zerocode/core/domain/LoadWith.java
index f41b542e..6bf5b30b 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/LoadWith.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/LoadWith.java
@@ -1,12 +1,9 @@
 package org.jsmart.zerocode.core.domain;
 
-import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
 public @interface LoadWith {
     String value();
 }
\ No newline at end of file
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilder.java b/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilder.java
similarity index 88%
rename from core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilder.java
rename to core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilder.java
index b10841ab..67c74e52 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilder.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilder.java
@@ -18,8 +18,8 @@ import java.util.concurrent.Executors;
 import static org.jsmart.zerocode.core.domain.reports.ZeroCodeReportProperties.TARGET_REPORT_DIR;
 import static org.slf4j.LoggerFactory.getLogger;
 
-public class ZeroCodeReportBuilder {
-    private static final org.slf4j.Logger LOGGER = getLogger(ZeroCodeReportBuilder.class);
+public class ZeroCodeExecResultIoWriteBuilder {
+    private static final org.slf4j.Logger LOGGER = getLogger(ZeroCodeExecResultIoWriteBuilder.class);
     public static final int REPORT_WRITING_THREAD_POOL = 5;
 
     private LocalDateTime timeStamp;
@@ -28,8 +28,8 @@ public class ZeroCodeReportBuilder {
 
     private ExecutorService executorService = Executors.newFixedThreadPool(REPORT_WRITING_THREAD_POOL);
 
-    public static ZeroCodeReportBuilder newInstance() {
-        return new ZeroCodeReportBuilder();
+    public static ZeroCodeExecResultIoWriteBuilder newInstance() {
+        return new ZeroCodeExecResultIoWriteBuilder();
     }
 
     public ZeroCodeReport build() {
@@ -39,17 +39,17 @@ public class ZeroCodeReportBuilder {
         return built;
     }
 
-    public ZeroCodeReportBuilder timeStamp(LocalDateTime timeStamp) {
+    public ZeroCodeExecResultIoWriteBuilder timeStamp(LocalDateTime timeStamp) {
         this.timeStamp = timeStamp;
         return this;
     }
 
-    public ZeroCodeReportBuilder results(List<ZeroCodeExecResult> results) {
+    public ZeroCodeExecResultIoWriteBuilder results(List<ZeroCodeExecResult> results) {
         this.results = results;
         return this;
     }
 
-    public ZeroCodeReportBuilder result(ZeroCodeExecResult result) {
+    public ZeroCodeExecResultIoWriteBuilder result(ZeroCodeExecResult result) {
         this.results.add(result);
         return this;
     }
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportStepBuilder.java b/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportStepBuilder.java
index 70e2fff5..27473c0a 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportStepBuilder.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportStepBuilder.java
@@ -17,6 +17,7 @@ public class ZeroCodeReportStepBuilder {
     String request;
     String response;
     String id;
+    String assertions;
 
     public static ZeroCodeReportStepBuilder newInstance() {
         return new ZeroCodeReportStepBuilder();
@@ -27,7 +28,7 @@ public class ZeroCodeReportStepBuilder {
                 loop, name, url,
                 correlationId, operation, requestTimeStamp,
                 responseTimeStamp, responseDelay, result,
-                request, response);
+                request, response, assertions);
         return built;
     }
 
@@ -86,6 +87,11 @@ public class ZeroCodeReportStepBuilder {
         return this;
     }
 
+    public ZeroCodeReportStepBuilder assertions(String assertions) {
+        this.assertions = assertions;
+        return this;
+    }
+
     public ZeroCodeReportStepBuilder id(String id) {
         this.id = id;
         return this;
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportStep.java b/core/src/main/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportStep.java
index fe25353f..925aaf00 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportStep.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportStep.java
@@ -25,21 +25,22 @@ public class ZeroCodeReportStep {
     private final String result;
     private final String request;
     private final String response;
+    private final String assertions;
 
     @JsonCreator
     public ZeroCodeReportStep(
-            @JsonProperty("stepLoop")Integer loop,
-            @JsonProperty("name")String name,
-            @JsonProperty("url")String url,
-            @JsonProperty("correlationId")String correlationId,
-            @JsonProperty("operation")String operation,
-            @JsonProperty("requestTimeStamp")LocalDateTime requestTimeStamp,
-            @JsonProperty("responseTimeStamp")LocalDateTime responseTimeStamp,
-            @JsonProperty("responseDelay")Double responseDelay,
-            @JsonProperty("result")String result,
-            @JsonProperty("request")String request,
-            @JsonProperty("response")String response
-    ) {
+            @JsonProperty("stepLoop") Integer loop,
+            @JsonProperty("name") String name,
+            @JsonProperty("url") String url,
+            @JsonProperty("correlationId") String correlationId,
+            @JsonProperty("operation") String operation,
+            @JsonProperty("requestTimeStamp") LocalDateTime requestTimeStamp,
+            @JsonProperty("responseTimeStamp") LocalDateTime responseTimeStamp,
+            @JsonProperty("responseDelay") Double responseDelay,
+            @JsonProperty("result") String result,
+            @JsonProperty("request") String request,
+            @JsonProperty("response") String response,
+            @JsonProperty("assertions") String assertions) {
         this.loop = loop;
         this.name = name;
         this.url = url;
@@ -51,6 +52,7 @@ public class ZeroCodeReportStep {
         this.result = result;
         this.request = request;
         this.response = response;
+        this.assertions = assertions;
     }
 
     public Integer getLoop() {
@@ -93,14 +95,14 @@ public class ZeroCodeReportStep {
         return request;
     }
 
-//    public JsonNode getRequest() throws IOException {
-//        return new ObjectMapperProvider().get().readTree(request);
-//    }
-
     public String getResponse() {
         return response;
     }
 
+    public String getAssertions() {
+        return assertions;
+    }
+
     @Override
     public String toString() {
         return "ZeroCodeReportStep{" +
@@ -115,6 +117,7 @@ public class ZeroCodeReportStep {
                 ", result='" + result + '\'' +
                 ", request='" + request + '\'' +
                 ", response='" + response + '\'' +
+                ", assertions='" + assertions + '\'' +
                 '}';
     }
 }
diff --git a/core/src/main/java/org/jsmart/zerocode/core/logbuilder/LogCorrelationshipPrinter.java b/core/src/main/java/org/jsmart/zerocode/core/logbuilder/LogCorrelationshipPrinter.java
index a23f1adb..bd0d66d9 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/logbuilder/LogCorrelationshipPrinter.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/logbuilder/LogCorrelationshipPrinter.java
@@ -61,14 +61,13 @@ public class LogCorrelationshipPrinter {
         ZeroCodeReportStepBuilder zeroCodeReportStep = ZeroCodeReportStepBuilder.newInstance()
                 //.request(requestLogBuilder.request) //TODO
                 //.response(responseLogBuilder.response) //TODO
-                //.assertions()
                 .loop(stepLoop)
                 .name(requestLogBuilder.getStepName())
                 .correlationId(getCorrelationId())
                 .result(result == true? RESULT_PASS : RESULT_FAIL)
                 .url(requestLogBuilder.getUrl())
                 .operation(requestLogBuilder.getMethod())
-                .result(responseLogBuilder.getAssertion())
+                .assertions(responseLogBuilder.getAssertion())
                 .requestTimeStamp(requestLogBuilder.getRequestTimeStamp())
                 .responseTimeStamp(responseLogBuilder.responseTimeStamp)
                 .responseDelay(responseDelay)
diff --git a/core/src/main/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImpl.java b/core/src/main/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImpl.java
index 40f4b694..45377ec5 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImpl.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImpl.java
@@ -69,8 +69,7 @@ public class ZeroCodeReportGeneratorImpl implements ZeroCodeReportGenerator {
     @Named("interactive.html.report.disabled")
     private boolean interactiveHtmlReportDisabled;
 
-    @Inject
-    private ObjectMapper mapper;
+    private final ObjectMapper mapper;
 
     private List<ZeroCodeReport> treeReports;
 
@@ -78,7 +77,9 @@ public class ZeroCodeReportGeneratorImpl implements ZeroCodeReportGenerator {
 
     private List<ZeroCodeCsvReport> csvRows = new ArrayList<>();
 
-    public ZeroCodeReportGeneratorImpl() {
+    @Inject
+    public ZeroCodeReportGeneratorImpl(ObjectMapper mapper) {
+        this.mapper = mapper;
     }
 
     @Override
@@ -114,7 +115,7 @@ public class ZeroCodeReportGeneratorImpl implements ZeroCodeReportGenerator {
                     	step.info(MarkupHelper.createCodeBlock(thisStep.getOperation() + "\t" + thisStep.getUrl()));
                     	step.info(MarkupHelper.createCodeBlock(thisStep.getRequest(), CodeLanguage.JSON));
                         step.info(MarkupHelper.createCodeBlock(thisStep.getResponse(), CodeLanguage.JSON));
-                    	step.fail(MarkupHelper.createCodeBlock("Reason:\n" + thisStep.getResult()));
+                    	step.fail(MarkupHelper.createCodeBlock("Reason:\n" + thisStep.getAssertions()));
                     }
                     extentReports.flush();
                 });
diff --git a/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java b/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
index 83c987a2..b46988c8 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeMultiStepsScenarioRunnerImpl.java
@@ -9,7 +9,7 @@ import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
 import org.jsmart.zerocode.core.domain.ScenarioSpec;
 import org.jsmart.zerocode.core.domain.Step;
 import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder;
-import org.jsmart.zerocode.core.domain.builders.ZeroCodeReportBuilder;
+import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultIoWriteBuilder;
 import org.jsmart.zerocode.core.engine.assertion.AssertionReport;
 import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;
 import org.jsmart.zerocode.core.engine.executor.JsonServiceExecutor;
@@ -72,7 +72,7 @@ public class ZeroCodeMultiStepsScenarioRunnerImpl implements ZeroCodeMultiStepsS
 
     private static StepNotificationHandler notificationHandler = new StepNotificationHandler();
 
-    private ZeroCodeReportBuilder reportBuilder;
+    private ZeroCodeExecResultIoWriteBuilder reportBuilder;
 
     private ZeroCodeExecResultBuilder reportResultBuilder;
 
@@ -83,7 +83,7 @@ public class ZeroCodeMultiStepsScenarioRunnerImpl implements ZeroCodeMultiStepsS
 
         LOGGER.info("\n-------------------------- BDD: Scenario:{} -------------------------\n", scenario.getScenarioName());
 
-        reportBuilder = ZeroCodeReportBuilder.newInstance().timeStamp(LocalDateTime.now());
+        reportBuilder = ZeroCodeExecResultIoWriteBuilder.newInstance().timeStamp(LocalDateTime.now());
 
         ScenarioExecutionState scenarioExecutionState = new ScenarioExecutionState();
 
diff --git a/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeUnitRunner.java b/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeUnitRunner.java
index 2e44271c..0d860c6e 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeUnitRunner.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/runner/ZeroCodeUnitRunner.java
@@ -4,12 +4,11 @@ import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.util.Modules;
 import org.jsmart.zerocode.core.di.main.ApplicationMainModule;
-import org.jsmart.zerocode.core.di.module.PropertiesInjectorModule;
 import org.jsmart.zerocode.core.di.module.RuntimeHttpClientModule;
 import org.jsmart.zerocode.core.di.module.RuntimeKafkaClientModule;
 import org.jsmart.zerocode.core.domain.*;
 import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder;
-import org.jsmart.zerocode.core.domain.builders.ZeroCodeReportBuilder;
+import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultIoWriteBuilder;
 import org.jsmart.zerocode.core.engine.listener.ZeroCodeTestReportListener;
 import org.jsmart.zerocode.core.httpclient.BasicHttpClient;
 import org.jsmart.zerocode.core.httpclient.ssl.SslTrustHttpClient;
@@ -285,7 +284,7 @@ public class ZeroCodeUnitRunner extends BlockJUnit4ClassRunner {
         ZeroCodeExecResultBuilder reportResultBuilder = newInstance().loop(0).scenarioName(description.getClassName());
         reportResultBuilder.step(logCorrelationshipPrinter.buildReportSingleStep());
 
-        ZeroCodeReportBuilder reportBuilder = ZeroCodeReportBuilder.newInstance().timeStamp(LocalDateTime.now());
+        ZeroCodeExecResultIoWriteBuilder reportBuilder = ZeroCodeExecResultIoWriteBuilder.newInstance().timeStamp(LocalDateTime.now());
         reportBuilder.result(reportResultBuilder.build());
         reportBuilder.printToFile(description.getClassName() + logCorrelationshipPrinter.getCorrelationId() + ".json");
     }
diff --git a/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/LoadProcessor.java b/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/LoadProcessor.java
index d42d3693..1fca8fa5 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/LoadProcessor.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/LoadProcessor.java
@@ -1,5 +1,6 @@
 package org.jsmart.zerocode.core.runner.parallel;
 
+import java.util.concurrent.atomic.AtomicInteger;
 import org.jsmart.zerocode.parallel.ExecutorServiceRunner;
 import org.junit.runner.JUnitCore;
 import org.junit.runner.Request;
@@ -7,16 +8,16 @@ import org.junit.runner.Result;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.concurrent.atomic.AtomicInteger;
-
 import static java.time.LocalDateTime.now;
 
 public class LoadProcessor {
     private static final Logger LOGGER = LoggerFactory.getLogger(LoadProcessor.class);
 
     private final String loadPropertiesFile;
+
     private final AtomicInteger passedCounter = new AtomicInteger();
     private final AtomicInteger failedCounter = new AtomicInteger();
+
     private ExecutorServiceRunner executorServiceRunner;
     private boolean failed = true;
     private boolean passed = !failed;
@@ -26,6 +27,18 @@ public class LoadProcessor {
         executorServiceRunner = new ExecutorServiceRunner(loadPropertiesFile);
     }
 
+    public ExecutorServiceRunner getExecutorServiceRunner() {
+        return executorServiceRunner;
+    }
+
+    public AtomicInteger getPassedCounter() {
+        return passedCounter;
+    }
+
+    public AtomicInteger getFailedCounter() {
+        return failedCounter;
+    }
+
     public LoadProcessor addTest(Class<?> testClass, String testMethod) {
 
         Runnable zeroCodeJunitTest = createRunnable(testClass, testMethod);
@@ -39,13 +52,30 @@ public class LoadProcessor {
         executorServiceRunner.runRunnables();
 
         LOGGER.info(
-                  "\n------------------------------------"
-                + "\n   >> Total load test count:" + (failedCounter.get() + passedCounter.get())
-                + "\n   >> Passed count:" + passedCounter.get()
-                + "\n   >> Failed count:" + failedCounter.get()
-                + "\n------------------------------------");
+                "\n------------------------------------"
+                        + "\n   >> Total load test count:" + (failedCounter.get() + passedCounter.get())
+                        + "\n   >> Passed count:" + passedCounter.get()
+                        + "\n   >> Failed count:" + failedCounter.get()
+                        + "\n------------------------------------");
 
-        if(failedCounter.get() > 0){
+        if (failedCounter.get() > 0) {
+            return failed;
+        }
+
+        return passed;
+    }
+
+    public boolean processMultiLoad() {
+        executorServiceRunner.runRunnablesMulti();
+
+        LOGGER.info(
+                "\n------------------------------------"
+                        + "\n   >> Total load test count:" + (failedCounter.get() + passedCounter.get())
+                        + "\n   >> Passed count:" + passedCounter.get()
+                        + "\n   >> Failed count:" + failedCounter.get()
+                        + "\n------------------------------------");
+
+        if (failedCounter.get() > 0) {
             return failed;
         }
 
@@ -68,20 +98,4 @@ public class LoadProcessor {
         };
     }
 
-    public boolean processMultiLoad() {
-        executorServiceRunner.runRunnablesMulti();
-
-        LOGGER.info(
-                "\n------------------------------------"
-                        + "\n   >> Total load test count:" + (failedCounter.get() + passedCounter.get())
-                        + "\n   >> Passed count:" + passedCounter.get()
-                        + "\n   >> Failed count:" + failedCounter.get()
-                        + "\n------------------------------------");
-
-        if(failedCounter.get() > 0){
-            return failed;
-        }
-
-        return passed;
-    }
 }
diff --git a/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/ZeroCodeLoadRunner.java b/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/ZeroCodeLoadRunner.java
index 78be6169..7981fa98 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/ZeroCodeLoadRunner.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/runner/parallel/ZeroCodeLoadRunner.java
@@ -1,5 +1,7 @@
 package org.jsmart.zerocode.core.runner.parallel;
 
+import java.util.Arrays;
+import java.util.List;
 import org.jsmart.zerocode.core.domain.LoadWith;
 import org.jsmart.zerocode.core.domain.TestMapping;
 import org.junit.runner.Description;
@@ -10,9 +12,7 @@ import org.junit.runners.model.InitializationError;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Arrays;
-import java.util.List;
-
+import static org.jsmart.zerocode.core.utils.RunnerUtils.validateTestMethod;
 import static org.junit.runner.Description.createTestDescription;
 
 public class ZeroCodeLoadRunner extends ParentRunner<TestMapping> {
@@ -34,7 +34,7 @@ public class ZeroCodeLoadRunner extends ParentRunner<TestMapping> {
     @Override
     protected List<TestMapping> getChildren() {
         validateAnnotationPresence();
-        validateTestMethod();
+        validateTestMethod(testClass);
         return Arrays.asList(testClass.getAnnotationsByType(TestMapping.class));
     }
 
@@ -91,16 +91,4 @@ public class ZeroCodeLoadRunner extends ParentRunner<TestMapping> {
 
     }
 
-    private void validateTestMethod() {
-        String errMessage = " was invalid, please re-check and pick the correct test method to load.";
-        try {
-            TestMapping methodMapping = testClass.getAnnotation(TestMapping.class);
-            errMessage = "Mapped test method `" + methodMapping.testMethod() + "`" + errMessage;
-            methodMapping.testClass().getMethod(methodMapping.testMethod());
-        } catch (NoSuchMethodException e) {
-            LOGGER.error(errMessage);
-            throw new RuntimeException(errMessage + e);
-        }
-    }
-
 }
diff --git a/core/src/main/java/org/jsmart/zerocode/core/utils/RunnerUtils.java b/core/src/main/java/org/jsmart/zerocode/core/utils/RunnerUtils.java
index f64656dd..2c679ef9 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/utils/RunnerUtils.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/utils/RunnerUtils.java
@@ -2,6 +2,7 @@ package org.jsmart.zerocode.core.utils;
 
 import org.apache.commons.lang.StringUtils;
 import org.jsmart.zerocode.core.domain.EnvProperty;
+import org.jsmart.zerocode.core.domain.TestMapping;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -86,4 +87,15 @@ public class RunnerUtils {
         }
     }
 
+    public static void validateTestMethod(Class<?> testClass) {
+        String errMessage = " was invalid, please re-check and pick the correct test method to load.";
+        try {
+            TestMapping methodMapping = testClass.getAnnotation(TestMapping.class);
+            errMessage = "Mapped test method `" + methodMapping.testMethod() + "`" + errMessage;
+            methodMapping.testClass().getMethod(methodMapping.testMethod());
+        } catch (NoSuchMethodException e) {
+            LOGGER.error(errMessage);
+            throw new RuntimeException(errMessage + e);
+        }
+    }
 }
diff --git a/pom.xml b/pom.xml
index ae717cf3..6f2c5648 100644
--- a/pom.xml
+++ b/pom.xml
@@ -32,6 +32,7 @@
         <module>core</module>
         <module>http-testing</module>
         <module>kafka-testing</module>
+        <module>junit5-testing</module>
     </modules>
 
     <developers>
@@ -58,6 +59,9 @@
 
     <properties>
         <!-- This project properties -->
+        <junit5.version>5.4.2</junit5.version>
+        <junit.vintage.version>5.4.2</junit.vintage.version>
+        <junit-platform-runner.version>1.4.2</junit-platform-runner.version>
         <junit.version>4.12</junit.version>
         <jackson-databind.version>2.9.8</jackson-databind.version>
         <guava.version>23.0</guava.version>
@@ -79,7 +83,7 @@
         <extentreports.version>4.0.9</extentreports.version>
         <version.kafka-clients>2.1.0</version.kafka-clients>
         <version.gson>2.6.2</version.gson>
-        <!-- maven plugin, build properties  -->
+        <!-- Maven plugins, build properties  -->
         <maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
         <java-compiler-source.version>1.8</java-compiler-source.version>
         <java-compiler-target.version>1.8</java-compiler-target.version>
@@ -90,6 +94,26 @@
 
     <dependencyManagement>
         <dependencies>
+            <dependency>
+                <groupId>org.junit.jupiter</groupId>
+                <artifactId>junit-jupiter-params</artifactId>
+                <version>${junit5.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.junit.jupiter</groupId>
+                <artifactId>junit-jupiter-engine</artifactId>
+                <version>${junit5.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.junit.vintage</groupId>
+                <artifactId>junit-vintage-engine</artifactId>
+                <version>${junit.vintage.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.junit.platform</groupId>
+                <artifactId>junit-platform-runner</artifactId>
+                <version>${junit-platform-runner.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.code.gson</groupId>
                 <artifactId>gson</artifactId>


Test patch:
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/TestMapping.java b/core/src/main/java/org/jsmart/zerocode/core/domain/TestMapping.java
index c279ed7b..4aaafd18 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/TestMapping.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/TestMapping.java
@@ -1,10 +1,11 @@
 package org.jsmart.zerocode.core.domain;
 
 
-import java.lang.annotation.*;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 @Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
 @Repeatable( value = TestMappings.class )
 public @interface TestMapping {
     Class<?> testClass();
diff --git a/core/src/main/java/org/jsmart/zerocode/core/domain/TestMappings.java b/core/src/main/java/org/jsmart/zerocode/core/domain/TestMappings.java
index ee1280fe..75283f57 100644
--- a/core/src/main/java/org/jsmart/zerocode/core/domain/TestMappings.java
+++ b/core/src/main/java/org/jsmart/zerocode/core/domain/TestMappings.java
@@ -1,12 +1,9 @@
 package org.jsmart.zerocode.core.domain;
 
 
-import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 
-@Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface TestMappings {
     public TestMapping[] value() default {};
diff --git a/core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilderTest.java b/core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilderTest.java
similarity index 85%
rename from core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilderTest.java
rename to core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilderTest.java
index 1289ce08..2c4a6cf5 100644
--- a/core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeReportBuilderTest.java
+++ b/core/src/test/java/org/jsmart/zerocode/core/domain/builders/ZeroCodeExecResultIoWriteBuilderTest.java
@@ -2,7 +2,7 @@ package org.jsmart.zerocode.core.domain.builders;
 
 import org.junit.Test;
 
-public class ZeroCodeReportBuilderTest {
+public class ZeroCodeExecResultIoWriteBuilderTest {
 
     @Test
     public void testActual() throws Exception {
diff --git a/core/src/test/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportTest.java b/core/src/test/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportTest.java
index 2f8eb957..4517529c 100644
--- a/core/src/test/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportTest.java
+++ b/core/src/test/java/org/jsmart/zerocode/core/domain/reports/ZeroCodeReportTest.java
@@ -3,7 +3,7 @@ package org.jsmart.zerocode.core.domain.reports;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
-import org.jsmart.zerocode.core.domain.builders.ZeroCodeReportBuilder;
+import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultIoWriteBuilder;
 import org.jsmart.zerocode.core.domain.builders.ZeroCodeReportStepBuilder;
 import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder;
 import org.jsmart.zerocode.core.utils.SmartUtils;
@@ -32,7 +32,7 @@ public class ZeroCodeReportTest {
     @Test
     public void willSerialize_ToJson() throws Exception {
 
-        ZeroCodeReport javaBuilt = ZeroCodeReportBuilder.newInstance()
+        ZeroCodeReport javaBuilt = ZeroCodeExecResultIoWriteBuilder.newInstance()
                 .timeStamp(LocalDateTime.now())
                 .results(Arrays.asList(ZeroCodeExecResultBuilder.newInstance()
                         .scenarioName("scenario name")
diff --git a/core/src/test/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImplTest.java b/core/src/test/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImplTest.java
index 5d84b411..b05c464f 100644
--- a/core/src/test/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImplTest.java
+++ b/core/src/test/java/org/jsmart/zerocode/core/report/ZeroCodeReportGeneratorImplTest.java
@@ -1,5 +1,7 @@
 package org.jsmart.zerocode.core.report;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Rule;
@@ -17,11 +19,12 @@ public class ZeroCodeReportGeneratorImplTest {
 
     private ZeroCodeReportGeneratorImpl zeroCodeReportGenerator;
 
+    ObjectMapper mapper = new ObjectMapperProvider().get();
 
     @Before
     public void setItUp() throws Exception {
 
-        zeroCodeReportGenerator = new ZeroCodeReportGeneratorImpl();
+        zeroCodeReportGenerator = new ZeroCodeReportGeneratorImpl(mapper);
 
     }
 
diff --git a/junit5-testing/pom.xml b/junit5-testing/pom.xml
new file mode 100644
index 00000000..44d6a54a
--- /dev/null
+++ b/junit5-testing/pom.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>zerocode-tdd-parent</artifactId>
+        <groupId>org.jsmart</groupId>
+        <version>1.3.7-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.jsmart</groupId>
+    <artifactId>zerocode-tdd-jupiter</artifactId>
+
+    <packaging>jar</packaging>
+    <name>Zerocode JUnit5 Jupiter Testing</name>
+    <description>Zerocode tests with JUnit5 Jupiter Engine</description>
+
+    <properties>
+        <java.version>1.8</java.version>
+        <micro-simulator.version>1.1.8</micro-simulator.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <artifactId>zerocode-tdd</artifactId>
+            <groupId>org.jsmart</groupId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.vintage</groupId>
+            <artifactId>junit-vintage-engine</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-runner</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M3</version>
+                <configuration>
+                    <!--<junitPlatformArtifactName>com.github.junit-team.junit5:junit-platform-engine</junitPlatformArtifactName>-->
+                    <!--<properties>-->
+                    <!--<configurationParameters>-->
+                    <!--junit.jupiter.execution.parallel.enabled=true-->
+                    <!--junit.jupiter.execution.parallel.config.strategy=fixed-->
+                    <!--junit.jupiter.execution.parallel.config.fixed.parallelism=2-->
+                    <!--</configurationParameters>-->
+                    <!--</properties>-->
+                    <includes>
+                        <include>org.jsmart.zerocode.jupiter.extension.JupiterZeroCodeParallelTest</include>
+                        <include>org.jsmart.zerocode.tests.loadjupiter.JUnit5LoadTest</include>
+                    </includes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtension.java b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtension.java
new file mode 100644
index 00000000..79a94eb9
--- /dev/null
+++ b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtension.java
@@ -0,0 +1,107 @@
+package org.jsmart.zerocode.jupiter.extension;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import org.apiguardian.api.API;
+import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
+import org.jsmart.zerocode.core.domain.LoadWith;
+import org.jsmart.zerocode.core.domain.TestMapping;
+import org.jsmart.zerocode.core.report.ZeroCodeReportGenerator;
+import org.jsmart.zerocode.core.report.ZeroCodeReportGeneratorImpl;
+import org.jsmart.zerocode.jupiter.load.JupiterLoadProcessor;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.lang.String.format;
+import static org.apiguardian.api.API.Status.EXPERIMENTAL;
+import static org.junit.jupiter.api.Assertions.fail;
+
+/**
+ * This JUnit5 extension helps to generate load declaratively for performance testing. We can
+ * simply cherry-pick existing/new JUnit5 tests and run them in parallel as configured by the
+ * load-properties.
+ * <p>
+ * This class implements BeforeEachCallback(not BeforeAllCallback), because the load generation
+ * can be done for each test method. This way we don't need to create multiple load generation
+ * classes and add them into a Test-Suite runner. Instead, just create multiple test-methods with
+ * annotating with @Test(from Jupiter package) and @TestMappings(...).
+ * <p>
+ * Visit the Wiki page and HelloWorld repo on this for precise examples.
+ */
+@API(status = EXPERIMENTAL)
+public class ParallelLoadExtension implements BeforeEachCallback {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ParallelLoadExtension.class);
+    private final ObjectMapper mapper = new ObjectMapperProvider().get();
+    private final ZeroCodeReportGenerator reportGenerator = new ZeroCodeReportGeneratorImpl(mapper);
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception {
+        Method testMethod = extensionContext.getRequiredTestMethod();
+        Class<?> testClass = extensionContext.getRequiredTestClass();
+        String loadPropertiesFile = validateAndGetLoadPropertiesFile(testClass, testMethod);
+        JupiterLoadProcessor loadProcessor = new JupiterLoadProcessor(loadPropertiesFile);
+
+        //-------------------------------------------
+        //       On/Off Extent-Report switch
+        //-------------------------------------------
+        // Load the key 'chart.dashboard.generation'
+        // from 'loadPropertiesFile'
+        //-------------------------------------------
+        boolean chartAndDashBoardGenerationEnabled = false;
+
+
+        TestMapping[] testMappingArray = testMethod.getAnnotationsByType(TestMapping.class);
+
+        Arrays.stream(testMappingArray).forEach(thisMapping -> {
+            loadProcessor.addJupiterTest(thisMapping.testClass(), thisMapping.testMethod());
+        });
+
+        boolean hasFailed = loadProcessor.processMultiLoad();
+
+        reportGenerator.generateCsvReport();
+        if (chartAndDashBoardGenerationEnabled) {
+            reportGenerator.generateExtentReport();
+        }
+
+        if (hasFailed) {
+            failTest(testMethod, testClass);
+        } else {
+            LOGGER.info("\nAll Passed \uD83D\uDC3C. \nSee the granular 'csv report' for individual test statistics.");
+        }
+
+    }
+
+    private void failTest(Method testMethod, Class<?> testClass) {
+        String failureMessage = testClass.getName() + " with load/stress test(s): " + testMethod + " have Failed";
+        LOGGER.error("\n" + failureMessage + ". \n\uD83D\uDC47" +
+                "\na) See the 'target/' for granular 'csv report' for pass/fail/response-delay statistics.\uD83D\uDE0E" +
+                "\n-Also- " +
+                "\nb) See the 'target/logs' for individual failures by their correlation-ID.\n\n");
+        String testDescription = testClass + "#" + testMethod;
+
+        fail(testDescription, new RuntimeException(failureMessage));
+    }
+
+    protected String validateAndGetLoadPropertiesFile(Class<?> testClass, Method method) {
+        LoadWith loadClassWith = testClass.getAnnotation(LoadWith.class);
+        LoadWith loadMethodWith = method.getAnnotation(LoadWith.class);
+
+        if (loadClassWith != null) {
+            return loadClassWith.value();
+        }
+
+        if (loadMethodWith != null) {
+            return loadMethodWith.value();
+        }
+
+        throw new RuntimeException(
+                format("\n<< Ah! Missing the the @LoadWith(...) on this Class '%s' or Method '%s' >> ",
+                        testClass.getName(), method.getName())
+        );
+
+    }
+
+}
diff --git a/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/listener/ZeroCodeTestReportJupiterListener.java b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/listener/ZeroCodeTestReportJupiterListener.java
new file mode 100644
index 00000000..f65db4e6
--- /dev/null
+++ b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/listener/ZeroCodeTestReportJupiterListener.java
@@ -0,0 +1,101 @@
+package org.jsmart.zerocode.jupiter.listener;
+
+import java.time.LocalDateTime;
+import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder;
+import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultIoWriteBuilder;
+import org.jsmart.zerocode.core.logbuilder.LogCorrelationshipPrinter;
+import org.junit.platform.engine.TestExecutionResult;
+import org.junit.platform.launcher.TestExecutionListener;
+import org.junit.platform.launcher.TestIdentifier;
+import org.junit.platform.launcher.TestPlan;
+import org.slf4j.Logger;
+
+import static java.time.LocalDateTime.now;
+import static org.jsmart.zerocode.core.domain.builders.ZeroCodeExecResultBuilder.newInstance;
+import static org.junit.platform.engine.TestExecutionResult.Status.FAILED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * This class correlates between request and response of a test and creates easily traceable logs.
+ * Here, for each JUnit5 parallel tests this can be interpreted the following way-
+ * - a) Request timestamp - When the test started execution
+ * - b) Response timestamp - When the test finished execution
+ * - c) Response Delay(milli second) - (b-a) milli seconds
+ * - d) Scenario: Fully qualified name of the Test-Class
+ * - e) Step: Name of the Test-Method in the above Test-Class with @Test(jupiter package)
+ *
+ * Later the logs are written to the target folder as raw JSON files ready for rendering
+ * CSV-reports and Html-Chart/Dashboards
+ *
+ * @author Nirmal Chandra on 25-apr-2019
+ */
+public class ZeroCodeTestReportJupiterListener implements TestExecutionListener {
+    private static final Logger LOGGER = getLogger(ZeroCodeTestReportJupiterListener.class);
+
+    private final Class<?> testClass;
+    private final String testMethod;
+    private String testDescription;
+
+    private LogCorrelationshipPrinter correlationshipPrettyLogger;
+    private String logPrefixRelationshipId;
+    private boolean passed=true;
+
+    public ZeroCodeTestReportJupiterListener(Class<?> testClass, String testMethod) {
+        this.testClass = testClass;
+        this.testMethod = testMethod;
+        this.testDescription = testClass + "#" + testMethod;
+    }
+
+    @Override
+    public void testPlanExecutionStarted(TestPlan testPlan) {
+        logPrefixRelationshipId = prepareRequestReport(testDescription);
+    }
+
+    @Override
+    public void testPlanExecutionFinished(TestPlan testPlan) {
+        prepareResponseReport(logPrefixRelationshipId);
+        buildReportAndPrintToFile(testDescription);
+    }
+
+    @Override
+    public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) {
+        if(testExecutionResult.getStatus().equals(FAILED)){
+            passed = false;
+        }
+    }
+
+    private String prepareRequestReport(String description) {
+        correlationshipPrettyLogger = LogCorrelationshipPrinter.newInstance(LOGGER);
+        correlationshipPrettyLogger.stepLoop(0);
+        final String logPrefixRelationshipId = correlationshipPrettyLogger.createRelationshipId();
+        LocalDateTime timeNow = now();
+        correlationshipPrettyLogger.aRequestBuilder()
+                .stepLoop(0)
+                .relationshipId(logPrefixRelationshipId)
+                .requestTimeStamp(timeNow)
+                .step(testMethod);
+        LOGGER.info("JUnit5 *requestTimeStamp:{}, \nJUnit Request:{}", timeNow, logPrefixRelationshipId);
+        return logPrefixRelationshipId;
+    }
+
+    private void prepareResponseReport(String logPrefixRelationshipId) {
+        LocalDateTime timeNow = now();
+        LOGGER.info("JUnit5 *responseTimeStamp:{}, \nJUnit Response:{}", timeNow, logPrefixRelationshipId);
+        correlationshipPrettyLogger.aResponseBuilder()
+                .relationshipId(logPrefixRelationshipId)
+                .responseTimeStamp(timeNow);
+        correlationshipPrettyLogger.result(passed);
+        correlationshipPrettyLogger.buildResponseDelay();
+    }
+
+    private void buildReportAndPrintToFile(String description) {
+        ZeroCodeExecResultBuilder reportResultBuilder = newInstance().loop(0).scenarioName(testClass.getName());
+        reportResultBuilder.step(correlationshipPrettyLogger.buildReportSingleStep());
+
+        ZeroCodeExecResultIoWriteBuilder reportBuilder = ZeroCodeExecResultIoWriteBuilder.newInstance().timeStamp(now());
+        reportBuilder.result(reportResultBuilder.build());
+
+        reportBuilder.printToFile(description + correlationshipPrettyLogger.getCorrelationId() + ".json");
+    }
+
+}
\ No newline at end of file
diff --git a/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessor.java b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessor.java
new file mode 100644
index 00000000..49094c06
--- /dev/null
+++ b/junit5-testing/src/main/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessor.java
@@ -0,0 +1,84 @@
+package org.jsmart.zerocode.jupiter.load;
+
+import org.jsmart.zerocode.core.runner.parallel.LoadProcessor;
+import org.jsmart.zerocode.jupiter.listener.ZeroCodeTestReportJupiterListener;
+import org.junit.platform.launcher.Launcher;
+import org.junit.platform.launcher.LauncherDiscoveryRequest;
+import org.junit.platform.launcher.TestIdentifier;
+import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
+import org.junit.platform.launcher.core.LauncherFactory;
+import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
+import org.junit.platform.launcher.listeners.TestExecutionSummary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.time.LocalDateTime.now;
+import static org.junit.platform.engine.discovery.DiscoverySelectors.selectMethod;
+
+public class JupiterLoadProcessor extends LoadProcessor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(JupiterLoadProcessor.class);
+
+    public JupiterLoadProcessor(String loadPropertiesFile) {
+        super(loadPropertiesFile);
+    }
+
+    public LoadProcessor addJupiterTest(Class<?> testClass, String testMethod) {
+
+        Runnable zeroCodeJunitTest = createJupiterRunnable(testClass, testMethod);
+
+        getExecutorServiceRunner().addRunnable(zeroCodeJunitTest);
+
+        return this;
+    }
+
+    public void updatePassFailCount(SummaryGeneratingListener summaryListener) {
+        TestExecutionSummary summary = summaryListener.getSummary();
+        if (summary.getTotalFailureCount() > 0) {
+            getFailedCounter().incrementAndGet();
+            summary.getFailures().forEach(thisFailure -> {
+                TestIdentifier testIdentifier = thisFailure.getTestIdentifier();
+                String exceptionMessage = thisFailure.getException().getMessage();
+                LOGGER.info("\n----------------------------------------------------------------------\n");
+                LOGGER.info("\n###JUnit5: Test Failed Due To --> {}, \ntestIdentifier={}", exceptionMessage, testIdentifier);
+                LOGGER.info("\n----------------------------------------------------------------------\n");
+            });
+        } else {
+            getPassedCounter().incrementAndGet();
+        }
+    }
+
+    private void registerReportListener(Class<?> testClass, String testMethod, Launcher launcher) {
+        ZeroCodeTestReportJupiterListener reportListener =
+                new ZeroCodeTestReportJupiterListener(testClass, testMethod );
+        launcher.registerTestExecutionListeners(reportListener);
+    }
+
+    private Runnable createJupiterRunnable(Class<?> testClass, String testMethod) {
+        return () -> {
+
+            LOGGER.info(Thread.currentThread().getName() + "\n - Parallel Junit5 test- *Start-Time = " + now());
+
+            final LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
+                    .selectors(selectMethod(testClass, testMethod))
+                    .build();
+            final Launcher launcher = LauncherFactory.create();
+
+            // -------------------------
+            // Register Report listener
+            // -------------------------
+            registerReportListener(testClass, testMethod, launcher);
+
+            // ------------------------------
+            // Register Test-Summary listener
+            // ------------------------------
+            final SummaryGeneratingListener summaryListener = new SummaryGeneratingListener();
+            launcher.registerTestExecutionListeners(summaryListener);
+
+            launcher.execute(request);
+            LOGGER.info(Thread.currentThread().getName() + "\n   - Parallel Junit5 test- *End-Time = " + now());
+
+            updatePassFailCount(summaryListener);
+
+        };
+    }
+}
diff --git a/junit5-testing/src/main/resources/logback.xml b/junit5-testing/src/main/resources/logback.xml
new file mode 100644
index 00000000..f5bc0aef
--- /dev/null
+++ b/junit5-testing/src/main/resources/logback.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
+        <file>target/logs/your_app_tests_logs.log</file>
+        <append>true</append>
+        <encoder>
+            <pattern>%d [%thread] %-5level %logger{100} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
+        <!--<encoder>
+            <pattern>%d [%thread] %-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
+        </encoder>-->
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <!--<pattern>%d %green([%thread]) %highlight(%level) %logger{100} - %blue(%msg%n)</pattern>-->
+            <pattern>%d [%thread] %-5level %logger{100} - %msg%n</pattern>
+        </layout>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="fileAppender" />
+        <appender-ref ref="consoleAppender" />
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtensionTest.java b/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtensionTest.java
new file mode 100644
index 00000000..9cad982d
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/extension/ParallelLoadExtensionTest.java
@@ -0,0 +1,71 @@
+package org.jsmart.zerocode.jupiter.extension;
+
+import java.lang.reflect.Method;
+import org.jsmart.zerocode.core.domain.LoadWith;
+import org.jsmart.zerocode.core.domain.TestMapping;
+import org.jsmart.zerocode.core.domain.TestMappings;
+import org.jsmart.zerocode.tests.jupiter.JUnit5Test;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class ParallelLoadExtensionTest {
+
+    @ExtendWith({ParallelLoadExtension.class})
+    public class JUnit5ExampleLoad {
+
+        @Test
+        //@LoadWith("load_generation.properties") //missing case
+        @TestMappings({
+                @TestMapping(testClass = JUnit5Test.class, testMethod = "testX"),
+                @TestMapping(testClass = JUnit5Test.class, testMethod = "testY")
+        })
+        public void testLoad() {
+            /* No code needed here */
+        }
+    }
+
+    @Test
+    void testValidation_exception() {
+        Class<JUnit5ExampleLoad> clazz = JUnit5ExampleLoad.class;
+        Method[] declaredMethods = clazz.getDeclaredMethods();
+        Method testMethod = declaredMethods[0]; // this is 'testLoad()'
+
+        ParallelLoadExtension parallelLoadExtension = new ParallelLoadExtension();
+        RuntimeException thrown =
+                assertThrows(RuntimeException.class,
+                        () -> parallelLoadExtension.validateAndGetLoadPropertiesFile(clazz, testMethod),
+                        "Expected to throw RuntimeException, but it didn't throw.");
+
+        assertTrue(thrown.getMessage().contains("Missing the the @LoadWith(...)"));
+    }
+
+    @ExtendWith({ParallelLoadExtension.class})
+    public class JUnit5ExampleLoad2 {
+
+        @Test
+        @LoadWith("load_generation.properties")
+        @TestMappings({
+                @TestMapping(testClass = JUnit5Test.class, testMethod = "testX"),
+                @TestMapping(testClass = JUnit5Test.class, testMethod = "testY")
+        })
+        public void testLoad() {
+            /* No code needed here */
+        }
+    }
+
+    @Test
+    void testLoadAnnotation_success() {
+        Class<JUnit5ExampleLoad2> clazz = JUnit5ExampleLoad2.class;
+        Method[] declaredMethods = clazz.getDeclaredMethods();
+        Method testMethod = declaredMethods[0]; // this is 'testLoad()'
+
+        ParallelLoadExtension parallelLoadExtension = new ParallelLoadExtension();
+        String loadPropertiesFile = parallelLoadExtension.validateAndGetLoadPropertiesFile(clazz, testMethod);
+
+        assertEquals("load_generation.properties", loadPropertiesFile);
+    }
+}
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessorTest.java b/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessorTest.java
new file mode 100644
index 00000000..f6edaf86
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/jupiter/load/JupiterLoadProcessorTest.java
@@ -0,0 +1,5 @@
+package org.jsmart.zerocode.jupiter.load;
+
+class JupiterLoadProcessorTest {
+
+}
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/GitHubHelloWorldTest.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/GitHubHelloWorldTest.java
new file mode 100644
index 00000000..fa02f967
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/GitHubHelloWorldTest.java
@@ -0,0 +1,18 @@
+package org.jsmart.zerocode.tests.junit4;
+
+import org.jsmart.zerocode.core.domain.JsonTestCase;
+import org.jsmart.zerocode.core.domain.TargetEnv;
+import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@TargetEnv("github_host.properties")
+@RunWith(ZeroCodeUnitRunner.class)
+public class GitHubHelloWorldTest {
+
+    @Test
+    @JsonTestCase("helloworld_github_REST_api/GitHub_REST_api_sample_assertions.json")
+    public void testGitGubSample_RESTApi() throws Exception {
+    }
+
+}
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/JUnit4Test.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/JUnit4Test.java
new file mode 100644
index 00000000..43fc6949
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/junit4/JUnit4Test.java
@@ -0,0 +1,17 @@
+package org.jsmart.zerocode.tests.junit4;
+
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+
+public class JUnit4Test {
+
+    @Test
+    public void testJunit4_passed() {
+        String msg = "junit4 works as usual";
+        assertTrue("junit4 works as usual".equals(msg));
+    }
+
+}
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/jupiter/JUnit5Test.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/jupiter/JUnit5Test.java
new file mode 100644
index 00000000..ffeeef6e
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/jupiter/JUnit5Test.java
@@ -0,0 +1,26 @@
+package org.jsmart.zerocode.tests.jupiter;
+
+import org.jsmart.zerocode.tests.postgres.ExtensionA;
+import org.jsmart.zerocode.tests.postgres.ExtensionB;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import static java.lang.System.out;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@ExtendWith({ExtensionA.class, ExtensionB.class})
+public class JUnit5Test {
+
+    @Test
+    public void testX() {
+        out.println("*JUnit5 ---> testX()");
+        assertTrue(2 == 2); //jupiter assert
+    }
+
+    @Test
+    public void testY() {
+        out.println("*JUnit5 ---> testY()");
+        assertTrue(2 == 2); //jupiter assert
+    }
+
+}
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/loadjupiter/JUnit5LoadTest.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/loadjupiter/JUnit5LoadTest.java
new file mode 100644
index 00000000..5b612e8b
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/loadjupiter/JUnit5LoadTest.java
@@ -0,0 +1,24 @@
+package org.jsmart.zerocode.tests.loadjupiter;
+
+import org.jsmart.zerocode.core.domain.LoadWith;
+import org.jsmart.zerocode.core.domain.TestMapping;
+import org.jsmart.zerocode.core.domain.TestMappings;
+import org.jsmart.zerocode.jupiter.extension.ParallelLoadExtension;
+import org.jsmart.zerocode.tests.jupiter.JUnit5Test;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith({ParallelLoadExtension.class})
+public class JUnit5LoadTest {
+
+    @Test
+    @LoadWith("load_generation.properties")
+    @TestMappings({
+            @TestMapping(testClass = JUnit5Test.class, testMethod = "testX"),
+            @TestMapping(testClass = JUnit5Test.class, testMethod = "testY")
+    })
+    public void testLoad() {
+        /* No code needed here */
+    }
+
+}
\ No newline at end of file
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionA.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionA.java
new file mode 100644
index 00000000..f30f58bb
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionA.java
@@ -0,0 +1,35 @@
+package org.jsmart.zerocode.tests.postgres;
+
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+import static java.lang.System.out;
+
+public class ExtensionA implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) throws Exception {
+        out.println("ExtentionA - afterEach");
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception {
+        out.println("ExtentionA - beforeEach");
+
+    }
+
+    @Override
+    public void afterAll(ExtensionContext extensionContext) throws Exception {
+        out.println("ExtentionA - afterAll");
+
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext extensionContext) throws Exception {
+        out.println("ExtentionA - beforeAll");
+
+    }
+}
diff --git a/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionB.java b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionB.java
new file mode 100644
index 00000000..3f7f4cb5
--- /dev/null
+++ b/junit5-testing/src/test/java/org/jsmart/zerocode/tests/postgres/ExtensionB.java
@@ -0,0 +1,34 @@
+package org.jsmart.zerocode.tests.postgres;
+
+
+import org.junit.jupiter.api.extension.AfterAllCallback;
+import org.junit.jupiter.api.extension.AfterEachCallback;
+import org.junit.jupiter.api.extension.BeforeAllCallback;
+import org.junit.jupiter.api.extension.BeforeEachCallback;
+import org.junit.jupiter.api.extension.ExtensionContext;
+
+public class ExtensionB implements BeforeAllCallback, AfterAllCallback, BeforeEachCallback, AfterEachCallback {
+
+    @Override
+    public void afterEach(ExtensionContext extensionContext) throws Exception {
+        System.out.println("ExtentionB - afterEach");
+    }
+
+    @Override
+    public void beforeEach(ExtensionContext extensionContext) throws Exception {
+        System.out.println("ExtentionB - beforeEach");
+
+    }
+
+    @Override
+    public void afterAll(ExtensionContext extensionContext) throws Exception {
+        System.out.println("ExtentionB - afterAll");
+
+    }
+
+    @Override
+    public void beforeAll(ExtensionContext extensionContext) throws Exception {
+        System.out.println("ExtentionB - beforeAll");
+
+    }
+}
diff --git a/junit5-testing/src/test/resources/github_host.properties b/junit5-testing/src/test/resources/github_host.properties
new file mode 100644
index 00000000..1fe6afa8
--- /dev/null
+++ b/junit5-testing/src/test/resources/github_host.properties
@@ -0,0 +1,6 @@
+# Web Server host and port
+web.application.endpoint.host=https://api.github.com
+# Web Service Port; Leave it blank in case it is default port i.e. 80 or 443 etc
+web.application.endpoint.port=
+# Web Service context; Leave it blank in case you do not have a common context
+web.application.endpoint.context=
diff --git a/junit5-testing/src/test/resources/helloworld_github_REST_api/GitHub_REST_api_sample_assertions.json b/junit5-testing/src/test/resources/helloworld_github_REST_api/GitHub_REST_api_sample_assertions.json
new file mode 100644
index 00000000..b9a785c6
--- /dev/null
+++ b/junit5-testing/src/test/resources/helloworld_github_REST_api/GitHub_REST_api_sample_assertions.json
@@ -0,0 +1,18 @@
+{
+    "scenarioName": "GitHub Version-Details REST API will GET, version and server details @@Emma",
+    "steps": [
+        {
+            "name": "get_github_server_details",
+            "url": "/users/octocat/orgs",
+            "operation": "GET",
+            "request": {
+                "headers":{
+                    "api_key": "efg-135-xyz-9393"
+                }
+            },
+            "assertions": {
+                "status": 200
+            }
+        }
+    ]
+}
diff --git a/junit5-testing/src/test/resources/load_generation.properties b/junit5-testing/src/test/resources/load_generation.properties
new file mode 100755
index 00000000..43a2edf4
--- /dev/null
+++ b/junit5-testing/src/test/resources/load_generation.properties
@@ -0,0 +1,22 @@
+# You can enter as many threads to stimulate a load test. A single user is represented by each Thread. So if you wish
+# to simulate a load test with 5 concurrent users then you need to enter 5 as the value for this property. A high end
+# machine will be able to spawn more number of threads. To keep the consistent(or nearly consistent) gap between the
+# threads, adjust this number with 'ramp.up.period.in.seconds' and the actual response time of the API end point.
+# For "@RunWith(ZeroCodeMultiLoadRunner.class)", set this to at least equal to number of "@TestMapping" or more,
+# otherwise there wont be enough threads to run each test.
+number.of.threads=2
+
+# It indicates the time taken to create all of the threads needed to fork the requests. If you set 10 seconds as the
+# ramp-up period for 5 threads then the framework will take  10 seconds to create those 5 threads, i.e. each thread
+# will be at work appx 2 secs gap between the requests. Also by setting its value to 0 all the threads can be created
+# at once at the same time. Note- If you want to fire more threads/user-requests in less ramp up time e.g. 5 threads
+# in 2secs(or 5 threads in 1 sec), then, use '@UseHttpClient(SslTrustHttpClient.class)' as this 'client' closes the
+# connection before making the next connection.
+ramp.up.period.in.seconds=4
+
+# By specifying its value framework gets to know that how many times the test(s), i.e. the number of requests will be
+# repeated per every 'ramp.up.period.in.seconds'.
+# Supposing number.of.threads = x, ramp.up.period.in.seconds = y, loop.count = i
+# then (x * i) = number of requests will be fired over (y * i) seconds. If x=5, i=3, y=20, then 15 requests will be
+# fired in 60 seconds which means- every request in 4 seconds gap. 60/15 or 20/5 = 4seconds.
+loop.count=1
diff --git a/junit5-testing/src/test/resources/loadtesting/github_get_api_test_case.json b/junit5-testing/src/test/resources/loadtesting/github_get_api_test_case.json
new file mode 100644
index 00000000..b10f695c
--- /dev/null
+++ b/junit5-testing/src/test/resources/loadtesting/github_get_api_test_case.json
@@ -0,0 +1,23 @@
+{
+    "scenarioName": "Load testing- Git Hub GET API",
+    "steps": [
+        {
+            "name": "get_user_details",
+            "url": "/users/octocat",
+            "operation": "GET",
+            "request": {
+            },
+            "assertions": {
+                "status": 200,
+                "body": {
+                    "login" : "octocat",
+                    "id" : 583231,
+                    "avatar_url" : "https://avatars3.githubusercontent.com/u/583231?v=4",
+                    "type" : "User",
+                    "name" : "The Octocat",
+                    "company" : "GitHub"
+                }
+            }
+        }
+    ]
+}
diff --git a/junit5-testing/src/test/resources/localhost_stubs/localhost_REST_fake_end_points_stubs.json b/junit5-testing/src/test/resources/localhost_stubs/localhost_REST_fake_end_points_stubs.json
new file mode 100644
index 00000000..6113f540
--- /dev/null
+++ b/junit5-testing/src/test/resources/localhost_stubs/localhost_REST_fake_end_points_stubs.json
@@ -0,0 +1,226 @@
+{
+    "name": "Localhost mocked aka stubbed aka fake REST Endpoints - GET POST PUT apis",
+    "apis": [
+        {
+            "name": "Sample_POST_Employee_Create",
+            "operation": "POST",
+            "url": "/api/v1/google-uk/employees",
+            "ignoreBody": true,
+            "response": {
+                "status": 201,
+                "body": {
+                    "id": 1000,
+                    "name": "Larry Pg",
+                    "addresses": [
+                        {
+                            "gpsLocation": "x9000-y9000z-9000-home"
+                        },
+                        {
+                            "gpsLocation": "x9000-y9000z-9000-home-off"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "sample POST with matching body",
+            "operation": "POST",
+            "url": "/api/v1/employees",
+            "ignoreBody": false,
+            "body": {
+                "name": "Emma",
+                "surName": "Norton"
+            },
+            "response": {
+                "status": 201,
+                "body": {
+                    "id": 39001,
+                    "ldapId": "emmanorton"
+                }
+            }
+        },
+        {
+            "name": "sample GET for Emma Norton",
+            "operation": "GET",
+            "url": "/api/v1/employees/39001",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": 39001,
+                    "ldapId": "emmanorton",
+                    "name": "Emma",
+                    "surName": "Norton"
+                }
+            }
+        },
+        {
+            "name": "Sample_Get_Employee_by_Id",
+            "operation": "GET",
+            "url": "/api/v1/google-uk/employees/999",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": 999,
+                    "name": "Larry P",
+                    "addresses": [
+                        {
+                            "gpsLocation": "x1000-25000-z30000"
+                        },
+                        {
+                            "gpsLocation": "x3000-y5000-z70000"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "Screening - sample POST with matching body",
+            "operation": "POST",
+            "url": "/api/v1/employees/screening",
+            "ignoreBody": false,
+            "body": {
+                "empId": "EMP39001",
+                "originAddress": {
+                    "addressId":"lon-hsbc-5432",
+                    "countryOfOrigin":"UK"
+                }
+            },
+            "response": {
+                "status": 201,
+                "body": {
+                    "id": "SCRUNIQUEID5003"
+                }
+            }
+        },
+        {
+            "name": "Screening - sample GET",
+            "operation": "GET",
+            "url": "/api/v1/employees/screening/SCRUNIQUEID5003",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": "SCRUNIQUEID5003",
+                    "empId": "EMP39001",
+                    "originAddress": {
+                        "addressId":"lon-hsbc-5432",
+                        "countryOfOrigin":"UK"
+                    }
+                }
+            }
+        },
+        {
+            "name": "Sample_Get_Created_Employee_by_Id",
+            "operation": "GET",
+            "url": "/api/v1/google-uk/employees/1000",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": 1000,
+                    "name": "Larry Pg",
+                    "addresses": [
+                        {
+                            "gpsLocation": "x9000-y9000z-9000-home"
+                        },
+                        {
+                            "gpsLocation": "x9000-y9000z-9000-home-off"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "sample_get_api",
+            "operation": "GET",
+            "url": "/api/v1/google-uk/employees/UK1001",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": "UK1001",
+                    "name": "Bobby Lion",
+                    "addresses": [
+                        {
+                            "line1": "HOME, London, PostCode - IG1 5TX"
+                        },
+                        {
+                            "line1": "OFFICE, Newark, ZIP-730290"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "bare_string_get",
+            "operation": "GET",
+            "url": "/api/v1/google-uk/employees/101",
+            "response": {
+                "status": 200,
+                "body": "I am emp No 101. Nothing more than this I can respond"
+            }
+        },
+        {
+            "name": "Sample_Get_Full_Employee_by_Id",
+            "operation": "GET",
+            "url": "/api/v1/employees/emp1001",
+            "response": {
+                "status": 200,
+                "body": {
+                    "id": "emp1001",
+                    "name": "Jeff Bezos",
+                    "achievements": "Amazon",
+                    "empType": "Self Employed",
+                    "addresses": [
+                        {
+                            "type": "Office",
+                            "line1": "39 NewYork Street",
+                            "zip": "560 390"
+                        },
+                        {
+                            "type": "Home",
+                            "line1": "99 Piscataway",
+                            "zip": "560 001"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "Sample_Get_Address_by_emp_id",
+            "operation": "GET",
+            "url": "/api/v1/addresses/empoyee/emp1001",
+            "response": {
+                "status": 200,
+                "body": {
+                    "empId": "emp1001",
+                    "addresses": [
+                        {
+                            "addressId": "addr-001",
+                            "type": "Office",
+                            "line1": "39 NewYork Street",
+                            "zip": "560 390"
+                        },
+                        {
+                            "addressId": "addr-002",
+                            "type": "Home",
+                            "line1": "99 Piscataway",
+                            "zip": "560 001"
+                        }
+                    ]
+                }
+            }
+        },
+        {
+            "name": "Mock GET employee details including DOB",
+            "operation": "GET",
+            "url": "/api/v1/google-uk/employees/UK-LON-1002",
+            "response": {
+                "status": 200,
+                "body": {
+                    "empId": "UK-LON-1002",
+                    "city": "UK-London",
+                    "dob": "1989-07-09"
+                }
+            }
+        }
+
+    ]
+}
\ No newline at end of file
diff --git a/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/ExampleUtils.java b/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/ExampleUtils.java
new file mode 100644
index 00000000..86064618
--- /dev/null
+++ b/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/ExampleUtils.java
@@ -0,0 +1,5 @@
+package org.jsmart.zerocode.zerocodejavaexec.utils;
+
+public class ExampleUtils {
+
+}
diff --git a/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/TokenGenerator.java b/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/TokenGenerator.java
deleted file mode 100644
index dd693df1..00000000
--- a/kafka-testing/src/main/java/org/jsmart/zerocode/zerocodejavaexec/utils/TokenGenerator.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.jsmart.zerocode.zerocodejavaexec.utils;
-
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-public class TokenGenerator {
-
-    public Map<String, String> generateNew(String anyParam){
-        Map<String, String> tokenMap = new HashMap<>();
-
-        // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-        //          Your token generation logic goes here.
-        // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-        // You need to put a valid implementation for this token.
-        // For time being it's unique here as current time-stamp.
-        // The key "token" here is just for demo purpose.
-        // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-        String uniqueToken = tokenFromCurrentTimeStamp();
-
-        // ------------------------------------
-        // Now put this token into a map key
-        //  - Choose any key name e.g. newToken
-        // ------------------------------------
-        tokenMap.put("newToken", uniqueToken);
-
-        return tokenMap;
-    }
-
-    private String tokenFromCurrentTimeStamp() {
-        return LocalDateTime.now().toString()
-                    .replace(":", "-")
-                    .replace(".", "-");
-    }
-}