diff --git a/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java b/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java index feb5a69f53..ba9dab77ad 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java +++ b/core/citrus-api/src/main/java/org/citrusframework/CitrusSettings.java @@ -1,5 +1,28 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + package org.citrusframework; +import org.citrusframework.message.MessageType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; @@ -11,10 +34,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.citrusframework.common.TestLoader; -import org.citrusframework.message.MessageType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.citrusframework.common.TestLoader.GROOVY; +import static org.citrusframework.common.TestLoader.SPRING; +import static org.citrusframework.common.TestLoader.XML; +import static org.citrusframework.common.TestLoader.YAML; /** * @author Christoph Deppisch @@ -287,16 +310,11 @@ public static Set getLogMaskKeywords() { * @return */ public static Set getTestFileNamePattern(String type) { - switch (type) { - case TestLoader.XML: - case TestLoader.SPRING: - return CitrusSettings.getXmlTestFileNamePattern(); - case TestLoader.GROOVY: - return CitrusSettings.getGroovyTestFileNamePattern(); - case TestLoader.YAML: - return CitrusSettings.getYamlTestFileNamePattern(); - default: - return Collections.emptySet(); - } + return switch (type) { + case SPRING, XML -> CitrusSettings.getXmlTestFileNamePattern(); + case GROOVY -> CitrusSettings.getGroovyTestFileNamePattern(); + case YAML -> CitrusSettings.getYamlTestFileNamePattern(); + default -> Collections.emptySet(); + }; } } diff --git a/core/citrus-api/src/main/java/org/citrusframework/TestCaseRunnerProvider.java b/core/citrus-api/src/main/java/org/citrusframework/TestCaseRunnerProvider.java index 1c1480643a..e4fe58c967 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/TestCaseRunnerProvider.java +++ b/core/citrus-api/src/main/java/org/citrusframework/TestCaseRunnerProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2023 the original author or authors. + * Copyright 2023-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -28,6 +28,7 @@ * @since 4.0 */ public interface TestCaseRunnerProvider { + /** * Creates a TestCaseRunner which runs the given {@link TestCase} and the given {@link TestContext}. * @param testCase @@ -42,5 +43,4 @@ public interface TestCaseRunnerProvider { * @return */ TestCaseRunner createTestCaseRunner(TestContext context); - } diff --git a/core/citrus-api/src/main/java/org/citrusframework/common/TestLoader.java b/core/citrus-api/src/main/java/org/citrusframework/common/TestLoader.java index 87298f9956..6ebac3763b 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/common/TestLoader.java +++ b/core/citrus-api/src/main/java/org/citrusframework/common/TestLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2013 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,30 @@ package org.citrusframework.common; -import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; - import org.citrusframework.TestCase; import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.spi.ResourcePathTypeResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; +import java.util.Optional; +import java.util.function.Consumer; + +import static java.util.stream.Collectors.toMap; + /** * Test loader interface. + *

+ * Deprecation notice: Implementations of this interface load and execute test cases in one breath. That + * is very intransparent to end-users. It is therefore supersed by the {@link TestLoaderAndExecutor}, which splits + * loading and execution of test cases into multiple methods, or at least has a more transparent API. + * * @author Christoph Deppisch * @since 2.1 + * @deprecated use {@link TestLoaderAndExecutor} instead */ +@Deprecated public interface TestLoader { /** Logger */ @@ -48,19 +57,18 @@ public interface TestLoader { String GROOVY = "groovy"; /** - * Loads and creates new test case object. - * @return + * Loads and creates new test case object. The test case is expected to be cached and returned by {@link TestLoader#getTestCase()}. */ void load(); /** * Adds test case handler that is called before test case gets executed. - * @param handler + * @param configurer */ - void configureTestCase(Consumer handler); + void configureTestCase(Consumer configurer); /** - * Adds test case handler that is called once the test case has been loaded. + * Adds test case handler that is called once the test case has been executed. * @param handler */ void doWithTestCase(Consumer handler); @@ -80,14 +88,19 @@ public interface TestLoader { /** * Resolves all available test loader from resource path lookup. Scans classpath for test loader meta information * and instantiates the components. - * @return + * + * @return the available test loaders */ static Map lookup() { - Map loader = TYPE_RESOLVER.resolveAll(); + Map loader = TYPE_RESOLVER.resolveAll() + .entrySet().stream() + .filter(entry -> entry.getValue() instanceof TestLoader) + .collect(toMap(Map.Entry::getKey, e -> ((TestLoader) e.getValue()))); if (logger.isDebugEnabled()) { loader.forEach((k, v) -> logger.debug(String.format("Found test loader '%s' as %s", k, v.getClass()))); } + return loader; } @@ -95,14 +108,17 @@ static Map lookup() { * Resolves test loader from resource path lookup with given resource name. Scans classpath for test loader meta information * with given name and returns instance of the loader. Returns optional instead of throwing exception when no test loader * could be found. - * @param loader - * @return + * + * @param loader the name of the test loader + * @return the test loader, if present */ static Optional lookup(String loader) { try { return Optional.of(TYPE_RESOLVER.resolve(loader)); } catch (CitrusRuntimeException e) { logger.warn(String.format("Failed to resolve test loader from resource '%s/%s'", RESOURCE_PATH, loader)); + } catch (ClassCastException ignore) { + // Ignore exception } return Optional.empty(); diff --git a/core/citrus-api/src/main/java/org/citrusframework/common/TestLoaderAndExecutor.java b/core/citrus-api/src/main/java/org/citrusframework/common/TestLoaderAndExecutor.java new file mode 100644 index 0000000000..a24ad1c253 --- /dev/null +++ b/core/citrus-api/src/main/java/org/citrusframework/common/TestLoaderAndExecutor.java @@ -0,0 +1,105 @@ +/* + * Copyright 2024 the original author or authors. + * + * 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. + */ + +package org.citrusframework.common; + +import org.citrusframework.TestCase; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.Resource; + +import java.util.Map; +import java.util.Optional; + +import static java.util.stream.Collectors.toMap; + +/** + * Provides an interface for loading and executing test cases. + *

+ * This interface extends both {@link InitializingPhase} and {@link TestLoader}, offering methods to discover, load, and + * execute test cases. Test cases are resolved using resource path lookup and can be executed immediately upon loading + * or loaded for later execution. + */ +public interface TestLoaderAndExecutor extends InitializingPhase, TestLoader { + + /** + * Discovers and returns all available {@link TestLoaderAndExecutor} instances by scanning the classpath for test + * loader meta-information. This method facilitates the dynamic discovery of test loader and executor components. + * + * @return A map of test loader and executor names to their respective {@link TestLoaderAndExecutor} instances. + */ + static Map lookup() { + Map testLoaderAndExecutors = TYPE_RESOLVER.resolveAll(); + testLoaderAndExecutors = testLoaderAndExecutors.entrySet() + .stream() + .filter(entry -> entry.getValue() instanceof TestLoaderAndExecutor) + .collect(toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (logger.isDebugEnabled()) { + testLoaderAndExecutors.forEach((k, v) -> logger.debug(String.format("Found test loader and executor '%s' as %s", k, v.getClass()))); + } + + return testLoaderAndExecutors; + } + + + /** + * Attempts to resolve a specific {@link TestLoaderAndExecutor} by its name. This method scans the classpath for + * test loader meta-information matching the given name. It returns an Optional to avoid exceptions when a test + * loader is not found. + * + * @param loader the name of the test loader to resolve. + * @return An {@link Optional} containing the resolved {@link TestLoaderAndExecutor}, if found. + */ + static Optional lookup(String loader) { + try { + return Optional.of(TYPE_RESOLVER.resolve(loader)); + } catch (CitrusRuntimeException e) { + logger.warn(String.format("Failed to resolve test loader and executor from resource '%s/%s'", RESOURCE_PATH, loader)); + } catch (ClassCastException ignore) { + // Ignore exception + } + + return Optional.empty(); + } + + /** + * Loads a new test case and immediately executes it. This method combines the process of loading a test case from + * resources and executing it in one step. + * + * @return The executed {@link TestCase} instance. + */ + default TestCase loadAndExecute() { + load(); + return getTestCase(); + } + + /** + * Loads a test case from the specified resource without executing it. This method allows for deferred execution + * of the test case. + * + * @param resource the resource from which to load the test case. + * @return The loaded {@link TestCase} instance. + */ + TestCase loadTestCase(Resource resource); + + /** + * Executes the provided test case. This method allows for the execution of a preloaded test case. + * + * @param testCase the test case to execute. + * @return The executed {@link TestCase} instance. + */ + TestCase executeTestCase(TestCase testCase); +} diff --git a/core/citrus-api/src/main/java/org/citrusframework/context/TestContext.java b/core/citrus-api/src/main/java/org/citrusframework/context/TestContext.java index e6683c3f24..e0ada293b8 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/context/TestContext.java +++ b/core/citrus-api/src/main/java/org/citrusframework/context/TestContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2010 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -904,6 +904,7 @@ public boolean isSuccess(TestResult testResult) { * Empty test case implementation used as test result when tests fail before execution. */ private static class EmptyTestCase implements TestCase { + private final String testName; private final String packageName; diff --git a/core/citrus-api/src/main/java/org/citrusframework/spi/ClasspathResourceResolver.java b/core/citrus-api/src/main/java/org/citrusframework/spi/ClasspathResourceResolver.java index 9c7e176d2c..caf7bb7c93 100644 --- a/core/citrus-api/src/main/java/org/citrusframework/spi/ClasspathResourceResolver.java +++ b/core/citrus-api/src/main/java/org/citrusframework/spi/ClasspathResourceResolver.java @@ -82,6 +82,7 @@ public Set getResources(String path) throws IOException { for (ClassLoader classLoader : getClassLoaders()) { findResources(path, classLoader, resources, name -> !name.endsWith(".class")); } + return resources; } @@ -91,11 +92,10 @@ public Set getResources(String path, String fileNamePattern) throws IOExce .collect(Collectors.toSet()); } - private void findResources(String path, ClassLoader classLoader, Set result, - Predicate filter) throws IOException { + private void findResources(String path, ClassLoader classLoader, Set result, Predicate filter) throws IOException { String resourcePath; - // If the URL is a jar, the URLClassloader.getResources() seems to require a trailing slash. The - // trailing slash is harmless for other URLs + // If the URL is a jar, the URLClassloader.getResources() seems to require a trailing slash. The trailing slash + // is harmless for other URLs! if (!path.isEmpty() && !path.endsWith("/")) { resourcePath = path.replace(".", "/") + "/"; } else { @@ -126,10 +126,7 @@ private void findResources(String path, ClassLoader classLoader, Set resul } } - private void loadResourcesInJar(ClassLoader classLoader, String path, - String urlPath, Set resources, Predicate filter) - throws IOException { - + private void loadResourcesInJar(ClassLoader classLoader, String path, String urlPath, Set resources, Predicate filter) throws IOException { String[] split = urlPath.split("!"); if (split.length == 1) { @@ -139,7 +136,6 @@ private void loadResourcesInJar(ClassLoader classLoader, String path, } else { throw new CitrusRuntimeException("Unable to load urlPath from : "+urlPath); } - } /** @@ -154,8 +150,7 @@ private static void loadFromNestedJar(ClassLoader classLoader, String path, Stri } } - private static void readFromJarStream(ClassLoader classLoader, String path, String urlPath, - Set resources, Predicate filter, InputStream jarInputStream) { + private static void readFromJarStream(ClassLoader classLoader, String path, String urlPath, Set resources, Predicate filter, InputStream jarInputStream) { List entries = new ArrayList<>(); try (JarInputStream jarStream = new JarInputStream(jarInputStream)) { JarEntry entry; @@ -168,8 +163,7 @@ private static void readFromJarStream(ClassLoader classLoader, String path, Stri for (String name : entries) { if (logger.isTraceEnabled()) { - logger.trace("Found resource: {} in {}", name.substring(path.length()), - urlPath); + logger.trace("Found resource: {} in {}", name.substring(path.length()), urlPath); } URL url = classLoader.getResource(name); if (url != null) { @@ -177,8 +171,7 @@ private static void readFromJarStream(ClassLoader classLoader, String path, Stri } } } catch (IOException e) { - logger.warn("Cannot search jar file '{} due to an IOException: {}", urlPath, - e.getMessage(), e); + logger.warn("Cannot search jar file '{} due to an IOException: {}", urlPath, e.getMessage(), e); } } @@ -196,8 +189,7 @@ private void loadResourcesInDirectory(String path, File location, Set resu String name = file.getName().trim(); if (file.isDirectory()) { - loadResourcesInDirectory(builder.append(path).append(name).append("/").toString(), - file, result, filter); + loadResourcesInDirectory(builder.append(path).append(name).append("/").toString(), file, result, filter); } else if (file.isFile() && file.exists() && filter.test(name)) { logger.trace("Found resource: {} as {}", name, file.toURI()); result.add(Paths.get(builder.append(path).append(name).toString())); @@ -245,14 +237,12 @@ private static String removeNestedProtocol(String urlPath) { private Set getClassLoaders() { Set classLoaders = new LinkedHashSet<>(); try { - ClassLoader ccl = Thread.currentThread().getContextClassLoader(); - if (ccl != null) { - classLoaders.add(ccl); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader != null) { + classLoaders.add(classLoader); } } catch (Exception e) { - logger.warn( - "Cannot add ContextClassLoader from current thread due {}. This exception will be ignored", - e.getMessage()); + logger.warn("Cannot add ContextClassLoader from current thread due {}. This exception will be ignored", e.getMessage()); } classLoaders.add(ClasspathResourceResolver.class.getClassLoader()); diff --git a/core/citrus-base/src/main/java/org/citrusframework/DefaultTestCaseRunner.java b/core/citrus-base/src/main/java/org/citrusframework/DefaultTestCaseRunner.java index 68ccfb2ceb..e435b93dbe 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/DefaultTestCaseRunner.java +++ b/core/citrus-base/src/main/java/org/citrusframework/DefaultTestCaseRunner.java @@ -1,3 +1,22 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + package org.citrusframework; import java.util.Date; @@ -127,6 +146,7 @@ public T run(TestActionBuilder builder) { testCase.addTestAction(action); testCase.executeAction(action, context); + return action; } @@ -163,6 +183,5 @@ public TestCaseRunner createTestCaseRunner(TestContext context) { public TestCaseRunner createTestCaseRunner(TestCase testCase, TestContext context) { return new DefaultTestCaseRunner(testCase, context); } - } } diff --git a/core/citrus-base/src/main/java/org/citrusframework/common/DefaultTestLoader.java b/core/citrus-base/src/main/java/org/citrusframework/common/DefaultTestLoader.java index 123d358b4f..695eeaffad 100644 --- a/core/citrus-base/src/main/java/org/citrusframework/common/DefaultTestLoader.java +++ b/core/citrus-base/src/main/java/org/citrusframework/common/DefaultTestLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2022-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -75,8 +75,7 @@ public DefaultTestLoader() { /** * Constructor with context file and parent application context field for simple initialisation. **/ - public DefaultTestLoader(Class testClass, String testName, String packageName, - CitrusContext citrusContext) { + public DefaultTestLoader(Class testClass, String testName, String packageName, CitrusContext citrusContext) { this.testClass = testClass; this.testName = testName; this.packageName = packageName; diff --git a/core/citrus-base/src/main/java/org/citrusframework/util/SystemProvider.java b/core/citrus-base/src/main/java/org/citrusframework/util/SystemProvider.java new file mode 100644 index 0000000000..7a72a3ae59 --- /dev/null +++ b/core/citrus-base/src/main/java/org/citrusframework/util/SystemProvider.java @@ -0,0 +1,35 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.citrusframework.util; + +import java.util.Optional; + +import static java.util.Optional.ofNullable; + +public final class SystemProvider { + + public Optional getEnv(String envVarName) { + return ofNullable(System.getenv(envVarName)); + } + + public Optional getProperty(String propertyName) { + return ofNullable(System.getProperty(propertyName)); + } +} diff --git a/core/citrus-base/src/test/java/org/citrusframework/util/SystemProviderTest.java b/core/citrus-base/src/test/java/org/citrusframework/util/SystemProviderTest.java new file mode 100644 index 0000000000..8e908c8dbe --- /dev/null +++ b/core/citrus-base/src/test/java/org/citrusframework/util/SystemProviderTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.citrusframework.util; + +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.util.Optional; + +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + +public class SystemProviderTest { + + private SystemProvider systemProvider; + + @BeforeTest + public void beforeTestSetup() { + systemProvider = new SystemProvider(); + } + + @Test + public void getEnvWithExistingVariable() { + // Assuming 'PATH' is an existing environment variable + String envVarName = "PATH"; + Optional result = systemProvider.getEnv(envVarName); + + assertTrue("Expected environment variable PATH to be present", result.isPresent()); + } + + @Test + public void getEnvWithNonExistingVariable() { + String envVarName = "NON_EXISTING_ENV_VAR"; + Optional result = systemProvider.getEnv(envVarName); + + assertFalse("Expected environment variable NON_EXISTING_ENV_VAR to not be present", result.isPresent()); + } + + @Test + public void getPropertyWithExistingProperty() { + // Assuming 'java.version' is an existing system property + String propertyName = "java.version"; + Optional result = systemProvider.getProperty(propertyName); + + assertTrue("Expected system property java.version to be present", result.isPresent()); + } + + @Test + public void getPropertyWithNonExistingProperty() { + String propertyName = "NON_EXISTING_SYSTEM_PROPERTY"; + Optional result = systemProvider.getProperty(propertyName); + + assertFalse("Expected system property NON_EXISTING_SYSTEM_PROPERTY to not be present", result.isPresent()); + } +} diff --git a/runtime/citrus-junit/src/main/java/org/citrusframework/junit/JUnit4CitrusSupport.java b/runtime/citrus-junit/src/main/java/org/citrusframework/junit/JUnit4CitrusSupport.java index e526bf222f..491a9bce93 100644 --- a/runtime/citrus-junit/src/main/java/org/citrusframework/junit/JUnit4CitrusSupport.java +++ b/runtime/citrus-junit/src/main/java/org/citrusframework/junit/JUnit4CitrusSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2016 the original author or authors. + * Copyright 2006-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -114,8 +114,8 @@ protected TestLoader createTestLoader(String testName, String packageName, Strin testLoader.setTestName(testName); testLoader.setPackageName(packageName); - if (testLoader instanceof TestSourceAware) { - ((TestSourceAware) testLoader).setSource(source); + if (testLoader instanceof TestSourceAware testSourceAware) { + testSourceAware.setSource(source); } return testLoader; diff --git a/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusExtensionHelper.java b/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusExtensionHelper.java index 3cd5d6eb79..91504e4fdb 100644 --- a/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusExtensionHelper.java +++ b/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusExtensionHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -45,6 +45,8 @@ import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; +import static java.lang.String.format; + /** * @author Christoph Deppisch */ @@ -133,7 +135,7 @@ public static TestLoader getTestLoader(ExtensionContext extensionContext) { public static TestCase getTestCase(ExtensionContext extensionContext) { ObjectHelper.assertNotNull(extensionContext, "ExtensionContext must not be null"); return extensionContext.getRoot().getStore(CitrusExtension.NAMESPACE).getOrComputeIfAbsent(getBaseKey(extensionContext) + TestCase.class.getSimpleName(), key -> { - if (CitrusExtensionHelper.isTestSourceMethod(extensionContext.getRequiredTestMethod())) { + if (isTestSourceMethod(extensionContext.getRequiredTestMethod())) { return getTestLoader(extensionContext).getTestCase(); } else { return getTestRunner(extensionContext).getTestCase(); @@ -158,14 +160,13 @@ public static TestLoader createTestLoader(ExtensionContext extensionContext) { } TestLoader testLoader; - if (CitrusExtensionHelper.isTestSourceMethod(method)) { + if (isTestSourceMethod(method)) { CitrusTestSource citrusTestAnnotation = method.getAnnotation(CitrusTestSource.class); testLoader = TestLoader.lookup(citrusTestAnnotation.type()) - .orElseThrow(() -> new CitrusRuntimeException(String.format("Missing test loader for type '%s'", citrusTestAnnotation.type()))); + .orElseThrow(() -> new CitrusRuntimeException(format("Missing test loader for type '%s'", citrusTestAnnotation.type()))); - configure(testLoader, extensionContext, method, citrusTestAnnotation.name(), - citrusTestAnnotation.packageName(), citrusTestAnnotation.packageScan(), citrusTestAnnotation.sources()); + configure(testLoader, extensionContext, method, citrusTestAnnotation.name(), citrusTestAnnotation.packageName(), citrusTestAnnotation.packageScan(), citrusTestAnnotation.sources()); } else { testLoader = new DefaultTestLoader(); configure(testLoader, extensionContext, method, new String[]{}, null, new String[]{}, new String[]{}); @@ -222,7 +223,7 @@ public static void setCitrus(Citrus citrus, ExtensionContext extensionContext) { } public static Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { - TestCaseRunner runner = CitrusExtensionHelper.getTestRunner(extensionContext); + TestCaseRunner runner = getTestRunner(extensionContext); if (TestCaseRunner.class.isAssignableFrom(parameterContext.getParameter().getType())) { return runner; } else if (GherkinTestActionRunner.class.isAssignableFrom(parameterContext.getParameter().getType())) { @@ -230,10 +231,10 @@ public static Object resolveParameter(ParameterContext parameterContext, Extensi } else if (TestActionRunner.class.isAssignableFrom(parameterContext.getParameter().getType())) { return runner; } else if (TestContext.class.isAssignableFrom(parameterContext.getParameter().getType())) { - return CitrusExtensionHelper.getTestContext(extensionContext); + return getTestContext(extensionContext); } - throw new CitrusRuntimeException(String.format("Failed to resolve parameter %s", parameterContext.getParameter())); + throw new CitrusRuntimeException(format("Failed to resolve parameter %s", parameterContext.getParameter())); } /** @@ -258,8 +259,7 @@ public static boolean requiresCitrus(ExtensionContext extensionContext) { * @param packagesToScan * @param sources */ - private static void configure(TestLoader testLoader, ExtensionContext extensionContext, Method method, - String[] methodNames, String methodPackageName, String[] packagesToScan, String[] sources) { + private static void configure(TestLoader testLoader, ExtensionContext extensionContext, Method method, String[] methodNames, String methodPackageName, String[] packagesToScan, String[] sources) { String testName = extensionContext.getRequiredTestClass().getSimpleName(); String packageName = method.getDeclaringClass().getPackage().getName(); String source = null; @@ -296,7 +296,7 @@ private static void configure(TestLoader testLoader, ExtensionContext extensionC testLoader.setTestName(testName); testLoader.setPackageName(packageName); - CitrusAnnotations.injectAll(testLoader, CitrusExtensionHelper.getCitrus(extensionContext)); + CitrusAnnotations.injectAll(testLoader, getCitrus(extensionContext)); if (testLoader instanceof TestSourceAware) { ((TestSourceAware) testLoader).setSource(source); diff --git a/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusTestFactorySupport.java b/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusTestFactorySupport.java index 9bb6fa8408..ef895e5f26 100644 --- a/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusTestFactorySupport.java +++ b/runtime/citrus-junit5/src/main/java/org/citrusframework/junit/jupiter/CitrusTestFactorySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2022-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,6 +19,13 @@ package org.citrusframework.junit.jupiter; +import org.citrusframework.CitrusInstanceManager; +import org.citrusframework.CitrusSettings; +import org.citrusframework.common.TestLoader; +import org.citrusframework.exceptions.CitrusRuntimeException; +import org.citrusframework.spi.ClasspathResourceResolver; +import org.junit.jupiter.api.DynamicTest; + import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -28,14 +35,14 @@ import java.util.function.Consumer; import java.util.stream.Stream; -import org.citrusframework.CitrusInstanceManager; -import org.citrusframework.CitrusSettings; -import org.citrusframework.annotations.CitrusAnnotations; -import org.citrusframework.common.TestLoader; -import org.citrusframework.exceptions.CitrusRuntimeException; -import org.citrusframework.spi.ClasspathResourceResolver; -import org.citrusframework.util.FileUtils; -import org.junit.jupiter.api.DynamicTest; +import static java.lang.String.format; +import static java.lang.String.valueOf; +import static org.citrusframework.annotations.CitrusAnnotations.injectAll; +import static org.citrusframework.common.TestLoader.GROOVY; +import static org.citrusframework.common.TestLoader.SPRING; +import static org.citrusframework.common.TestLoader.XML; +import static org.citrusframework.common.TestLoader.lookup; +import static org.citrusframework.util.FileUtils.getBaseName; /** * @author Christoph Deppisch @@ -55,21 +62,23 @@ public static CitrusTestFactorySupport factory(String type) { } public static CitrusTestFactorySupport xml() { - return factory(TestLoader.XML); + return factory(XML); } public static CitrusTestFactorySupport groovy() { - return factory(TestLoader.GROOVY); + return factory(GROOVY); } public static CitrusTestFactorySupport springXml() { - return factory(TestLoader.SPRING); + return factory(SPRING); } /** - * Creates stream of dynamic tests based on package scan. Scans package for all Xml test case files and creates dynamic test instance for it. - * @param packagesToScan - * @return + * Creates stream of dynamic tests based on package scan. Scans package for all test case files and creates dynamic + * test instance for it. + * + * @param packagesToScan package patterns to scan. + * @return loaded test cases */ public Stream packageScan(String ... packagesToScan) { List tests = new ArrayList<>(); @@ -87,7 +96,7 @@ public Stream packageScan(String ... packagesToScan) { filePath = filePath.substring(filePath.indexOf(packageScan.replace('.', File.separatorChar))); - String testName = FileUtils.getBaseName(String.valueOf(fileResource.getFileName())); + String testName = getBaseName(valueOf(fileResource.getFileName())); TestLoader testLoader = createTestLoader(testName, filePath); tests.add(DynamicTest.dynamicTest(testName, () -> handler.accept(testLoader))); @@ -139,15 +148,15 @@ public DynamicTest dynamicTest(String packageName, String testName) { } private TestLoader createTestLoader(String testName, String packageName) { - TestLoader testLoader = TestLoader.lookup(type) - .orElseThrow(() -> new CitrusRuntimeException(String.format("Missing '%s' test loader in project classpath - " + + TestLoader testLoader = lookup(type) + .orElseThrow(() -> new CitrusRuntimeException(format("Missing '%s' test loader in project classpath - " + "please add proper Citrus module to the project", type))); testLoader.setTestClass(DynamicTest.class); testLoader.setTestName(testName); testLoader.setPackageName(packageName); - CitrusAnnotations.injectAll(testLoader, CitrusInstanceManager.getOrDefault()); + injectAll(testLoader, CitrusInstanceManager.getOrDefault()); return testLoader; } diff --git a/runtime/citrus-junit5/src/test/java/org/citrusframework/junit/jupiter/integration/spring/SpringBeanXml_IT.java b/runtime/citrus-junit5/src/test/java/org/citrusframework/junit/jupiter/integration/spring/SpringBeanXml_IT.java index 959604c072..569f124c25 100644 --- a/runtime/citrus-junit5/src/test/java/org/citrusframework/junit/jupiter/integration/spring/SpringBeanXml_IT.java +++ b/runtime/citrus-junit5/src/test/java/org/citrusframework/junit/jupiter/integration/spring/SpringBeanXml_IT.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,12 +19,9 @@ package org.citrusframework.junit.jupiter.integration.spring; -import java.util.stream.Stream; - import org.citrusframework.annotations.CitrusTestSource; import org.citrusframework.common.TestLoader; import org.citrusframework.config.CitrusSpringConfig; -import org.citrusframework.junit.jupiter.CitrusTestFactorySupport; import org.citrusframework.junit.jupiter.spring.CitrusSpringSupport; import org.citrusframework.junit.jupiter.spring.CitrusSpringXmlTestFactory; import org.junit.jupiter.api.DisplayName; @@ -32,6 +29,10 @@ import org.junit.jupiter.api.Test; import org.springframework.test.context.ContextConfiguration; +import java.util.stream.Stream; + +import static org.citrusframework.junit.jupiter.CitrusTestFactorySupport.springXml; + /** * @author Christoph Deppisch */ @@ -42,35 +43,35 @@ class SpringBeanXml_IT { @Test @DisplayName("SpringBeanXml_IT") @CitrusTestSource(type = TestLoader.SPRING, name = "SpringBeanXml_IT") - void SpringBeanXml_0_IT() { + void springBeanXml_0_IT() { } @Test @CitrusTestSource(type = TestLoader.GROOVY, name = "echo.test", packageName = "org.citrusframework.junit.jupiter.simple") - void SpringGroovy_IT() { + void springGroovy_IT() { } @Test @CitrusTestSource(type = TestLoader.SPRING, name = "SampleIT") - void SpringBeanXml_1_IT() { + void springBeanXml_1_IT() { } @CitrusSpringXmlTestFactory - Stream SpringBeanXml_2_IT() { + Stream springBeanXml_2_IT() { return Stream.of( - CitrusTestFactorySupport.springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "EchoActionIT"), - CitrusTestFactorySupport.springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "FailActionIT"), - CitrusTestFactorySupport.springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "CreateVariablesIT") + springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "EchoActionIT"), + springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "FailActionIT"), + springXml().dynamicTest("org.citrusframework.junit.jupiter.integration.actions", "CreateVariablesIT") ); } @CitrusSpringXmlTestFactory - Stream SpringBeanXml_3_IT() { - return CitrusTestFactorySupport.springXml().packageScan("org.citrusframework.junit.jupiter.simple"); + Stream springBeanXml_3_IT() { + return springXml().packageScan("org.citrusframework.junit.jupiter.simple"); } @Test @CitrusTestSource(type = TestLoader.SPRING, sources = "classpath:org/citrusframework/junit/jupiter/integration/spring/SampleIT.xml") - void SpringBeanXml_4_IT() { + void springBeanXml_4_IT() { } } diff --git a/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGCitrusSupport.java b/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGCitrusSupport.java index 641d8531b4..0db11c4ade 100644 --- a/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGCitrusSupport.java +++ b/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGCitrusSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,10 +19,6 @@ package org.citrusframework.testng; -import java.lang.reflect.Method; -import java.util.Date; -import java.util.List; - import org.citrusframework.Citrus; import org.citrusframework.CitrusContext; import org.citrusframework.GherkinTestActionRunner; @@ -50,6 +46,16 @@ import org.testng.annotations.BeforeSuite; import org.testng.annotations.Listeners; +import java.lang.reflect.Method; +import java.util.Date; +import java.util.List; + +import static java.lang.String.format; +import static org.citrusframework.testng.TestNGHelper.BUILDER_ATTRIBUTE; +import static org.citrusframework.testng.TestNGHelper.createMethodTestLoaders; +import static org.citrusframework.testng.TestNGHelper.createTestCaseRunner; +import static org.citrusframework.testng.TestNGHelper.invokeTestMethod; + /** * Basic Citrus TestNG support base class automatically handles test case runner creation. Also provides method parameter resolution * and resource injection. Users can just extend this class and make use of the action runner methods provided in {@link org.citrusframework.TestActionRunner} @@ -75,7 +81,7 @@ public void run(final IHookCallBack callBack, ITestResult testResult) { return; } - List methodTestLoaders = TestNGHelper.createMethodTestLoaders(method, this::createTestLoader); + List methodTestLoaders = createMethodTestLoaders(method, this::createTestLoader); if (method.getAnnotation(CitrusTest.class) != null || method.getAnnotation(CitrusTestSource.class) != null) { try { @@ -113,9 +119,9 @@ protected void run(ITestResult testResult, Method method, List metho TestContext ctx = prepareTestContext(citrus.getCitrusContext().createTestContext()); - TestCaseRunner runner = TestNGHelper.createTestCaseRunner(this, method, ctx); + TestCaseRunner runner = createTestCaseRunner(this, method, ctx); runner.groups(testResult.getMethod().getGroups()); - testResult.setAttribute(TestNGHelper.BUILDER_ATTRIBUTE, runner); + testResult.setAttribute(BUILDER_ATTRIBUTE, runner); delegate = runner; @@ -125,10 +131,10 @@ protected void run(ITestResult testResult, Method method, List metho if (method.getAnnotation(CitrusTestSource.class) != null && !methodTestLoaders.isEmpty()) { testLoader = methodTestLoaders.get(invocationCount % methodTestLoaders.size()); - if (testLoader instanceof TestSourceAware) { + if (testLoader instanceof TestSourceAware testSourceAware) { String[] sources = method.getAnnotation(CitrusTestSource.class).sources(); if (sources.length > 0) { - ((TestSourceAware) testLoader).setSource(sources[0]); + testSourceAware.setSource(sources[0]); } } } else { @@ -137,14 +143,14 @@ protected void run(ITestResult testResult, Method method, List metho CitrusAnnotations.injectAll(testLoader, citrus, ctx); CitrusAnnotations.injectTestRunner(testLoader, runner); - testLoader.configureTestCase(t -> { - if (t instanceof TestGroupAware) { - ((TestGroupAware) t).setGroups(testResult.getMethod().getGroups()); + testLoader.configureTestCase(testCase -> { + if (testCase instanceof TestGroupAware testGroupAware) { + testGroupAware.setGroups(testResult.getMethod().getGroups()); } }); - TestNGHelper.invokeTestMethod(this, testResult, method, testLoader, ctx, invocationCount); + invokeTestMethod(this, testResult, method, testLoader, ctx, invocationCount); } finally { - testResult.removeAttribute(TestNGHelper.BUILDER_ATTRIBUTE); + testResult.removeAttribute(BUILDER_ATTRIBUTE); } } @@ -233,7 +239,7 @@ protected TestContext prepareTestContext(final TestContext testContext) { */ protected TestLoader createTestLoader(String testName, String packageName, String type) { TestLoader testLoader = TestLoader.lookup(type) - .orElseThrow(() -> new CitrusRuntimeException(String.format("Missing test loader for type '%s'", type))); + .orElseThrow(() -> new CitrusRuntimeException(format("Missing test loader for type '%s'", type))); testLoader.setTestClass(getClass()); testLoader.setTestName(testName); diff --git a/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGHelper.java b/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGHelper.java index 80e67bfc14..adccd431b8 100644 --- a/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGHelper.java +++ b/runtime/citrus-testng/src/main/java/org/citrusframework/testng/TestNGHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -176,8 +176,8 @@ private static List createMethodTestLoaders(Method method, TestLoader testLoader = provider.createTestLoader(FileUtils.getBaseName(FileUtils.getFileName(file.getLocation())), sourceFilePackageName.replace("/","."), type); - if (testLoader instanceof TestSourceAware) { - ((TestSourceAware) testLoader).setSource(source); + if (testLoader instanceof TestSourceAware testSourceAware) { + testSourceAware.setSource(source); methodTestLoaders.add(testLoader); } else { logger.warn(String.format("Test loader %s is not able to handle test source %s", testLoader.getClass(), source)); diff --git a/runtime/citrus-xml/src/main/java/org/citrusframework/xml/XmlTestLoader.java b/runtime/citrus-xml/src/main/java/org/citrusframework/xml/XmlTestLoader.java index b766ba7e78..b797a075d0 100644 --- a/runtime/citrus-xml/src/main/java/org/citrusframework/xml/XmlTestLoader.java +++ b/runtime/citrus-xml/src/main/java/org/citrusframework/xml/XmlTestLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 the original author or authors. + * Copyright 2021-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -19,13 +19,12 @@ package org.citrusframework.xml; -import java.io.IOException; -import java.util.regex.Pattern; - import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBException; import org.citrusframework.DefaultTestCaseRunner; +import org.citrusframework.TestCase; import org.citrusframework.common.DefaultTestLoader; +import org.citrusframework.common.TestLoaderAndExecutor; import org.citrusframework.common.TestSourceAware; import org.citrusframework.exceptions.CitrusRuntimeException; import org.citrusframework.spi.ReferenceResolverAware; @@ -34,6 +33,9 @@ import org.citrusframework.util.FileUtils; import org.citrusframework.util.StringUtils; +import java.io.IOException; +import java.util.regex.Pattern; + /** * Loads test case as Spring bean from XML application context file. Loader holds application context file * for test case and a parent application context. At runtime this class loads the Spring application context and gets @@ -41,7 +43,7 @@ * * @author Christoph Deppisch */ -public class XmlTestLoader extends DefaultTestLoader implements TestSourceAware { +public class XmlTestLoader extends DefaultTestLoader implements TestLoaderAndExecutor, TestSourceAware { private String source; @@ -57,7 +59,7 @@ public XmlTestLoader() { try { jaxbContext = JAXBContext.newInstance("org.citrusframework.xml"); } catch (JAXBException e) { - throw new CitrusRuntimeException("Failed to create XMLTestLoader instance", e); + throw new CitrusRuntimeException("Failed to create XMLTestLoader instance!", e); } } @@ -75,39 +77,53 @@ public XmlTestLoader(Class testClass, String testName, String packageName) { @Override public void doLoad() { Resource xmlSource = FileUtils.getFileResource(getSource()); + testCase = loadTestCase(xmlSource); + testCase = executeTestCase(testCase); + } + @Override + public TestCase loadTestCase(Resource resource) { try { - testCase = jaxbContext.createUnmarshaller() - .unmarshal(new StringSource(applyNamespace(FileUtils.readToString(xmlSource))), XmlTestCase.class) - .getValue() - .getTestCase(); - if (runner instanceof DefaultTestCaseRunner) { - ((DefaultTestCaseRunner) runner).setTestCase(testCase); + TestCase loadedTestCase = jaxbContext.createUnmarshaller() + .unmarshal(new StringSource(applyNamespace(FileUtils.readToString(resource))), XmlTestCase.class) + .getValue() + .getTestCase(); + + if (runner instanceof DefaultTestCaseRunner defaultTestCaseRunner) { + defaultTestCaseRunner.setTestCase(loadedTestCase); } - testCase.getActionBuilders().stream() + loadedTestCase.getActionBuilders().stream() .filter(action -> ReferenceResolverAware.class.isAssignableFrom(action.getClass())) .map(ReferenceResolverAware.class::cast) .forEach(action -> action.setReferenceResolver(context.getReferenceResolver())); - configurer.forEach(handler -> handler.accept(testCase)); - citrus.run(testCase, context); - handler.forEach(handler -> handler.accept(testCase)); - } catch (JAXBException | IOException e) { + return loadedTestCase; + } catch (IOException | JAXBException e) { throw citrusContext.getTestContextFactory().getObject() .handleError(testName, packageName, "Failed to load XML test with name '" + testName + "'", e); } } + @Override + public TestCase executeTestCase(TestCase testCaseToExecute) { + configurer.forEach(handler -> handler.accept(testCaseToExecute)); + citrus.run(testCaseToExecute, context); + handler.forEach(handler -> handler.accept(testCaseToExecute)); + return testCaseToExecute; + } + + @Override + public void initialize() { + super.initializeTestRunner(); + } + /** - * Automatically applies Citrus test namespace if non is set on the root element. + * Sets custom Spring application context file for XML test case. */ - public static String applyNamespace(String xmlSource) { - if (NAMESPACE_IS_SET.matcher(xmlSource).matches()) { - return xmlSource; - } - - return xmlSource.replace(" lookup = lookup(XML); + assertTrue(lookup.isPresent()); + assertEquals(XmlTestLoader.class, lookup.get().getClass()); + } +} diff --git a/runtime/citrus-xml/src/test/java/org/citrusframework/xml/TestLoaderTest.java b/runtime/citrus-xml/src/test/java/org/citrusframework/xml/TestLoaderTest.java index 37e1b46432..821d7ca0ac 100644 --- a/runtime/citrus-xml/src/test/java/org/citrusframework/xml/TestLoaderTest.java +++ b/runtime/citrus-xml/src/test/java/org/citrusframework/xml/TestLoaderTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2022 the original author or authors. + * Copyright 2022-2024 the original author or authors. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -20,9 +20,15 @@ package org.citrusframework.xml; import org.citrusframework.common.TestLoader; -import org.testng.Assert; import org.testng.annotations.Test; +import java.util.Optional; + +import static org.citrusframework.common.TestLoader.XML; +import static org.citrusframework.common.TestLoader.lookup; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + /** * @author Christoph Deppisch */ @@ -30,8 +36,10 @@ public class TestLoaderTest { @Test public void shouldLookupTestLoader() { - Assert.assertTrue(TestLoader.lookup().containsKey(TestLoader.XML)); - Assert.assertTrue(TestLoader.lookup(TestLoader.XML).isPresent()); - Assert.assertEquals(TestLoader.lookup(TestLoader.XML).get().getClass(), XmlTestLoader.class); + assertTrue(lookup().containsKey(XML)); + + Optional lookup = lookup(XML); + assertTrue(lookup.isPresent()); + assertEquals(XmlTestLoader.class, lookup.get().getClass()); } } diff --git a/runtime/citrus-xml/src/test/resources/org/citrusframework/integration/sample-test.xml b/runtime/citrus-xml/src/test/resources/org/citrusframework/integration/sample-test.xml index 2b01bf4bc1..f0fcd2122c 100644 --- a/runtime/citrus-xml/src/test/resources/org/citrusframework/integration/sample-test.xml +++ b/runtime/citrus-xml/src/test/resources/org/citrusframework/integration/sample-test.xml @@ -1,5 +1,5 @@