From 1b2a4f0483713c497ef5cbd3e57ec5a8469d06c8 Mon Sep 17 00:00:00 2001 From: Richard Richter Date: Fri, 28 Feb 2020 12:08:45 +0100 Subject: [PATCH] test-util: added Abstract{Unit,Spring}Test classes and UnitTestMixin This helps with test method lifecycle: - printing header/footer of the test - providing typical when/then methods and storing thread-local context It's better to use one of Abstract*Test classes instead of mixin interface directly. --- infra/test-util/pom.xml | 5 ++ .../test/util/AbstractSpringTest.java | 52 +++++++++++++ .../midpoint/test/util/AbstractUnitTest.java | 46 +++++++++++ .../evolveum/midpoint/test/util/TestUtil.java | 10 +-- .../midpoint/test/util/UnitTestMixin.java | 78 +++++++++++++++++++ 5 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java create mode 100644 infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractUnitTest.java create mode 100644 infra/test-util/src/main/java/com/evolveum/midpoint/test/util/UnitTestMixin.java diff --git a/infra/test-util/pom.xml b/infra/test-util/pom.xml index 24007fc05a2..d982f65600e 100644 --- a/infra/test-util/pom.xml +++ b/infra/test-util/pom.xml @@ -61,6 +61,11 @@ org.springframework spring-context + + org.springframework + spring-test + + org.apache.felix diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java new file mode 100644 index 00000000000..2f3de528516 --- /dev/null +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractSpringTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010-2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.test.util; + +import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; + +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; + +/** + * Base test class for tests integrated with Spring providing {@link UnitTestMixin} implementation. + * Can be extended by any unit test class that would otherwise extend + * {@link AbstractTestNGSpringContextTests}. + */ +public abstract class AbstractSpringTest extends AbstractTestNGSpringContextTests + implements UnitTestMixin { + + private static final ThreadLocal TEST_CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); + + /** + * Hides parent's logger, but that one is from commons-logging and we don't want that. + */ + protected final Trace logger = TraceManager.getTrace(getClass()); + + @BeforeMethod + public void startTestContext(ITestResult testResult) { + Class testClass = testResult.getMethod().getTestClass().getRealClass(); + String testMethodName = testResult.getMethod().getMethodName(); + TestUtil.displayTestTitle(testClass.getSimpleName() + "." + testMethodName); + + TEST_CONTEXT_THREAD_LOCAL.set(testResult); + } + + @AfterMethod + public void finishTestContext(ITestResult testResult) { + TEST_CONTEXT_THREAD_LOCAL.remove(); + + displayDefaultTestFooter(testResult); + } + + @Override + public String getTestNameShort() { + return TEST_CONTEXT_THREAD_LOCAL.get().getMethod().getMethodName(); + } +} diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractUnitTest.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractUnitTest.java new file mode 100644 index 00000000000..019b95c2b4f --- /dev/null +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/AbstractUnitTest.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2010-2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.test.util; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; + +import com.evolveum.midpoint.util.logging.Trace; +import com.evolveum.midpoint.util.logging.TraceManager; + +/** + * Base test class providing basic {@link UnitTestMixin} implementation. + * Can be extended by any unit test class that otherwise doesn't extend anything. + */ +public abstract class AbstractUnitTest implements UnitTestMixin { + + private static final ThreadLocal TEST_CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); + + protected final Trace logger = TraceManager.getTrace(getClass()); + + @BeforeMethod + public void startTestContext(ITestResult testResult) { + Class testClass = testResult.getMethod().getTestClass().getRealClass(); + String testMethodName = testResult.getMethod().getMethodName(); + TestUtil.displayTestTitle(testClass.getSimpleName() + "." + testMethodName); + + TEST_CONTEXT_THREAD_LOCAL.set(testResult); + } + + @AfterMethod + public void finishTestContext(ITestResult testResult) { + TEST_CONTEXT_THREAD_LOCAL.remove(); + + displayDefaultTestFooter(testResult); + } + + @Override + public String getTestNameShort() { + return TEST_CONTEXT_THREAD_LOCAL.get().getMethod().getMethodName(); + } +} diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java index b42f23215d8..e38e9e0f1d3 100644 --- a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/TestUtil.java @@ -185,12 +185,12 @@ public static void displayWhen(String what) { LOGGER.info(TEST_LOG_SECTION_PREFIX + " WHEN " + what + TEST_LOG_SECTION_SUFFIX); } - public static void displayWhen(String testName, String part) { - if (part == null) { - part = ""; + public static void displayWhen(String testName, String description) { + if (description == null) { + description = ""; } - System.out.println(TEST_OUT_SECTION_PREFIX + testName + ": WHEN " + part + TEST_OUT_SECTION_SUFFIX); - LOGGER.info(TEST_LOG_SECTION_PREFIX + testName + ": WHEN " + part + TEST_LOG_SECTION_SUFFIX); + System.out.println(TEST_OUT_SECTION_PREFIX + testName + ": WHEN " + description + TEST_OUT_SECTION_SUFFIX); + LOGGER.info(TEST_LOG_SECTION_PREFIX + testName + ": WHEN " + description + TEST_LOG_SECTION_SUFFIX); } // TODO change like when diff --git a/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/UnitTestMixin.java b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/UnitTestMixin.java new file mode 100644 index 00000000000..540ee708e5d --- /dev/null +++ b/infra/test-util/src/main/java/com/evolveum/midpoint/test/util/UnitTestMixin.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010-2020 Evolveum and contributors + * + * This work is dual-licensed under the Apache License 2.0 + * and European Union Public License. See LICENSE file for details. + */ +package com.evolveum.midpoint.test.util; + +import org.testng.ITestResult; + +/** + * Mixin with various utility methods - typically delegating to {@link TestUtil}. + */ +public interface UnitTestMixin { + + /** + * Returns short test name - typically just a method name (without class). + */ + String getTestNameShort(); + + /** + * Displays "when" subsection header with test name. + * Even better, use {@link #when(String)} and provide human readable description. + */ + default void when() { + when(null); + } + + /** + * Displays "when" subsection header with test name and provided description (nullable). + */ + default void when(String description) { + TestUtil.displayWhen(getTestNameShort(), description); + } + + /** + * Displays "then" subsection header with test name. + * Even better, use {@link #then(String)} and provide human readable description. + */ + default void then() { + then(null); + } + + /** + * Displays "then" subsection header with test name and provided description (nullable). + */ + default void then(String description) { + TestUtil.displayThen(getTestNameShort(), description); + } + + // TODO introduce "expect" as well? sometimes we use when/then combined section + // in such a case instead of "given - when/then" we should have "given - expect" + + // TODO inline after merge to master + default void displayWhen() { + when(); + } + + // TODO inline after merge to master + default void displayWhen(String description) { + when(description); + } + + // TODO inline after merge to master + default void displayThen() { + then(); + } + + // TODO inline after merge to master + default void displayThen(String description) { + then(description); + } + + default void displayDefaultTestFooter(ITestResult testResult) { + long testMsDuration = testResult.getEndMillis() - testResult.getStartMillis(); + TestUtil.displayFooter(testResult.getMethod().getMethodName() + " FINISHED in " + testMsDuration + " ms"); + } +}