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 abc3e3e92..7000f32ef 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 @@ -3,33 +3,24 @@ import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.util.Modules; -import java.lang.annotation.Annotation; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; import org.jsmart.zerocode.core.di.main.ApplicationMainModule; import org.jsmart.zerocode.core.di.module.RuntimeHttpClientModule; import org.jsmart.zerocode.core.di.module.RuntimeKafkaClientModule; -import org.jsmart.zerocode.core.domain.HostProperties; -import org.jsmart.zerocode.core.domain.JsonTestCase; -import org.jsmart.zerocode.core.domain.Scenario; -import org.jsmart.zerocode.core.domain.ScenarioSpec; -import org.jsmart.zerocode.core.domain.TargetEnv; -import org.jsmart.zerocode.core.domain.UseHttpClient; -import org.jsmart.zerocode.core.domain.UseKafkaClient; +import org.jsmart.zerocode.core.domain.*; import org.jsmart.zerocode.core.domain.builders.ZeroCodeExecReportBuilder; import org.jsmart.zerocode.core.domain.builders.ZeroCodeIoWriteBuilder; import org.jsmart.zerocode.core.engine.listener.ZeroCodeTestReportListener; import org.jsmart.zerocode.core.httpclient.BasicHttpClient; -import org.jsmart.zerocode.core.httpclient.ssl.SslTrustHttpClient; import org.jsmart.zerocode.core.kafka.client.BasicKafkaClient; -import org.jsmart.zerocode.core.kafka.client.ZerocodeCustomKafkaClient; import org.jsmart.zerocode.core.logbuilder.ZerocodeCorrelationshipLogger; import org.jsmart.zerocode.core.report.ZeroCodeReportGenerator; import org.jsmart.zerocode.core.utils.SmartUtils; import org.junit.internal.AssumptionViolatedException; import org.junit.internal.runners.model.EachTestNotifier; +import org.junit.internal.runners.model.ReflectiveCallable; +import org.junit.internal.runners.statements.Fail; +import org.junit.rules.RunRules; +import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runner.Result; import org.junit.runner.notification.Failure; @@ -41,13 +32,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.annotation.Annotation; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + import static java.lang.System.getProperty; -import static org.jsmart.zerocode.core.domain.builders.ZeroCodeExecReportBuilder.newInstance; import static org.jsmart.zerocode.core.constants.ZeroCodeReportConstants.CHARTS_AND_CSV; import static org.jsmart.zerocode.core.constants.ZeroCodeReportConstants.ZEROCODE_JUNIT; -import static org.jsmart.zerocode.core.utils.RunnerUtils.getCustomHttpClientOrDefault; -import static org.jsmart.zerocode.core.utils.RunnerUtils.getCustomKafkaClientOrDefault; -import static org.jsmart.zerocode.core.utils.RunnerUtils.getEnvSpecificConfigFile; +import static org.jsmart.zerocode.core.domain.builders.ZeroCodeExecReportBuilder.newInstance; +import static org.jsmart.zerocode.core.utils.RunnerUtils.*; public class ZeroCodeUnitRunner extends BlockJUnit4ClassRunner { private static final Logger LOGGER = LoggerFactory.getLogger(ZeroCodeUnitRunner.class); @@ -115,7 +110,7 @@ protected void runChild(FrameworkMethod method, RunNotifier notifier) { final Description description = describeChild(method); JsonTestCase jsonTestCaseAnno = method.getMethod().getAnnotation(JsonTestCase.class); - if(jsonTestCaseAnno == null){ + if (jsonTestCaseAnno == null) { jsonTestCaseAnno = evalScenarioToJsonTestCase(method.getMethod().getAnnotation(Scenario.class)); } @@ -124,8 +119,7 @@ protected void runChild(FrameworkMethod method, RunNotifier notifier) { notifier.fireTestIgnored(description); } else if (jsonTestCaseAnno != null) { - - runLeafJsonTest(notifier, description, jsonTestCaseAnno); + runLeafJsonTest(method, notifier, description, jsonTestCaseAnno); } else { // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -136,6 +130,36 @@ protected void runChild(FrameworkMethod method, RunNotifier notifier) { } + private Statement withRules(FrameworkMethod method, Object target, + Statement statement) { + List testRules = getTestRules(target); + Statement result = statement; + result = withMethodRules(method, testRules, target, result); + result = withTestRules(method, testRules, result); + + return result; + } + + private Statement withTestRules(FrameworkMethod method, List testRules, + Statement statement) { + return testRules.isEmpty() ? statement : + new RunRules(statement, testRules, describeChild(method)); + } + + private Statement withMethodRules(FrameworkMethod method, List testRules, + Object target, Statement result) { + for (org.junit.rules.MethodRule each : getMethodRules(target)) { + if (!testRules.contains(each)) { + result = each.apply(result, method, target); + } + } + return result; + } + + private List getMethodRules(Object target) { + return rules(target); + } + public List getSmartTestCaseNames() { return smartTestCaseNames; } @@ -179,39 +203,68 @@ protected ZeroCodeReportGenerator getInjectedReportGenerator() { return getMainModuleInjector().getInstance(ZeroCodeReportGenerator.class); } - private void runLeafJsonTest(RunNotifier notifier, Description description, JsonTestCase jsonTestCaseAnno) { - if (jsonTestCaseAnno != null) { - currentTestCase = jsonTestCaseAnno.value(); + private void runLeafJsonTest(FrameworkMethod method, RunNotifier notifier, Description description, JsonTestCase jsonTestCaseAnno) { + Object test; + try { + test = new ReflectiveCallable() { + @Override + protected Object runReflectiveCall() throws Throwable { + return createTest(); + } + }.run(); + } catch (Throwable e) { + return; } - notifier.fireTestStarted(description); - - LOGGER.debug("### Running currentTestCase : " + currentTestCase); - - ScenarioSpec child = null; + Statement statement = createZeroCodeStatement(jsonTestCaseAnno, notifier, description); + statement = possiblyExpectingExceptions(method, test, statement); + statement = withPotentialTimeout(method, test, statement); + statement = withBefores(method, test, statement); + statement = withAfters(method, test, statement); + statement = withRules(method, test, statement); try { - child = smartUtils.scenarioFileToJava(currentTestCase, ScenarioSpec.class); - - LOGGER.debug("### Found currentTestCase : -" + child); - - passed = multiStepsRunner.runScenario(child, notifier, description); - - } catch (Exception ioEx) { - ioEx.printStackTrace(); - notifier.fireTestFailure(new Failure(description, ioEx)); + statement.evaluate(); + } catch (Throwable e) { } - testRunCompleted = true; + } - if (passed) { - LOGGER.info(String.format("\n**FINISHED executing all Steps for [%s] **.\nSteps were:%s", - child.getScenarioName(), - child.getSteps().stream() - .map(step -> step.getName() == null ? step.getId() : step.getName()) - .collect(Collectors.toList()))); - } + private Statement createZeroCodeStatement(JsonTestCase jsonTestCaseAnno, RunNotifier notifier, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + if (jsonTestCaseAnno != null) { + currentTestCase = jsonTestCaseAnno.value(); + } + notifier.fireTestStarted(description); + + LOGGER.debug("### Running currentTestCase : " + currentTestCase); + ScenarioSpec child = null; + try { + child = smartUtils.scenarioFileToJava(currentTestCase, ScenarioSpec.class); + + LOGGER.debug("### Found currentTestCase : -" + child); + + passed = multiStepsRunner.runScenario(child, notifier, description); + } catch (Throwable ioEx) { + ioEx.printStackTrace(); + notifier.fireTestFailure(new Failure(description, ioEx)); + throw ioEx; + } finally { + testRunCompleted = true; + + if (passed) { + LOGGER.info(String.format("\n**FINISHED executing all Steps for [%s] **.\nSteps were:%s", + child.getScenarioName(), + child.getSteps().stream() + .map(step -> step.getName() == null ? step.getId() : step.getName()) + .collect(Collectors.toList()))); + } - notifier.fireTestFinished(description); + notifier.fireTestFinished(description); + } + } + }; } private List getSmartChildrenList() { @@ -220,7 +273,7 @@ private List getSmartChildrenList() { frameworkMethod -> { JsonTestCase jsonTestCaseAnno = frameworkMethod.getAnnotation(JsonTestCase.class); - if(jsonTestCaseAnno == null){ + if (jsonTestCaseAnno == null) { jsonTestCaseAnno = evalScenarioToJsonTestCase(frameworkMethod.getAnnotation(Scenario.class)); } @@ -285,6 +338,7 @@ private final void runLeafJUnitTest(Statement statement, Description description } } + private void buildReportAndPrintToFile(Description description) { ZeroCodeExecReportBuilder reportResultBuilder = newInstance().loop(0).scenarioName(description.getClassName()); reportResultBuilder.step(corrLogger.buildReportSingleStep()); @@ -350,7 +404,7 @@ public Class annotationType() { @Override public String value() { - return scenario != null? scenario.value(): null; + return scenario != null ? scenario.value() : null; } }; diff --git a/core/src/test/java/org/jsmart/zerocode/annotations/TestBeforeAfter.java b/core/src/test/java/org/jsmart/zerocode/annotations/TestBeforeAfter.java new file mode 100644 index 000000000..b32fe8565 --- /dev/null +++ b/core/src/test/java/org/jsmart/zerocode/annotations/TestBeforeAfter.java @@ -0,0 +1,44 @@ +package org.jsmart.zerocode.annotations; + +import org.jsmart.zerocode.core.domain.JsonTestCase; +import org.jsmart.zerocode.core.runner.ZeroCodeUnitRunner; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; + +@RunWith(ZeroCodeUnitRunner.class) +public class TestBeforeAfter { + + private static int variable = 0; + + @Before + public void setUp() { + assertEquals(0, variable); + variable = 1; + } + + @After + public void tearDown() { + assertEquals(1, variable); + variable = 0; + } + + public void assertBeforeIsCalled(String request) { + assertEquals(1, variable); + } + + @Test + @JsonTestCase("integration_test_files/annotations/assert_before.json") + public void test_before_is_called_1() throws Exception { + + } + + @Test + @JsonTestCase("integration_test_files/annotations/assert_before.json") + public void test_before_is_called_2() throws Exception { + + } +} diff --git a/core/src/test/resources/integration_test_files/annotations/assert_before.json b/core/src/test/resources/integration_test_files/annotations/assert_before.json new file mode 100644 index 000000000..5cf305485 --- /dev/null +++ b/core/src/test/resources/integration_test_files/annotations/assert_before.json @@ -0,0 +1,11 @@ +{ + "scenarioName": "Testing @Before, @After annotations", + "steps": [ + { + "name": "assert_step", + "url": "org.jsmart.zerocode.annotations.TestBeforeAfter", + "operation": "assertBeforeIsCalled", + "assertions": {} + } + ] +} \ No newline at end of file