From c8c3b7ae17178ccced959df6986e47d0a1e2c830 Mon Sep 17 00:00:00 2001 From: Gelin Luo Date: Fri, 20 Mar 2020 11:36:52 +1100 Subject: [PATCH 1/5] support plugin test engine --- CHANGELOG.md | 1 + src/main/java/act/test/DefaultTestEngine.java | 26 +++++++++++ src/main/java/act/test/Interaction.java | 9 ++-- src/main/java/act/test/InteractionPart.java | 8 ++-- src/main/java/act/test/RequestSpec.java | 7 ++- src/main/java/act/test/ResponseSpec.java | 12 ++--- src/main/java/act/test/Scenario.java | 20 ++++++--- src/main/java/act/test/ScenarioPart.java | 4 +- src/main/java/act/test/TestEngine.java | 44 +++++++++++++++++++ src/main/java/act/test/TestEngineManager.java | 22 ++++++++++ src/main/java/act/test/TestSession.java | 3 +- 11 files changed, 134 insertions(+), 22 deletions(-) create mode 100644 src/main/java/act/test/DefaultTestEngine.java create mode 100644 src/main/java/act/test/TestEngine.java create mode 100644 src/main/java/act/test/TestEngineManager.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ab894ac5..ae276fbc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # ActFramework Change Log ##1.8.33** +* support plugin test engine * wrong file object inject from form field into the controller param #1316 * API doc - URL path variable in POST endpoint info is incorrect #1284 * `SampleData.ProvidedBy` is not effective on int type field #1310 diff --git a/src/main/java/act/test/DefaultTestEngine.java b/src/main/java/act/test/DefaultTestEngine.java new file mode 100644 index 000000000..4f571848c --- /dev/null +++ b/src/main/java/act/test/DefaultTestEngine.java @@ -0,0 +1,26 @@ +package act.test; + +import act.util.ProgressGauge; +import act.util.SingletonBase; + +import javax.validation.ValidationException; + +public class DefaultTestEngine extends SingletonBase implements TestEngine { + + public static final String NAME = "default"; + + @Override + public String getName() { + return NAME; + } + + @Override + public void validate(Scenario scenario, TestSession session) throws ValidationException { + scenario.validate(session); + } + + @Override + public boolean run(Scenario scenario, TestSession session, ProgressGauge gauge) { + return scenario.runInteractions(session, gauge); + } +} diff --git a/src/main/java/act/test/Interaction.java b/src/main/java/act/test/Interaction.java index e9e7d6217..c1dd8490e 100644 --- a/src/main/java/act/test/Interaction.java +++ b/src/main/java/act/test/Interaction.java @@ -31,13 +31,12 @@ import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; -import org.osgl.exception.UnexpectedException; import org.osgl.http.H; import org.osgl.util.E; import org.osgl.util.IO; -import org.osgl.util.N; import org.osgl.util.S; +import javax.validation.ValidationException; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -65,8 +64,10 @@ public class Interaction implements ScenarioPart { private transient Metric metric = Act.metricPlugin().metric(ACT_TEST_INTERACTION); @Override - public void validate(TestSession session) throws UnexpectedException { - E.unexpectedIf(null == request, "request spec not specified in interaction[%s]", this); + public void validate(TestSession session) throws ValidationException { + if (null == request) { + throw new ValidationException(S.fmt("request spec not specified in interaction[%s]", this)); + } //E.unexpectedIf(null == response, "response spec not specified"); act.metric.Timer timer = metric.startTimer("validate"); try { diff --git a/src/main/java/act/test/InteractionPart.java b/src/main/java/act/test/InteractionPart.java index ff0cc27e1..ec99a293f 100644 --- a/src/main/java/act/test/InteractionPart.java +++ b/src/main/java/act/test/InteractionPart.java @@ -22,15 +22,17 @@ import org.osgl.exception.UnexpectedException; +import javax.xml.bind.ValidationException; + public interface InteractionPart { /** * Check if the interaction part is valid. * - * If the data is not valid then throw out {@link UnexpectedException} + * If the data is not valid then throw out {@link ValidationException} * * @param interaction * the interaction in which this part is in - * @throws {@link UnexpectedException} if the data is not valid + * @throws {@link ValidationException} if the data is not valid */ - void validate(Interaction interaction) throws UnexpectedException; + void validate(Interaction interaction) throws ValidationException; } diff --git a/src/main/java/act/test/RequestSpec.java b/src/main/java/act/test/RequestSpec.java index 01850ea2d..e4bb030f6 100644 --- a/src/main/java/act/test/RequestSpec.java +++ b/src/main/java/act/test/RequestSpec.java @@ -29,6 +29,7 @@ import org.osgl.http.H; import org.osgl.util.*; +import javax.validation.ValidationException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -90,7 +91,7 @@ public void resolveParent(RequestTemplateManager manager) { } @Override - public void validate(Interaction interaction) throws UnexpectedException { + public void validate(Interaction interaction) throws ValidationException { if (S.notBlank(email)) { return; } @@ -107,7 +108,9 @@ public void validate(Interaction interaction) throws UnexpectedException { method = H.Method.DELETE; url = delete; } - E.unexpectedIf(null == method, "method not specified in request spec of interaction[%s]", interaction); + if (null == method) { + throw new ValidationException(S.fmt("method not specified in request spec of interaction[%s]", interaction)); + } if (null == url || ".".equals(url)) { url = ""; } diff --git a/src/main/java/act/test/ResponseSpec.java b/src/main/java/act/test/ResponseSpec.java index 06896d99a..564435d84 100644 --- a/src/main/java/act/test/ResponseSpec.java +++ b/src/main/java/act/test/ResponseSpec.java @@ -9,9 +9,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -21,13 +21,13 @@ */ import act.util.AdaptiveBeanBase; -import act.util.EnhancedAdaptiveMap; import com.alibaba.fastjson.JSON; import org.osgl.$; import org.osgl.exception.UnexpectedException; import org.osgl.http.H; import org.osgl.util.S; +import javax.validation.ValidationException; import java.lang.reflect.Field; import java.util.LinkedHashMap; import java.util.List; @@ -50,7 +50,7 @@ public enum Type { public Type __type; @Override - public void validate(Interaction interaction) throws UnexpectedException { + public void validate(Interaction interaction) throws ValidationException { checkForEmpty(interaction); } @@ -61,7 +61,7 @@ public String toString() { private void checkForEmpty(Interaction interaction) { if (size() == 0) { - throw new UnexpectedException("Empty response spec found in interaction[%s]", interaction); + throw new ValidationException(S.fmt("Empty response spec found in interaction[%s]", interaction)); } Map map = this.toMap(); String accept; @@ -110,7 +110,7 @@ private void checkForEmpty(Interaction interaction) { if (S.notBlank(downloadFilename)) { return; } - throw new UnexpectedException("Empty response spec found in interaction[%s]", interaction); + throw new ValidationException(S.fmt("Empty response spec found in interaction[%s]", interaction)); } } diff --git a/src/main/java/act/test/Scenario.java b/src/main/java/act/test/Scenario.java index 0e8cb7e50..cf53b4aa3 100644 --- a/src/main/java/act/test/Scenario.java +++ b/src/main/java/act/test/Scenario.java @@ -28,16 +28,17 @@ import act.metric.MetricInfo; import act.metric.Timer; import act.test.util.*; +import act.util.AdaptiveBeanBase; import act.util.ProgressGauge; import org.osgl.$; -import org.osgl.exception.UnexpectedException; import org.osgl.logging.LogManager; import org.osgl.logging.Logger; import org.osgl.util.*; +import javax.validation.ValidationException; import java.util.*; -public class Scenario implements ScenarioPart { +public class Scenario extends AdaptiveBeanBase implements ScenarioPart { private static final Logger LOGGER = LogManager.get(Scenario.class); @@ -45,6 +46,7 @@ public class Scenario implements ScenarioPart { private static final ThreadLocal current = new ThreadLocal<>(); + public String engine; public String name; public String issueKey; public boolean noIssue; @@ -136,6 +138,14 @@ public String errorMessageOf(Interaction interaction) { return interaction.errorMessage; } + public TestEngine getEngine() { + if (S.blank(engine)) { + return DefaultTestEngine.instance(); + } + TestEngineManager manager = TestEngineManager.instance(); + return manager.getEngine(engine); + } + public void resolveDependencies() { if (!allDepends.isEmpty()) { // already resolved @@ -169,7 +179,7 @@ public void resolveSetupDependencies() { } @Override - public void validate(TestSession session) throws UnexpectedException { + public void validate(TestSession session) throws ValidationException { errorIf(S.blank(name), "Scenario name not defined"); for (Interaction interaction : interactions) { interaction.validate(session); @@ -252,13 +262,13 @@ boolean run(TestSession session, ProgressGauge gauge) { } Timer timer = metric.startTimer("run"); try { - return generateTestData(session) && runInteractions(session, gauge); + return generateTestData(session) && getEngine().run(this, session, gauge); } finally { timer.stop(); } } - private boolean runInteractions(TestSession session, ProgressGauge gauge) { + boolean runInteractions(TestSession session, ProgressGauge gauge) { if (LOGGER.isTraceEnabled()) { LOGGER.trace("run interactions for " + name); } diff --git a/src/main/java/act/test/ScenarioPart.java b/src/main/java/act/test/ScenarioPart.java index fc2d52796..69f50b6e7 100644 --- a/src/main/java/act/test/ScenarioPart.java +++ b/src/main/java/act/test/ScenarioPart.java @@ -22,6 +22,8 @@ import org.osgl.exception.UnexpectedException; +import javax.xml.bind.ValidationException; + public interface ScenarioPart { /** * Check if the data is valid. @@ -30,7 +32,7 @@ public interface ScenarioPart { * * @throws {@link UnexpectedException} if the data is not valid */ - void validate(TestSession session) throws UnexpectedException; + void validate(TestSession session) throws ValidationException; void reset(); } diff --git a/src/main/java/act/test/TestEngine.java b/src/main/java/act/test/TestEngine.java new file mode 100644 index 000000000..de861fd4c --- /dev/null +++ b/src/main/java/act/test/TestEngine.java @@ -0,0 +1,44 @@ +package act.test; + +import act.util.ProgressGauge; + +import javax.validation.ValidationException; + +/** + * A `TestEngine` runs {@link Scenario test scenario} and {@link TestSession test session}. + */ +public interface TestEngine { + + /** + * Returns name of this test engine. + * + * Note test engine name must be unique across implmentations. + * + * @return test engine name + */ + String getName(); + + /** + * Validate a {@link Scenario test scenario}. + * + * If there are any issue with the test scenario then a {@link ValidationException} + * shall be raised. + * + * @param scenario a test scenario to be validated. + * @param session the test session that contains the scenario. + * @throws ValidationException in case any issue with the test session + */ + void validate(Scenario scenario, TestSession session) throws ValidationException; + + /** + * Run a {@link Scenario test scenario}. + * + * @param scenario the scenario to run by the test engine. + * @param session the test session that contains the scenario. + * @param gauge the progress gauge to track progress. + * @return `true` if run pass, `false` otherwise. + */ + boolean run(Scenario scenario, TestSession session, ProgressGauge gauge); + + +} diff --git a/src/main/java/act/test/TestEngineManager.java b/src/main/java/act/test/TestEngineManager.java new file mode 100644 index 000000000..b95deb0ce --- /dev/null +++ b/src/main/java/act/test/TestEngineManager.java @@ -0,0 +1,22 @@ +package act.test; + +import act.util.SingletonBase; +import org.osgl.inject.annotation.MapKey; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Map; + +@Singleton +public class TestEngineManager extends SingletonBase { + + @Inject + @MapKey("name") + private Map engineLookup; + + public TestEngine getEngine(String name) { + TestEngine engine = engineLookup.get(name); + return null == engine ? engineLookup.get(DefaultTestEngine.NAME) : engine; + } + +} diff --git a/src/main/java/act/test/TestSession.java b/src/main/java/act/test/TestSession.java index 9863eaf9c..d197d9947 100644 --- a/src/main/java/act/test/TestSession.java +++ b/src/main/java/act/test/TestSession.java @@ -167,9 +167,10 @@ private boolean runOne(Scenario scenario, ProgressGauge gauge) { gauge.clearPayload(); gauge.setPayload(Test.PG_PAYLOAD_SCENARIO, scenario.title()); boolean okay; + TestEngine engine = scenario.getEngine(); try { running = $.requireNotNull(scenario); - scenario.validate(this); + engine.validate(scenario, this); constants.putAll(running.constants); okay = createFixtures() && scenario.run(this, gauge); scenario.status = TestStatus.of(okay); From 08a8b5c92ae51ac978745b34319b43394ff8d8e1 Mon Sep 17 00:00:00 2001 From: Gelin Luo Date: Fri, 20 Mar 2020 11:42:28 +1100 Subject: [PATCH 2/5] support test engine --- src/main/java/act/test/DefaultTestEngine.java | 20 +++++++++++++++++++ src/main/java/act/test/TestEngine.java | 20 +++++++++++++++++++ src/main/java/act/test/TestEngineManager.java | 20 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/src/main/java/act/test/DefaultTestEngine.java b/src/main/java/act/test/DefaultTestEngine.java index 4f571848c..75f658d23 100644 --- a/src/main/java/act/test/DefaultTestEngine.java +++ b/src/main/java/act/test/DefaultTestEngine.java @@ -1,5 +1,25 @@ package act.test; +/*- + * #%L + * ACT Framework + * %% + * Copyright (C) 2014 - 2020 ActFramework + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + import act.util.ProgressGauge; import act.util.SingletonBase; diff --git a/src/main/java/act/test/TestEngine.java b/src/main/java/act/test/TestEngine.java index de861fd4c..e9a23385d 100644 --- a/src/main/java/act/test/TestEngine.java +++ b/src/main/java/act/test/TestEngine.java @@ -1,5 +1,25 @@ package act.test; +/*- + * #%L + * ACT Framework + * %% + * Copyright (C) 2014 - 2020 ActFramework + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + import act.util.ProgressGauge; import javax.validation.ValidationException; diff --git a/src/main/java/act/test/TestEngineManager.java b/src/main/java/act/test/TestEngineManager.java index b95deb0ce..3e354d100 100644 --- a/src/main/java/act/test/TestEngineManager.java +++ b/src/main/java/act/test/TestEngineManager.java @@ -1,5 +1,25 @@ package act.test; +/*- + * #%L + * ACT Framework + * %% + * Copyright (C) 2014 - 2020 ActFramework + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + import act.util.SingletonBase; import org.osgl.inject.annotation.MapKey; From c45097264cd8ffc9697784f22b2e46184aec5eb2 Mon Sep 17 00:00:00 2001 From: Gelin Luo Date: Wed, 25 Mar 2020 22:16:33 +1100 Subject: [PATCH 3/5] WIP --- pom.xml | 2 +- src/main/java/act/test/DefaultTestEngine.java | 15 ++++++++++++ src/main/java/act/test/Test.java | 2 ++ src/main/java/act/test/TestEngine.java | 14 +++++++++++ src/main/java/act/test/TestEngineManager.java | 6 +++++ src/main/java/act/test/TestSession.java | 23 +++++++++++-------- 6 files changed, 51 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index eceee70ad..432d8f4b7 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,7 @@ 1.2 1.3.3 3.12.3 - 1.2.66 + 1.2.67 1.1.2 0.7 1.18 diff --git a/src/main/java/act/test/DefaultTestEngine.java b/src/main/java/act/test/DefaultTestEngine.java index 75f658d23..2fbb89c39 100644 --- a/src/main/java/act/test/DefaultTestEngine.java +++ b/src/main/java/act/test/DefaultTestEngine.java @@ -43,4 +43,19 @@ public void validate(Scenario scenario, TestSession session) throws ValidationEx public boolean run(Scenario scenario, TestSession session, ProgressGauge gauge) { return scenario.runInteractions(session, gauge); } + + @Override + public void setup() { + + } + + @Override + public void setupSession(TestSession session) { + session.prepareHttp(); + session.reset(); + } + + @Override + public void teardownSession(TestSession session) { + } } diff --git a/src/main/java/act/test/Test.java b/src/main/java/act/test/Test.java index a8501c805..8d4007345 100644 --- a/src/main/java/act/test/Test.java +++ b/src/main/java/act/test/Test.java @@ -323,6 +323,8 @@ public List run(App app, Keyword testId, String partition, boolean shu eventBus.trigger(TestStart.INSTANCE); app.captchaManager().disable(); registerTypeConverters(); + TestEngineManager tem = Act.getInstance(TestEngineManager.class); + tem.setupEngines(); RequestTemplateManager requestTemplateManager = new RequestTemplateManager(); requestTemplateManager.load(); final ScenarioManager scenarioManager = new ScenarioManager(); diff --git a/src/main/java/act/test/TestEngine.java b/src/main/java/act/test/TestEngine.java index e9a23385d..b81370581 100644 --- a/src/main/java/act/test/TestEngine.java +++ b/src/main/java/act/test/TestEngine.java @@ -60,5 +60,19 @@ public interface TestEngine { */ boolean run(Scenario scenario, TestSession session, ProgressGauge gauge); + /** + * Set up the test engine before running any test. + */ + void setup(); + + /** + * Prepare to run a {@link TestSession} + */ + void setupSession(TestSession session); + + /** + * Tear down after running a {@link TestSession} + */ + void teardownSession(TestSession session); } diff --git a/src/main/java/act/test/TestEngineManager.java b/src/main/java/act/test/TestEngineManager.java index 3e354d100..f4eeb9689 100644 --- a/src/main/java/act/test/TestEngineManager.java +++ b/src/main/java/act/test/TestEngineManager.java @@ -39,4 +39,10 @@ public TestEngine getEngine(String name) { return null == engine ? engineLookup.get(DefaultTestEngine.NAME) : engine; } + public void setupEngines() { + for (TestEngine engine : engineLookup.values()) { + engine.setup(); + } + } + } diff --git a/src/main/java/act/test/TestSession.java b/src/main/java/act/test/TestSession.java index d197d9947..13ac05822 100644 --- a/src/main/java/act/test/TestSession.java +++ b/src/main/java/act/test/TestSession.java @@ -114,18 +114,21 @@ public int port() { public void run(ProgressGauge gauge) { current.set(this); - prepareHttp(); - gauge.incrMaxHintBy(dependencies.size() + 2); - reset(); - gauge.step(); - proceed = runAll(gauge, dependencies); - if (proceed) { - proceed = runOne(target, gauge); + target.getEngine().setupSession(this); + try { + gauge.incrMaxHintBy(dependencies.size() + 2); + gauge.step(); + proceed = runAll(gauge, dependencies); + if (proceed) { + proceed = runOne(target, gauge); + } + gauge.step(); + } finally { + target.getEngine().teardownSession(this); } - gauge.step(); } - private boolean reset() { + boolean reset() { Collections.sort(dependencies, new ScenarioComparator(target.partition)); for (Scenario scenario : dependencies) { scenario.reset(); @@ -261,7 +264,7 @@ boolean verify(RequestSpec req, String operation) { } } - private void prepareHttp() { + void prepareHttp() { if (isTraceEnabled()) { trace("prepareHTTP for scenario: " + target.name); } From 2b2d77c80dcf2f53934328d997986e777e4e1e35 Mon Sep 17 00:00:00 2001 From: Gelin Luo Date: Sun, 24 May 2020 13:41:29 +1000 Subject: [PATCH 4/5] update version tag --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7b6f9d529..735ce5934 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ org.actframework act jar - 1.8.33-SNAPSHOT + 1.8.33-te-SNAPSHOT ACT Framework The ACT full stack MVC framework From 59e4bc3547677a8dfdc2436825e425a0b41d7abf Mon Sep 17 00:00:00 2001 From: Gelin Luo Date: Fri, 29 May 2020 08:43:13 +1000 Subject: [PATCH 5/5] #1339 teardown test engines once all tests run --- CHANGELOG.md | 2 +- src/main/java/act/test/DefaultTestEngine.java | 5 +++++ src/main/java/act/test/Test.java | 5 +++-- src/main/java/act/test/TestEngine.java | 5 +++++ src/main/java/act/test/TestEngineManager.java | 6 ++++++ src/main/java/act/test/TestSession.java | 1 + 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fbea43a7..69528bc7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # ActFramework Change Log ##1.8.33** -* support plugin test engine +* support plugin test engine #1339 * Scenario manager - support loading test scenario files from child folders recursively #1337 * Param value loader framework - allow inject another controller class #1336 * `EnhancedAdaptiveMap.asMap(EnhancedAdaptiveMap)` generated `Map` shall implement hashCode and equals methods #1333 diff --git a/src/main/java/act/test/DefaultTestEngine.java b/src/main/java/act/test/DefaultTestEngine.java index f6777ba81..fc0955777 100644 --- a/src/main/java/act/test/DefaultTestEngine.java +++ b/src/main/java/act/test/DefaultTestEngine.java @@ -65,4 +65,9 @@ public void setupSession(TestSession session) { @Override public void teardownSession(TestSession session) { } + + @Override + public void teardown() { + } + } diff --git a/src/main/java/act/test/Test.java b/src/main/java/act/test/Test.java index 6638f7da0..110e157eb 100644 --- a/src/main/java/act/test/Test.java +++ b/src/main/java/act/test/Test.java @@ -319,12 +319,12 @@ public List run(App app, Keyword testId, String partition, boolean shu this.error = null; this.result = C.list(); this.gauge = gauge; + TestEngineManager engineManager = Act.getInstance(TestEngineManager.class); try { eventBus.trigger(TestStart.INSTANCE); app.captchaManager().disable(); registerTypeConverters(); - TestEngineManager tem = Act.getInstance(TestEngineManager.class); - tem.setupEngines(); + engineManager.setupEngines(); RequestTemplateManager requestTemplateManager = new RequestTemplateManager(); requestTemplateManager.load(); final ScenarioManager scenarioManager = new ScenarioManager(); @@ -460,6 +460,7 @@ public List run(App app, Keyword testId, String partition, boolean shu } else { app.captchaManager().enable(); } + engineManager.teardownEngines(); eventBus.trigger(TestStop.INSTANCE); } } diff --git a/src/main/java/act/test/TestEngine.java b/src/main/java/act/test/TestEngine.java index 625593d18..b3dd7a624 100644 --- a/src/main/java/act/test/TestEngine.java +++ b/src/main/java/act/test/TestEngine.java @@ -82,4 +82,9 @@ public interface TestEngine { */ void teardownSession(TestSession session); + /** + * Tear down after running all tests + */ + void teardown(); + } diff --git a/src/main/java/act/test/TestEngineManager.java b/src/main/java/act/test/TestEngineManager.java index 60d7fe269..d661b5168 100644 --- a/src/main/java/act/test/TestEngineManager.java +++ b/src/main/java/act/test/TestEngineManager.java @@ -50,4 +50,10 @@ public void setupEngines() { } } + public void teardownEngines() { + for (TestEngine engine: engineLookup.values()) { + engine.teardown(); + } + } + } diff --git a/src/main/java/act/test/TestSession.java b/src/main/java/act/test/TestSession.java index 8c25dd53c..8c1cbeb58 100644 --- a/src/main/java/act/test/TestSession.java +++ b/src/main/java/act/test/TestSession.java @@ -92,6 +92,7 @@ static TestSession current() { public TestSession(Scenario scenario, RequestTemplateManager requestTemplateManager) { this.requestTemplateManager = requestTemplateManager; dependencies.addAll(scenario.allDepends); + Collections.sort(dependencies, new ScenarioComparator(false)); target = scenario; app = Act.app(); if (null != app) {