diff --git a/CHANGELOG.md b/CHANGELOG.md index 785b949..c2bca3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Back to [Readme](README.md). +## [1.11.0] - 2023-12-04 + +### Added + +* New way to only generate features without runners by specifying `0`. + +### Changed + +* Default value of `` was changed from `0` to `-1`: + * `-1` means that the number generated runners should be equal to the number generated scenarios. + * `0` means that no runners should be generated at all. +* Java 11 requirement + +### Changed + +* Updated dependencies + ## [1.10.0] - 2023-06-27 ### Added @@ -330,6 +347,7 @@ Back to [Readme](README.md). Initial project version on GitHub and Maven Central. +[1.11.0]: https://github.com/trivago/cucable-plugin/compare/1.9.0...1.10.0 [1.10.0]: https://github.com/trivago/cucable-plugin/compare/1.9.0...1.10.0 [1.9.0]: https://github.com/trivago/cucable-plugin/compare/1.8.0...1.9.0 [1.8.0]: https://github.com/trivago/cucable-plugin/compare/1.7.2...1.8.0 diff --git a/README.md b/README.md index b747785..3b0e33d 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,21 @@ _Run Cucumber Scenarios in Parallel with Maven_ - [Cucable Maven Plugin](#cucable-maven-plugin) - [Cucumber 4](#cucumber-4) - [Cucumber 5 and higher](#cucumber-5-and-higher) + - [JUnit 5](#junit-5) - [Repository Structure](#repository-structure) - [Changelog](#changelog) - [Maven dependency](#maven-dependency) - [How it works](#how-it-works) - - [Template placeholders](#template-placeholders) + - [Runner template placeholders](#runner-template-placeholders) - [[CUCABLE:RUNNER]](#cucablerunner) - [[CUCABLE:FEATURE]](#cucablefeature) - [Custom template placeholders - [CUCABLE:CUSTOM:xxx]](#custom-template-placeholders---cucablecustomxxx) - [One runner per generated scenario](#one-runner-per-generated-scenario) - [One runner per group of generated scenarios](#one-runner-per-group-of-generated-scenarios) + - [No runners](#no-runners) - [Typical workflow](#typical-workflow) - [1. Generation of runners and features](#1-generation-of-runners-and-features) - - [Required Parameters](#required-parameters) + - [Parameters](#parameters) - [sourceRunnerTemplateFile](#sourcerunnertemplatefile) - [Using a java file as a runner template](#using-a-java-file-as-a-runner-template) - [Using a text file as a runner template](#using-a-text-file-as-a-runner-template) @@ -33,7 +35,6 @@ _Run Cucumber Scenarios in Parallel with Maven_ - [Combining different feature sources](#combining-different-feature-sources) - [generatedFeatureDirectory](#generatedfeaturedirectory) - [generatedRunnerDirectory](#generatedrunnerdirectory) - - [Optional Parameters](#optional-parameters) - [numberOfTestRuns](#numberoftestruns) - [includeScenarioTags](#includescenariotags) - [parallelizationMode](#parallelizationmode) @@ -86,6 +87,10 @@ Even though Cucumber 4 supports basic parallel runs, Cucable has more options th * Cucumber starting with version 5 (using testng or junit 5) can natively run features and scenarios in parallel. Cucable __can__ be used but does not __have__ to be. +## JUnit 5 + +When using the JUnit 5 platform, Cucable can still help parallelize scenarios more fine-grained and with more options than the standard JUnit and Cucumber properties. + ## Repository Structure * [plugin-code](plugin-code) contains the full plugin source code. @@ -111,9 +116,12 @@ All changes are documented in the [full changelog](CHANGELOG.md). * Each generated feature file includes a single scenario * After this, the runner classes for those generated features are generated based on a provided template file, either * one runner per generated "single scenario" feature file or - * one runner per group of "single scenario" feature files + * one runner per group of "single scenario" feature files or + * no runners at all (not needed if your tests are run as unit tests with JUnit 5 or TestNG) + +## Runner template placeholders -## Template placeholders +__Note:__ If you don't need runner classes to be generated, you can skip this section. ### [CUCABLE:RUNNER] @@ -177,7 +185,7 @@ public class [CUCABLE:RUNNER] { } -**Note:** The custom placeholder names are case sensitive! +**Note:** The custom placeholder names are case-sensitive! ## One runner per generated scenario @@ -195,6 +203,12 @@ This means that it will only generate the specified number of runners (or featur ![Multi feature runner generation](documentation/img/cucable_flow_multi_runner.png) +## No runners + +If you set `desiredNumberOfRunners` to `0`, this means that Cucable will not generate runner classes at all. In this case, you do not need to set these properties: +* `sourceRunnerTemplateFile` (as you do not need a template file) +* `generatedRunnerDirectory` (as no runners will be generated) + # Typical workflow 1. Generation of runners and features @@ -237,10 +251,12 @@ The following sections break down the above steps. ``` -### Required Parameters +### Parameters #### sourceRunnerTemplateFile +__Note:__ This is only needed, when you want to generate runner classes! + The specified file will be used to generate runner classes for the generated feature file that can be run using [Maven Failsafe](http://maven.apache.org/surefire/maven-failsafe-plugin/). This can be either a text file or a Java class. The difference can be seen below: @@ -362,6 +378,8 @@ If you want to use a directory inside Maven's target folder, [check this example #### generatedRunnerDirectory +__Note:__ This is only needed, when you want to generate runner classes! + The path where the __generated__ runner classes should be located (e.g. _src/test/java/parallel/runners_). **Note:** This directory should be located under a valid source folder to be included as a test source by Maven. @@ -369,8 +387,6 @@ If you want to use a directory inside Maven's target folder, [check this example **Caution:** This directory will be wiped prior to the runner file generation! -### Optional Parameters - #### numberOfTestRuns Optional number of test runs. This can be used if specific scenarios should be run multiple times. @@ -449,7 +465,7 @@ This can be configured by passing the `logLevel` property: If you set this options, all generated features will be distributed to a fixed set of runner classes. This means that one runner can potentially run multiple features in sequence. -If this option is not set, its default value is `0` which basically means "Generate a dedicated runner for every generated feature". +If this option is not set, its default value is `-1` which basically means "Generate a dedicated runner for every generated feature". __Note:__ This cannot be used together with `desiredNumberOfFeaturesPerRunner`! diff --git a/example-project/pom.xml b/example-project/pom.xml index a087e63..41ccbbf 100644 --- a/example-project/pom.xml +++ b/example-project/pom.xml @@ -7,20 +7,21 @@ com.trivago.rta cucable-test-project - 1.10.0 + 1.11.0 jar UTF-8 UTF-8 - 3.0.0-M3 - 3.0.0 - 6.9.0 - 3.7.0 + 3.1.2 + 3.4.0 + 7.11.1 + 3.11.0 3.1.2 ${project.build.directory}/parallel/runners ${project.build.directory}/parallel/features + 3.3.1 @@ -53,7 +54,7 @@ - src/test/java/some/template/CucableJavaTemplate.java + src/test/java/some/template/CucableTemplate.java @@ -73,7 +74,7 @@ - + src/test/resources/features/testfeature/MyTest1.feature:8:19 @@ -104,7 +105,7 @@ - + @@ -154,13 +155,17 @@ true + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + org.apache.maven.plugins maven-compiler-plugin ${maven.compiler.plugin.version} - 8 - 8 + 11 diff --git a/example-project/src/test/java/some/template/CucableJavaTemplate.java b/example-project/src/test/java/some/template/CucableTemplate.java similarity index 86% rename from example-project/src/test/java/some/template/CucableJavaTemplate.java rename to example-project/src/test/java/some/template/CucableTemplate.java index 26dcdd3..2f3558c 100644 --- a/example-project/src/test/java/some/template/CucableJavaTemplate.java +++ b/example-project/src/test/java/some/template/CucableTemplate.java @@ -7,10 +7,9 @@ @RunWith(Cucumber.class) @CucumberOptions( glue = "steps", - strict = true, features = {"target/parallel/features/[CUCABLE:FEATURE].feature"}, plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"} ) -public class CucableJavaTemplate { +public class CucableTemplate { // [CUCABLE:CUSTOM:comment] } \ No newline at end of file diff --git a/example-project/src/test/resources/cucable.template b/example-project/src/test/resources/cucable.template index 5d989fd..bf00869 100644 --- a/example-project/src/test/resources/cucable.template +++ b/example-project/src/test/resources/cucable.template @@ -9,6 +9,6 @@ import org.junit.runner.RunWith; features = {"target/parallel/features/[CUCABLE:FEATURE].feature"}, plugin = {"json:target/cucumber-report/[CUCABLE:RUNNER].json"} ) -public class CucableJavaTemplate { +public class CucableTemplate { // [CUCABLE:CUSTOM:comment] } \ No newline at end of file diff --git a/makefile b/makefile index 26676b4..11285c4 100644 --- a/makefile +++ b/makefile @@ -1,4 +1,12 @@ -build-and-test: +help: ## Show this help. + @grep -hE '^[A-Za-z0-9_ \-]*?:.*##.*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: help + +build-and-test: ## Build the plugin and run demo tests mvn clean install - mvn verify -f=examples/maven-example - open examples/maven-example/target/cluecumber-report/index.html \ No newline at end of file + mvn verify -f=examples-project/pom.xml -ntp + open example-project/target/cluecumber-report/index.html + +show-versions: ## Show most recent dependency versions + mvn versions:display-dependency-updates -ntp -f=plugin-code/pom.xml +.PHONY: show-versions \ No newline at end of file diff --git a/plugin-code/pom.xml b/plugin-code/pom.xml index 9029fae..4ae1c90 100644 --- a/plugin-code/pom.xml +++ b/plugin-code/pom.xml @@ -6,7 +6,7 @@ com.trivago.rta cucable-plugin - 1.10.0 + 1.11.0 https://github.com/trivago/cucable-plugin Cucable Maven Plugin @@ -17,14 +17,14 @@ trivago N.V. - http://www.trivago.de + https://www.trivago.com Benjamin Bischoff trivago N.V. - http://www.trivago.de + https://www.trivago.com Test Automation Engineer Knowledge Lead Test Automation @@ -70,21 +70,20 @@ 3.3.0 3.11.0 3.3.0 - 0.8.10 - 2.1.0 - 3.6.0 + 0.8.11 + 2.1.1 + 3.10.2 3.3.0 - 1.8 - 1.8 - 8 5.2.0 - 5.0.1 - 3.12.0 + 6.0.0 + 3.14.0 - 3.6.28 - 5.7.0 + 4.11.0 + 5.10.1 0.9.1 - 3.5.0 + 4.0.0 + 3.11.0 + 3.3.1 @@ -124,13 +123,17 @@ + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + org.apache.maven.plugins maven-compiler-plugin ${maven.compiler.plugin.version} - 8 - 8 + 11 diff --git a/plugin-code/src/main/java/com/trivago/CucablePlugin.java b/plugin-code/src/main/java/com/trivago/CucablePlugin.java index 300508f..af301f5 100644 --- a/plugin-code/src/main/java/com/trivago/CucablePlugin.java +++ b/plugin-code/src/main/java/com/trivago/CucablePlugin.java @@ -45,13 +45,13 @@ /** * The complete path to the runner template file. */ - @Parameter(property = "parallel.sourceRunnerTemplateFile", required = true) + @Parameter(property = "parallel.sourceRunnerTemplateFile", required = false, defaultValue = "") private String sourceRunnerTemplateFile; /** * The path where the generated runner classes should be created. */ - @Parameter(property = "parallel.generatedRunnerDirectory", required = true) + @Parameter(property = "parallel.generatedRunnerDirectory", required = false, defaultValue = "") private String generatedRunnerDirectory; /** @@ -90,7 +90,7 @@ /** * Optional desired number of test runners that each run multiple features in sequence. */ - @Parameter(property = "parallel.desiredNumberOfRunners", defaultValue = "0") + @Parameter(property = "parallel.desiredNumberOfRunners", defaultValue = "-1") private int desiredNumberOfRunners; /** diff --git a/plugin-code/src/main/java/com/trivago/features/FeatureFileConverter.java b/plugin-code/src/main/java/com/trivago/features/FeatureFileConverter.java index e9c87d7..0e6a35e 100644 --- a/plugin-code/src/main/java/com/trivago/features/FeatureFileConverter.java +++ b/plugin-code/src/main/java/com/trivago/features/FeatureFileConverter.java @@ -325,8 +325,10 @@ private int generateRunnerClassesWithDesiredNumberOfRunners(final List g int targetRunnerNumber = numberOfDesiredRunners; List scenarioNames = propertyManager.getScenarioNames(); - if (targetRunnerNumber == 0) { + if (targetRunnerNumber == -1) { targetRunnerNumber = generatedFeatureNames.size(); + } else if (targetRunnerNumber == 0) { + return 0; } List> generatedFeatureNamesPerRunner = new ArrayList<>(targetRunnerNumber); @@ -367,7 +369,7 @@ private int generateRunnerClassesWithDesiredNumberOfRunners(final List g int runnerFileCounter = 0; for (List generatedFeatureNamesForSingleRunner : generatedFeatureNamesPerRunner) { - if (generatedFeatureNamesForSingleRunner.size() > 0) { + if (!generatedFeatureNamesForSingleRunner.isEmpty()) { generateRunnerClass(generatedFeatureNamesForSingleRunner); runnerFileCounter++; } diff --git a/plugin-code/src/main/java/com/trivago/files/FileSystemManager.java b/plugin-code/src/main/java/com/trivago/files/FileSystemManager.java index 4c9b157..1ef9a39 100644 --- a/plugin-code/src/main/java/com/trivago/files/FileSystemManager.java +++ b/plugin-code/src/main/java/com/trivago/files/FileSystemManager.java @@ -28,13 +28,14 @@ import javax.inject.Singleton; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; @Singleton public class FileSystemManager { @@ -91,8 +92,8 @@ public List getPathsFromCucableFeature(final CucableFeature cucableFeature */ public List getFilesWithExtension(final String sourceFeatureDirectory, final String extension) throws CucablePluginException { - try { - return Files.walk(Paths.get(sourceFeatureDirectory)) + try (Stream paths = Files.walk(Paths.get(sourceFeatureDirectory))) { + return paths .filter(Files::isRegularFile) .filter(p -> p.toString().endsWith("." + extension)) .collect(Collectors.toList()); @@ -109,8 +110,10 @@ public void prepareGeneratedFeatureAndRunnerDirectories(final String runnerDir, createDirIfNotExists(featureDir); removeFilesFromPath(featureDir, "feature"); - createDirIfNotExists(runnerDir); - removeFilesFromPath(runnerDir, "java"); + if (runnerDir != null && !runnerDir.isEmpty()) { + createDirIfNotExists(runnerDir); + removeFilesFromPath(runnerDir, "java"); + } } /** @@ -154,8 +157,9 @@ private void removeFilesFromPath(final String path, final String fileExtension) */ public void writeContentToFile(String content, String filePath) throws FileCreationException { try { - FileUtils.fileAppend(filePath, "UTF-8", content); - } catch (IOException e) { + Path path = Paths.get(filePath); + Files.write(path, content.getBytes(StandardCharsets.UTF_8)); + } catch (Exception e) { throw new FileCreationException(filePath); } } diff --git a/plugin-code/src/main/java/com/trivago/properties/PropertyManager.java b/plugin-code/src/main/java/com/trivago/properties/PropertyManager.java index ae4df3e..ae54001 100644 --- a/plugin-code/src/main/java/com/trivago/properties/PropertyManager.java +++ b/plugin-code/src/main/java/com/trivago/properties/PropertyManager.java @@ -48,7 +48,7 @@ public class PropertyManager { private String includeScenarioTags; private ParallelizationMode parallelizationMode; private Map customPlaceholders; - private int desiredNumberOfRunners; + private int desiredNumberOfRunners = -1; private int desiredNumberOfFeaturesPerRunner; private List scenarioNames = new ArrayList<>(); @@ -71,6 +71,9 @@ public String getGeneratedRunnerDirectory() { } public void setGeneratedRunnerDirectory(final String generatedRunnerDirectory) { + if (generatedRunnerDirectory == null) { + return; + } this.generatedRunnerDirectory = generatedRunnerDirectory.replaceAll("/$", ""); } @@ -245,10 +248,16 @@ public void checkForMissingMandatoryProperties() throws CucablePluginException { List missingProperties = new ArrayList<>(); if (sourceFeatures == null || sourceFeatures.isEmpty()) { - saveMissingProperty("", "", missingProperties); + missingProperties.add(""); + } + if (desiredNumberOfRunners != 0) { + if (sourceRunnerTemplateFile == null || sourceRunnerTemplateFile.isEmpty()) { + saveMissingProperty(sourceRunnerTemplateFile, "", missingProperties); + } + if (generatedRunnerDirectory == null || generatedRunnerDirectory.isEmpty()) { + saveMissingProperty(generatedRunnerDirectory, "", missingProperties); + } } - saveMissingProperty(sourceRunnerTemplateFile, "", missingProperties); - saveMissingProperty(generatedRunnerDirectory, "", missingProperties); saveMissingProperty(generatedFeatureDirectory, "", missingProperties); if (!missingProperties.isEmpty()) { @@ -305,13 +314,19 @@ public void logProperties() { String logLine = " - " + currentOrigin; logger.info(logLine, logLevels); } + } else { + logger.info("- sourceFeatures : not specified", logLevels); } - logger.info(String.format("- sourceRunnerTemplateFile : %s", sourceRunnerTemplateFile), logLevels); + if (desiredNumberOfRunners != 0) { + logger.info(String.format("- sourceRunnerTemplateFile : %s", sourceRunnerTemplateFile), logLevels); + } logger.logInfoSeparator(DEFAULT); - logger.info(String.format("- generatedRunnerDirectory : %s", generatedRunnerDirectory), logLevels); logger.info(String.format("- generatedFeatureDirectory : %s", generatedFeatureDirectory), logLevels); + if (desiredNumberOfRunners != 0) { + logger.info(String.format("- generatedRunnerDirectory : %s", generatedRunnerDirectory), logLevels); + } logger.logInfoSeparator(DEFAULT); if (includeScenarioTags != null && !includeScenarioTags.isEmpty()) { diff --git a/plugin-code/src/test/java/com/trivago/features/FeatureFileConverterTest.java b/plugin-code/src/test/java/com/trivago/features/FeatureFileConverterTest.java index bcf172f..06e77c8 100644 --- a/plugin-code/src/test/java/com/trivago/features/FeatureFileConverterTest.java +++ b/plugin-code/src/test/java/com/trivago/features/FeatureFileConverterTest.java @@ -123,6 +123,43 @@ public void convertToSingleScenariosAndRunnersTest() throws Exception { verify(fileSystemManager, times(3)).writeContentToFile(anyString(), anyString()); } + @Test + public void convertToSingleScenariosWithoutRunnersTest() throws Exception { + String generatedFeatureDir = testFolder.getRoot().getPath().concat("/features/"); + + final String FEATURE_FILE_NAME = "FEATURE_FILE.feature"; + + propertyManager.setNumberOfTestRuns(1); + propertyManager.setDesiredNumberOfRunners(0); + propertyManager.setGeneratedFeatureDirectory(generatedFeatureDir); + + when(fileSystemManager.readContentFromFile(FEATURE_FILE_NAME)).thenReturn("TEST_CONTENT"); + + List cucableFeatures = new ArrayList<>(); + CucableFeature cucableFeature = new CucableFeature("", "", FEATURE_FILE_NAME, null); + cucableFeatures.add(cucableFeature); + + when(fileSystemManager.getPathsFromCucableFeature(cucableFeature)) + .thenReturn(Collections.singletonList(Paths.get(cucableFeature.getName()))); + + List scenarioList = new ArrayList<>(); + SingleScenario singleScenario = getSingleScenario(); + scenarioList.add(singleScenario); + when(gherkinDocumentParser.getSingleScenariosFromFeature("TEST_CONTENT", FEATURE_FILE_NAME, null)) + .thenReturn(scenarioList); + + String featureFileContent = "test"; + when(featureFileContentRenderer.getRenderedFeatureFileContent(singleScenario)).thenReturn(featureFileContent); + featureFileConverter.generateParallelizableFeatures(cucableFeatures); + + ArgumentCaptor logCaptor = ArgumentCaptor.forClass(String.class); + verify(logger, times(1)).info(logCaptor.capture(), any(CucableLogger.CucableLogLevel.class), + any(CucableLogger.CucableLogLevel.class), any(CucableLogger.CucableLogLevel.class) + ); + assertThat(logCaptor.getAllValues().get(0), is("Cucable created 1 separate feature file and 0 runners.")); + verify(fileSystemManager, times(2)).writeContentToFile(anyString(), anyString()); + } + @Test public void convertToSingleScenariosAndRunnersWithScenarioNameTest() throws Exception { String generatedFeatureDir = testFolder.getRoot().getPath().concat("/features/"); diff --git a/plugin-code/src/test/java/com/trivago/files/FileSystemManagerTest.java b/plugin-code/src/test/java/com/trivago/files/FileSystemManagerTest.java index ecfc275..75c8d63 100644 --- a/plugin-code/src/test/java/com/trivago/files/FileSystemManagerTest.java +++ b/plugin-code/src/test/java/com/trivago/files/FileSystemManagerTest.java @@ -36,7 +36,7 @@ public void prepareGeneratedFeatureAndRunnerDirsMissingFeatureDirTest() throws E fileSystemManager.prepareGeneratedFeatureAndRunnerDirectories("", ""); } - @Test(expected = PathCreationException.class) + @Test public void prepareGeneratedFeatureAndRunnerDirsMissingRunnerDirTest() throws Exception { String featurePath = testFolder.getRoot().getPath().concat("/featureDir"); fileSystemManager.prepareGeneratedFeatureAndRunnerDirectories("", featurePath); diff --git a/plugin-code/src/test/java/com/trivago/properties/PropertyManagerTest.java b/plugin-code/src/test/java/com/trivago/properties/PropertyManagerTest.java index 4239fa9..7942b4b 100644 --- a/plugin-code/src/test/java/com/trivago/properties/PropertyManagerTest.java +++ b/plugin-code/src/test/java/com/trivago/properties/PropertyManagerTest.java @@ -258,56 +258,56 @@ public void desiredNumberOfRunnersAndFeaturesPerRunnersTest() throws CucablePlug propertyManager.checkForDisallowedPropertyCombinations(); } -// @Test -// public void logMandatoryPropertiesTest() throws CucablePluginException { -// ArgumentCaptor logCaptor = ArgumentCaptor.forClass(String.class); -// propertyManager.setParallelizationMode("scenarios"); -// propertyManager.logProperties(); -// verify(logger, times(6)).info(logCaptor.capture(), any(CucableLogger.CucableLogLevel.class), -// any(CucableLogger.CucableLogLevel.class) -// ); -// List capturedLogs = logCaptor.getAllValues(); -// assertThat(capturedLogs.get(0), is("- sourceFeatures:")); -// assertThat(capturedLogs.get(1), is("- sourceRunnerTemplateFile : null")); -// assertThat(capturedLogs.get(2), is("- generatedRunnerDirectory : null")); -// assertThat(capturedLogs.get(3), is("- generatedFeatureDirectory : null")); -// assertThat(capturedLogs.get(4), is("- parallelizationMode : scenarios")); -// assertThat(capturedLogs.get(5), is("- numberOfTestRuns : 0")); -// } - -// @Test -// public void logExtendedPropertiesTest() throws CucablePluginException { -// ArgumentCaptor logCaptor = ArgumentCaptor.forClass(String.class); -// propertyManager.setIncludeScenarioTags("@include1 and @include2"); -// -// Map customPlaceholders = new HashMap<>(); -// customPlaceholders.put("key1", "value1"); -// customPlaceholders.put("key2", "value2"); -// propertyManager.setCustomPlaceholders(customPlaceholders); -// -// propertyManager.setSourceFeatures("test.feature:3"); -// propertyManager.setDesiredNumberOfRunners(2); -// propertyManager.setParallelizationMode("features"); -// -// propertyManager.logProperties(); -// -// verify(logger, times(12)).info(logCaptor.capture(), any(CucableLogger.CucableLogLevel.class), -// any(CucableLogger.CucableLogLevel.class) -// ); -// List capturedLogs = logCaptor.getAllValues(); -// assertThat(capturedLogs.get(0), is("- sourceFeatures:")); -// assertThat(capturedLogs.get(1), is(" - test.feature:3")); -// assertThat(capturedLogs.get(2), is("- sourceRunnerTemplateFile : null")); -// assertThat(capturedLogs.get(3), is("- generatedRunnerDirectory : null")); -// assertThat(capturedLogs.get(4), is("- generatedFeatureDirectory : null")); -// assertThat(capturedLogs.get(5), is("- includeScenarioTags : @include1 and @include2")); -// assertThat(capturedLogs.get(6), is("- customPlaceholders :")); -// assertThat(capturedLogs.get(7), is(" key1 => value1")); -// assertThat(capturedLogs.get(8), is(" key2 => value2")); -// assertThat(capturedLogs.get(9), is("- parallelizationMode : features")); -// assertThat(capturedLogs.get(10), is("- numberOfTestRuns : 0")); -// assertThat(capturedLogs.get(11), is("- desiredNumberOfRunners : 2")); -// } + @Test + public void logMandatoryPropertiesTest() throws CucablePluginException { + ArgumentCaptor logCaptor = ArgumentCaptor.forClass(String.class); + propertyManager.setParallelizationMode("scenarios"); + propertyManager.logProperties(); + verify(logger, times(6)).info(logCaptor.capture(), any(CucableLogger.CucableLogLevel.class), + any(CucableLogger.CucableLogLevel.class) + ); + List capturedLogs = logCaptor.getAllValues(); + assertThat(capturedLogs.get(0), is("- sourceFeatures : not specified")); + assertThat(capturedLogs.get(1), is("- sourceRunnerTemplateFile : null")); + assertThat(capturedLogs.get(2), is("- generatedFeatureDirectory : null")); + assertThat(capturedLogs.get(3), is("- generatedRunnerDirectory : null")); + assertThat(capturedLogs.get(4), is("- parallelizationMode : scenarios")); + assertThat(capturedLogs.get(5), is("- numberOfTestRuns : 0")); + } + + @Test + public void logExtendedPropertiesTest() throws CucablePluginException { + ArgumentCaptor logCaptor = ArgumentCaptor.forClass(String.class); + propertyManager.setIncludeScenarioTags("@include1 and @include2"); + + Map customPlaceholders = new HashMap<>(); + customPlaceholders.put("key1", "value1"); + customPlaceholders.put("key2", "value2"); + propertyManager.setCustomPlaceholders(customPlaceholders); + + propertyManager.setSourceFeatures("test.feature:3"); + propertyManager.setDesiredNumberOfRunners(2); + propertyManager.setParallelizationMode("features"); + + propertyManager.logProperties(); + + verify(logger, times(12)).info(logCaptor.capture(), any(CucableLogger.CucableLogLevel.class), + any(CucableLogger.CucableLogLevel.class) + ); + List capturedLogs = logCaptor.getAllValues(); + assertThat(capturedLogs.get(0), is("- sourceFeatures:")); + assertThat(capturedLogs.get(1), is(" - test.feature:3")); + assertThat(capturedLogs.get(2), is("- sourceRunnerTemplateFile : null")); + assertThat(capturedLogs.get(3), is("- generatedFeatureDirectory : null")); + assertThat(capturedLogs.get(4), is("- generatedRunnerDirectory : null")); + assertThat(capturedLogs.get(5), is("- includeScenarioTags : @include1 and @include2")); + assertThat(capturedLogs.get(6), is("- customPlaceholders :")); + assertThat(capturedLogs.get(7), is(" key1 => value1")); + assertThat(capturedLogs.get(8), is(" key2 => value2")); + assertThat(capturedLogs.get(9), is("- parallelizationMode : features")); + assertThat(capturedLogs.get(10), is("- numberOfTestRuns : 0")); + assertThat(capturedLogs.get(11), is("- desiredNumberOfRunners : 2")); + } @Test public void logMissingPropertiesTest() throws CucablePluginException {