diff --git a/.github/workflows/bld.yml b/.github/workflows/bld.yml index c0ba763..d55711f 100644 --- a/.github/workflows/bld.yml +++ b/.github/workflows/bld.yml @@ -1,14 +1,16 @@ name: bld-ci -on: [push, pull_request, workflow_dispatch] +on: [ push, pull_request, workflow_dispatch ] jobs: build-bld-project: - runs-on: ubuntu-latest - strategy: matrix: - java-version: [17, 21, 22] + java-version: [ 17, 21, 24 ] + kotlin-version: [ 1.9.25, 2.0.21, 2.1.20 ] + os: [ ubuntu-latest, windows-latest, macos-latest ] + + runs-on: ${{ matrix.os }} steps: - name: Checkout source repository @@ -22,11 +24,16 @@ jobs: distribution: "zulu" java-version: ${{ matrix.java-version }} - - name: Grant execute permission for bld - run: chmod +x bld - - - name: Download the dependencies + - name: Download dependencies [examples] + working-directory: examples run: ./bld download - - name: Run tests with bld - run: ./bld compile test + - name: Run tests with JaCoCo [examples] + working-directory: examples + run: ./bld compile jacoco + + - name: Download dependencies + run: ./bld download + + - name: Run tests + run: ./bld compile test \ No newline at end of file diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index bf43624..508f6a5 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -47,11 +47,11 @@ jobs: uses: actions/configure-pages@v3 - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: # Upload generated Javadocs repository path: "build/javadoc/" - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v1 + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index ea86fe8..aa3405d 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ atlassian-ide-plugin.xml .idea/httpRequests local.properties +test-output diff --git a/.idea/bld.xml b/.idea/bld.xml new file mode 100644 index 0000000..6600cee --- /dev/null +++ b/.idea/bld.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/copyright/Apache_License.xml b/.idea/copyright/Apache_License.xml index ade80da..4446c15 100644 --- a/.idea/copyright/Apache_License.xml +++ b/.idea/copyright/Apache_License.xml @@ -1,6 +1,6 @@ - - + \ No newline at end of file diff --git a/.idea/icon.svg b/.idea/icon.svg new file mode 100644 index 0000000..81220b4 --- /dev/null +++ b/.idea/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml index 59ffe59..a203de8 100644 --- a/.idea/libraries/bld.xml +++ b/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/.idea/libraries/compile.xml b/.idea/libraries/compile.xml index 9bd86aa..99cc0c0 100644 --- a/.idea/libraries/compile.xml +++ b/.idea/libraries/compile.xml @@ -7,7 +7,7 @@ - - + + \ No newline at end of file diff --git a/.idea/libraries/runtime.xml b/.idea/libraries/runtime.xml index 2ae5c4b..d4069f2 100644 --- a/.idea/libraries/runtime.xml +++ b/.idea/libraries/runtime.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/.idea/libraries/test.xml b/.idea/libraries/test.xml index b80486a..57ed5ef 100644 --- a/.idea/libraries/test.xml +++ b/.idea/libraries/test.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 9e8368e..ba429d0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,7 +9,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.0.jar", + "${HOME}/.bld/dist/bld-2.2.1.jar", "lib/**/*.jar" ] } diff --git a/README.md b/README.md index 12750a1..e44b64e 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,20 @@ [![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) -[![bld](https://img.shields.io/badge/1.9.0-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) +[![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-testng/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-testng) [![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-testng/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-testng) [![GitHub CI](https://github.com/rife2/bld-testng/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/bld-testng/actions/workflows/bld.yml) -To install, please refer to the [extensions documentation](https://github.com/rife2/bld/wiki/Extensions). +To install the latest version, add the following to the `lib/bld/bld-wrapper.properties` file: + +```properties +bld.extension-testng=com.uwyn.rife2:bld-testng +``` + +For more information, please refer to the [extensions](https://github.com/rife2/bld/wiki/Extensions) documentation. + +## Test with TestNG To run the tests with TestNG, add the following to your build file: @@ -34,5 +42,5 @@ Don't forget to add a TestNG `test` dependency to your build file, as it is not ```java repositories = List.of(MAVEN_CENTRAL); -scope(test).include(dependency("org.testng", "testng", version(7, 10, 0))); +scope(test).include(dependency("org.testng", "testng", version(7, 11, 0))); ``` diff --git a/checkcliargs.sh b/checkcliargs.sh deleted file mode 100755 index 77e8ec5..0000000 --- a/checkcliargs.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -MAIN="org.testng.TestNG" -TMPNEW=/tmp/checkcliargs-new -TMPOLD=/tmp/checkcliargs-old - -java -cp "lib/test/*" $MAIN >$TMPNEW -java -cp "examples/lib/test/*" $MAIN >$TMPOLD - -if [ "$1" = "-v" ]; then - code --wait --diff $TMPOLD $TMPNEW -else - diff $TMPOLD $TMPNEW -fi - -rm -rf $TMPNEW $TMPOLD diff --git a/config/pmd.xml b/config/pmd.xml index 3d3203c..2641880 100644 --- a/config/pmd.xml +++ b/config/pmd.xml @@ -7,9 +7,9 @@ - - + + diff --git a/examples/.idea/bld.xml b/examples/.idea/bld.xml new file mode 100644 index 0000000..6600cee --- /dev/null +++ b/examples/.idea/bld.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/examples/.idea/libraries/bld.xml b/examples/.idea/libraries/bld.xml index 59ffe59..a203de8 100644 --- a/examples/.idea/libraries/bld.xml +++ b/examples/.idea/libraries/bld.xml @@ -2,12 +2,12 @@ - + - + diff --git a/examples/.idea/libraries/compile.xml b/examples/.idea/libraries/compile.xml index 9bd86aa..99cc0c0 100644 --- a/examples/.idea/libraries/compile.xml +++ b/examples/.idea/libraries/compile.xml @@ -7,7 +7,7 @@ - - + + \ No newline at end of file diff --git a/examples/.idea/libraries/runtime.xml b/examples/.idea/libraries/runtime.xml index 2ae5c4b..d4069f2 100644 --- a/examples/.idea/libraries/runtime.xml +++ b/examples/.idea/libraries/runtime.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/examples/.idea/libraries/test.xml b/examples/.idea/libraries/test.xml index b80486a..57ed5ef 100644 --- a/examples/.idea/libraries/test.xml +++ b/examples/.idea/libraries/test.xml @@ -8,7 +8,7 @@ - - + + \ No newline at end of file diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json index 259291e..3005cd9 100644 --- a/examples/.vscode/settings.json +++ b/examples/.vscode/settings.json @@ -10,7 +10,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.bld/dist/bld-1.9.0.jar", + "${HOME}/.bld/dist/bld-2.2.1.jar", "lib/**/*.jar" ] } diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index e815177..88faac2 100644 Binary files a/examples/lib/bld/bld-wrapper.jar and b/examples/lib/bld/bld-wrapper.jar differ diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 3e2cccf..85fd25e 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -1,8 +1,8 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extensions=com.uwyn.rife2:bld-testng:0.9.6 -bld.extension.jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.5 -bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= +bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.10-SNAPSHOT +bld.extension-testng=com.uwyn.rife2:bld-testng:1.0.3-SNAPSHOT +bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= -bld.version=1.9.0 +bld.version=2.2.1 diff --git a/examples/src/bld/java/com/example/ExamplesBuild.java b/examples/src/bld/java/com/example/ExamplesBuild.java index 265b245..9bd0bea 100644 --- a/examples/src/bld/java/com/example/ExamplesBuild.java +++ b/examples/src/bld/java/com/example/ExamplesBuild.java @@ -6,7 +6,6 @@ import rife.bld.extension.JacocoReportOperation; import rife.bld.extension.TestNgOperation; import rife.bld.operations.TestOperation; -import java.io.IOException; import java.util.List; import java.util.logging.ConsoleHandler; import java.util.logging.Level; @@ -18,10 +17,10 @@ import static rife.bld.dependencies.Scope.test; /** * Example build. * - *
    - *
  • {@code ./bld compile test}
  • - *
  • {@code ./bld compile jacoco}
  • - *
+ *
{@code
+ * ./bld compile test
+ * ./bld compile jacoco
+ * }
*/ public class ExamplesBuild extends BaseProject { public ExamplesBuild() { @@ -36,7 +35,7 @@ public class ExamplesBuild extends BaseProject { repositories = List.of(MAVEN_CENTRAL); - scope(test).include(dependency("org.testng", "testng", version(7, 10, 0))); + scope(test).include(dependency("org.testng", "testng", version(7, 11, 0))); } public static void main(String[] args) { @@ -54,7 +53,7 @@ public class ExamplesBuild extends BaseProject { } @BuildCommand(summary = "Generates Jacoco Reports") - public void jacoco() throws IOException { + public void jacoco() throws Exception { new JacocoReportOperation() .fromProject(this) .execute(); diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar index e815177..97c0a4b 100644 Binary files a/lib/bld/bld-wrapper.jar and b/lib/bld/bld-wrapper.jar differ diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index d80f091..c5da09f 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -1,7 +1,8 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true -bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.8 -bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.downloadLocation= +bld.extension-exec=com.uwyn.rife2:bld-exec:1.0.4 +bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.2.1 +bld.repositories=MAVEN_CENTRAL,MAVEN_LOCAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES bld.sourceDirectories= -bld.version=1.9.0 +bld.version=2.2.1 diff --git a/scripts/checkcliargs.sh b/scripts/checkcliargs.sh new file mode 100755 index 0000000..294a6c6 --- /dev/null +++ b/scripts/checkcliargs.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +main="org.testng.TestNG" +new=/tmp/checkcliargs-new +old=/tmp/checkcliargs-old + +java -cp "lib/test/*" $main 2>/dev/null >$new +java -cp "examples/lib/test/*" $main 2>/dev/null >$old + +if [ "$1" = "-v" ]; then + code --wait --diff $old $new +else + diff $old $new +fi + +rm -rf $new $old diff --git a/scripts/cliargs.sh b/scripts/cliargs.sh new file mode 100755 index 0000000..e6d2a32 --- /dev/null +++ b/scripts/cliargs.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +java -cp "lib/test/*" org.testng.TestNG 2>/dev/null |\ +grep "^ -.*" |\ +sed -e "s/ -/-/" -e "s/, -/\n-/" |\ +sed "/testRunFactory/d" |\ +sort |\ +sed '$s/,//' > "src/test/resources/testng-args.txt" + diff --git a/src/bld/java/rife/bld/extension/TestNgOperationBuild.java b/src/bld/java/rife/bld/extension/TestNgOperationBuild.java index a452d9c..88f713c 100644 --- a/src/bld/java/rife/bld/extension/TestNgOperationBuild.java +++ b/src/bld/java/rife/bld/extension/TestNgOperationBuild.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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. @@ -24,8 +24,7 @@ import rife.bld.publish.PublishScm; import java.util.List; -import static rife.bld.dependencies.Repository.MAVEN_CENTRAL; -import static rife.bld.dependencies.Repository.RIFE2_RELEASES; +import static rife.bld.dependencies.Repository.*; import static rife.bld.dependencies.Scope.compile; import static rife.bld.dependencies.Scope.test; import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING; @@ -34,23 +33,23 @@ public class TestNgOperationBuild extends Project { public TestNgOperationBuild() { pkg = "rife.bld.extension"; name = "bld-testng"; - version = version(0, 9, 6); + version = version(1, 0, 3, "SNAPSHOT"); javaRelease = 17; + downloadSources = true; autoDownloadPurge = true; - repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES); + + repositories = List.of(MAVEN_LOCAL, MAVEN_CENTRAL, RIFE2_RELEASES, RIFE2_SNAPSHOTS); - var rife2 = version(1, 7, 3); scope(compile) - .include(dependency("com.uwyn.rife2", "rife2", rife2)) - .include(dependency("com.uwyn.rife2", "bld", version(1, 9, 0))); + .include(dependency("com.uwyn.rife2", "bld", version(2, 2, 1))); scope(test) - .include(dependency("org.testng", "testng", version(7, 10, 0))) - .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 2))) - .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 2))) - .include(dependency("org.assertj", "assertj-core", version(3, 25, 3))); + .include(dependency("org.testng", "testng", version(7, 11, 0))) + .include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 1))) + .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 1))) + .include(dependency("org.assertj", "assertj-core", version(3, 27, 3))); javadocOperation() .javadocOptions() @@ -61,28 +60,26 @@ public class TestNgOperationBuild extends Project { publishOperation() .repository(version.isSnapshot() ? repository("rife2-snapshot") : repository("rife2")) + .repository(repository("github")) .info() .groupId("com.uwyn.rife2") .artifactId("bld-testng") .description("bld Extension to execute tests with TestNG") .url("https://github.com/rife2/bld-testng") - .developer( - new PublishDeveloper() - .id("ethauvin") - .name("Erik C. Thauvin") - .email("erik@thauvin.net") - .url("https://erik.thauvin.net/") + .developer(new PublishDeveloper() + .id("ethauvin") + .name("Erik C. Thauvin") + .email("erik@thauvin.net") + .url("https://erik.thauvin.net/") ) - .license( - new PublishLicense() - .name("The Apache License, Version 2.0") - .url("https://www.apache.org/licenses/LICENSE-2.0.txt") + .license(new PublishLicense() + .name("The Apache License, Version 2.0") + .url("https://www.apache.org/licenses/LICENSE-2.0.txt") ) - .scm( - new PublishScm() - .connection("scm:git:https://github.com/rife2/bld-testng.git") - .developerConnection("scm:git:git@github.com:rife2/bld-testng.git") - .url("https://github.com/rife2/bld-testng") + .scm(new PublishScm() + .connection("scm:git:https://github.com/rife2/bld-testng.git") + .developerConnection("scm:git:git@github.com:rife2/bld-testng.git") + .url("https://github.com/rife2/bld-testng") ) .signKey(property("sign.key")) .signPassphrase(property("sign.passphrase")); @@ -93,11 +90,23 @@ public class TestNgOperationBuild extends Project { } @BuildCommand(summary = "Runs PMD analysis") - public void pmd() { + public void pmd() throws Exception { new PmdOperation() .fromProject(this) .failOnViolation(true) .ruleSets("config/pmd.xml") .execute(); } + + @Override + public void test() throws Exception { + var os = System.getProperty("os.name"); + if (os != null && os.toLowerCase().contains("linux")) { + new ExecOperation() + .fromProject(this) + .command("scripts/cliargs.sh") + .execute(); + } + super.test(); + } } diff --git a/src/main/java/rife/bld/extension/TestNgOperation.java b/src/main/java/rife/bld/extension/TestNgOperation.java index d72a48c..298857f 100644 --- a/src/main/java/rife/bld/extension/TestNgOperation.java +++ b/src/main/java/rife/bld/extension/TestNgOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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. @@ -18,6 +18,7 @@ package rife.bld.extension; import rife.bld.BaseProject; import rife.bld.operations.TestOperation; +import rife.bld.operations.exceptions.ExitStatusException; import java.io.File; import java.io.IOException; @@ -39,23 +40,27 @@ import java.util.stream.Collectors; @SuppressWarnings("PMD.TestClassWithoutTestCases") public class TestNgOperation extends TestOperation> { private static final Logger LOGGER = Logger.getLogger(TestNgOperation.class.getName()); + /** + * The methods to run. + */ + private final Set methods_ = new HashSet<>(); /** * The run options. */ - protected final Map options = new ConcurrentHashMap<>(); + private final Map options_ = new ConcurrentHashMap<>(); /** * The suite packages to run. */ - protected final Set packages = new HashSet<>(); + private final Set packages_ = new HashSet<>(); /** * The suites to run. */ - protected final Set suites = new HashSet<>(); + private final Set suites_ = new HashSet<>(); /** * The classpath entries used for running tests. */ - protected final Set testClasspath = new HashSet<>(); - private BaseProject project; + private final Set testClasspath_ = new HashSet<>(); + private BaseProject project_; /** * Should Method Invocation Listeners be run even for skipped methods. @@ -66,10 +71,23 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation alwaysRunListeners(Boolean isAlwaysRunListeners) { - options.put("-alwaysrunlisteners", String.valueOf(isAlwaysRunListeners)); + options_.put("-alwaysrunlisteners", String.valueOf(isAlwaysRunListeners)); return this; } + private String buildClassPath(String... path) { + var classpath = new StringBuilder(); + for (var p : path) { + if (!p.isBlank()) { + if (!classpath.isEmpty()) { + classpath.append(File.pathSeparator); + } + classpath.append(p); + } + } + return classpath.toString(); + } + /** * This sets the default maximum number of threads to use for data providers when running tests in parallel. * It will only take effect if the parallel mode has been selected (for example,with the @@ -80,7 +98,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation dataProviderThreadCount(int count) { if (count >= 0) { - options.put("-dataproviderthreadcount", String.valueOf(count)); + options_.put("-dataproviderthreadcount", String.valueOf(count)); } return this; } @@ -93,7 +111,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation dependencyInjectorFactory(String injectorFactory) { if (isNotBlank(injectorFactory)) { - options.put("-dependencyinjectorfactory", injectorFactory); + options_.put("-dependencyinjectorfactory", injectorFactory); } return this; } @@ -108,11 +126,35 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation directory(String directoryPath) { if (isNotBlank(directoryPath)) { - options.put("-d", directoryPath); + options_.put("-d", directoryPath); } return this; } + /** + * The directory where the reports will be generated + * + *

Default is {@code build/test-output})

+ * + * @param directoryPath the directory path + * @return this operation instance + */ + public TestNgOperation directory(File directoryPath) { + return directory(directoryPath.getAbsolutePath()); + } + + /** + * The directory where the reports will be generated + * + *

Default is {@code build/test-output})

+ * + * @param directoryPath the directory path + * @return this operation instance + */ + public TestNgOperation directory(Path directoryPath) { + return directory(directoryPath.toFile()); + } + /** * The list of groups you want to be excluded from this run. * @@ -121,8 +163,7 @@ public class TestNgOperation extends TestOperation * @see #excludeGroups(Collection) #excludeGroups(Collection) */ public TestNgOperation excludeGroups(String... group) { - options.put("-excludegroups", String.join(",", Arrays.stream(group).filter(this::isNotBlank).toList())); - return this; + return excludeGroups(List.of(group)); } /** @@ -133,63 +174,90 @@ public class TestNgOperation extends TestOperation * @see #excludeGroups(String...) #excludeGroups(String...) */ public TestNgOperation excludeGroups(Collection group) { - options.put("-excludegroups", String.join(",", group.stream().filter(this::isNotBlank).toList())); + options_.put("-excludegroups", String.join(",", group.stream().filter(this::isNotBlank).toList())); return this; } + @Override + public void execute() throws IOException, InterruptedException, ExitStatusException { + if (project_ == null) { + if (LOGGER.isLoggable(Level.SEVERE) && !silent()) { + LOGGER.severe("A project must be specified."); + } + throw new ExitStatusException(ExitStatusException.EXIT_FAILURE); + } else if (packages_.isEmpty() && suites_.isEmpty() && methods_.isEmpty()) { + if (LOGGER.isLoggable(Level.SEVERE) && !silent()) { + LOGGER.severe("At least an XML suite, package or method is required."); + } + throw new ExitStatusException(ExitStatusException.EXIT_FAILURE); + } else { + super.execute(); + } + } + /** * Part of the {@link #execute execute} operation, constructs the command list to use for building the process. * * @return the command list */ @Override + @SuppressWarnings("PMD.AvoidThrowingRawExceptionTypes") protected List executeConstructProcessCommandList() { - if (project == null) { - LOGGER.severe("A project must be specified."); - } else if (packages.isEmpty() && suites.isEmpty()) { - LOGGER.severe("At least one package or XML suite is required."); - } - - if (!options.containsKey("-d")) { - options.put("-d", Path.of(project.buildDirectory().getPath(), "test-output").toString()); - } - final List args = new ArrayList<>(); - args.add(javaTool()); - args.addAll(this.javaOptions()); - args.add("-cp"); - if (testClasspath.isEmpty()) { - args.add(String.format("%s:%s:%s:%s", Path.of(project.libTestDirectory().getPath(), "*"), - Path.of(project.libCompileDirectory().getPath(), "*"), project.buildMainDirectory(), - project.buildTestDirectory())); - } else { - args.add(String.join(":", testClasspath)); - } - - args.add("org.testng.TestNG"); - - options.forEach((k, v) -> { - args.add(k); - args.add(v); - }); - - if (!suites.isEmpty()) { - args.addAll(suites); - } else if (!options.containsKey("-testclass")) { - try { - args.add(writeDefaultSuite().getPath()); - } catch (IOException ioe) { - LOGGER.log(Level.SEVERE, "An IO error occurred while accessing the default testng.xml file", ioe); + if (project_ != null) { + if (!options_.containsKey("-d")) { + options_.put("-d", new File(project_.buildDirectory(), "test-output").getAbsolutePath()); } - } - if (LOGGER.isLoggable(Level.FINE)) { - LOGGER.fine(String.join(" ", args)); - } + args.add(javaTool()); + args.addAll(javaOptions()); - if (LOGGER.isLoggable(Level.INFO)) { - LOGGER.info(String.format("Report will be saved in file://%s", new File(options.get("-d")))); + args.add("-cp"); + if (testClasspath_.isEmpty()) { + args.add(buildClassPath(joinClasspathJar(project_.testClasspathJars()), + joinClasspathJar(project_.compileClasspathJars()), + joinClasspathJar(project_.providedClasspathJars()), + project_.buildMainDirectory().getAbsolutePath(), + project_.buildTestDirectory().getAbsolutePath())); + } else { + args.add(String.join(File.pathSeparator, testClasspath_)); + } + + args.add("org.testng.TestNG"); + + options_.forEach((k, v) -> { + args.add(k); + args.add(v); + }); + + if (!suites_.isEmpty()) { + args.addAll(suites_); + } else if (!options_.containsKey("-testclass")) { + try { + args.add(writeDefaultSuite().getAbsolutePath()); + } catch (IOException ioe) { + if (LOGGER.isLoggable(Level.SEVERE) && !silent()) { + LOGGER.severe("An IO error occurred while accessing the default testng.xml file: " + + ioe.getMessage()); + } + throw new RuntimeException(ioe); + } + } + + if (!methods_.isEmpty()) { + args.add("-methods"); + args.add(String.join(",", methods_)); + } + + if (LOGGER.isLoggable(Level.FINE) && !silent()) { + LOGGER.fine(String.join(" ", args)); + } + + if (LOGGER.isLoggable(Level.INFO) && !silent()) { + LOGGER.info(String.format("Report will be saved in file://%s", + new File(options_.get("-d")).toURI().getPath())); + } } return args; @@ -203,7 +271,7 @@ public class TestNgOperation extends TestOperation */ @Override public TestNgOperation fromProject(BaseProject project) { - this.project = project; + project_ = project; directory(Path.of(project.buildDirectory().getPath(), "test-output").toString()); return this; } @@ -215,7 +283,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation failWhenEverythingSkipped(Boolean isFailAllSkipped) { - options.put("-failwheneverythingskipped", String.valueOf(isFailAllSkipped)); + options_.put("-failwheneverythingskipped", String.valueOf(isFailAllSkipped)); return this; } @@ -227,12 +295,12 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation failurePolicy(FailurePolicy policy) { - options.put("-configfailurepolicy", policy.name().toLowerCase(Locale.getDefault())); + options_.put("-configfailurepolicy", policy.name().toLowerCase(Locale.getDefault())); return this; } /** - * Should TestNG generate results on a per suite basis by creating a sub directory for each suite and dumping + * Should TestNG generate results on a per-suite basis by creating a subdirectory for each suite and dumping * results into it. * *

Default is {@code false}

. @@ -241,7 +309,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation generateResultsPerSuite(Boolean resultsPerSuite) { - options.put("-generateResultsPerSuite", String.valueOf(resultsPerSuite)); + options_.put("-generateResultsPerSuite", String.valueOf(resultsPerSuite)); return this; } @@ -255,8 +323,7 @@ public class TestNgOperation extends TestOperation * @see #groups(Collection) #groups(Collection) */ public TestNgOperation groups(String... group) { - options.put("-groups", String.join(",", Arrays.stream(group).filter(this::isNotBlank).toList())); - return this; + return groups(List.of(group)); } /** @@ -269,7 +336,7 @@ public class TestNgOperation extends TestOperation * @see #groups(String...) #groups(String...) */ public TestNgOperation groups(Collection group) { - options.put("-groups", String.join(",", group.stream().filter(this::isNotBlank).toList())); + options_.put("-groups", String.join(",", group.stream().filter(this::isNotBlank).toList())); return this; } @@ -283,7 +350,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation ignoreMissedTestName(Boolean isIgnoreMissedTestNames) { - options.put("-ignoreMissedTestNames", String.valueOf(isIgnoreMissedTestNames)); + options_.put("-ignoreMissedTestNames", String.valueOf(isIgnoreMissedTestNames)); return this; } @@ -296,7 +363,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation includeAllDataDrivenTestsWhenSkipping(Boolean isIncludeDrivenTestsWhenSkipping) { - options.put("-includeAllDataDrivenTestsWhenSkipping", String.valueOf(isIncludeDrivenTestsWhenSkipping)); + options_.put("-includeAllDataDrivenTestsWhenSkipping", String.valueOf(isIncludeDrivenTestsWhenSkipping)); return this; } @@ -316,10 +383,18 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation jUnit(Boolean isJunit) { - options.put("-junit", String.valueOf(isJunit)); + options_.put("-junit", String.valueOf(isJunit)); return this; } + private String joinClasspathJar(List jars) { + if (!jars.isEmpty()) { + return String.join(File.pathSeparator, jars.stream().map(File::getAbsolutePath).toList()); + } else { + return ""; + } + } + /** * The list of {@code .class} files or list of class names implementing {@code ITestListener} or * {@code ISuiteListener} @@ -329,8 +404,7 @@ public class TestNgOperation extends TestOperation * @see #listener(Collection) #listener(Collection) */ public TestNgOperation listener(String... listener) { - options.put("-listener", String.join(",", Arrays.stream(listener).filter(this::isNotBlank).toList())); - return this; + return listener(List.of(listener)); } /** @@ -342,7 +416,7 @@ public class TestNgOperation extends TestOperation * @see #listener(String...) #listener(String...) */ public TestNgOperation listener(Collection listener) { - options.put("-listener", String.join(",", listener.stream().filter(this::isNotBlank).toList())); + options_.put("-listener", String.join(",", listener.stream().filter(this::isNotBlank).toList())); return this; } @@ -354,7 +428,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation listenerComparator(String listenerComparator) { - options.put("-listenercomparator", listenerComparator); + options_.put("-listenercomparator", listenerComparator); return this; } @@ -365,7 +439,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation listenerFactory(String listenerFactory) { - options.put("-listenerfactory", listenerFactory); + options_.put("-listenerfactory", listenerFactory); return this; } @@ -378,7 +452,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation log(int level) { if (level >= 0) { - options.put("-log", String.valueOf(level)); + options_.put("-log", String.valueOf(level)); } return this; } @@ -393,9 +467,7 @@ public class TestNgOperation extends TestOperation * @see #methodSelectors(Collection) #methodSelectors(Collection) */ public TestNgOperation methodSelectors(String... selector) { - options.put("-methodselectors", - String.join(",", Arrays.stream(selector).filter(this::isNotBlank).toList())); - return this; + return methodSelectors(List.of(selector)); } /** @@ -408,7 +480,7 @@ public class TestNgOperation extends TestOperation * @see #methodSelectors(String...) #methodSelectors(String...) */ public TestNgOperation methodSelectors(Collection selector) { - options.put("-methodselectors", String.join(",", selector.stream().filter(this::isNotBlank).toList())); + options_.put("-methodselectors", String.join(",", selector.stream().filter(this::isNotBlank).toList())); return this; } @@ -422,8 +494,7 @@ public class TestNgOperation extends TestOperation * @see #methods(Collection) #methods(Collection) */ public TestNgOperation methods(String... method) { - options.put("-methods", String.join(",", Arrays.stream(method).filter(this::isNotBlank).toList())); - return this; + return methods(List.of(method)); } /** @@ -436,10 +507,19 @@ public class TestNgOperation extends TestOperation * @see #methods(String...) #methods(String...) */ public TestNgOperation methods(Collection method) { - options.put("-methods", String.join(",", method.stream().filter(this::isNotBlank).toList())); + methods_.addAll(method); return this; } + /** + * Returns the methods to run. + * + * @return the set of methods + */ + public Set methods() { + return methods_; + } + /** * Mixed mode autodetects the type of current test and run it with appropriate runner. * @@ -449,46 +529,48 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation mixed(Boolean isMixed) { - options.put("-mixed", String.valueOf(isMixed)); - return this; - } - - /** - * Fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create - * test class and listener instances. - * - * @param objectFactory the object factory - * @return this operation instance - */ - public TestNgOperation objectFactory(String objectFactory) { - options.put("-objectfactory", objectFactory); + options_.put("-mixed", String.valueOf(isMixed)); return this; } /** * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. + *

+ * A fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create + * test class and listener instances. * - * @param factory one or more factories + * @param factory one or more factory * @return this operation instance * @see #objectFactory(Collection) #objectFactory(Collection) */ public TestNgOperation objectFactory(String... factory) { - options.put("-objectfactory", String.join(",", Arrays.stream(factory).filter(this::isNotBlank).toList())); - return this; + return objectFactory(List.of(factory)); } /** * The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}. + *

+ * A fully qualified class name that implements {@code org.testng.ITestObjectFactory} which can be used to create + * test class and listener instances. * * @param factory the list of factories * @return this operation instance * @see #objectFactory(String...) #objectFactory(String...) */ public TestNgOperation objectFactory(Collection factory) { - options.put("-objectfactory", String.join(",", factory.stream().filter(this::isNotBlank).toList())); + options_.put("-objectfactory", String.join(",", factory.stream().filter(this::isNotBlank).toList())); return this; } + /** + * Returns the run options. + * + * @return the map of run options + */ + public Map options() { + return options_; + } + /** * The list of fully qualified class names of listeners that should be skipped from being wired in via * Service Loaders. @@ -498,9 +580,7 @@ public class TestNgOperation extends TestOperation * @see #overrideIncludedMethods(Collection) #overrideIncludedMethods(Collection) */ public TestNgOperation overrideIncludedMethods(String... method) { - options.put("-overrideincludedmethods", - String.join(",", Arrays.stream(method).filter(this::isNotBlank).toList())); - return this; + return overrideIncludedMethods(List.of(method)); } /** @@ -512,7 +592,7 @@ public class TestNgOperation extends TestOperation * @see #overrideIncludedMethods(String...) #overrideIncludedMethods(String...) */ public TestNgOperation overrideIncludedMethods(Collection method) { - options.put("-overrideincludedmethods", String.join(",", method.stream().filter(this::isNotBlank).toList())); + options_.put("-overrideincludedmethods", String.join(",", method.stream().filter(this::isNotBlank).toList())); return this; } @@ -528,8 +608,7 @@ public class TestNgOperation extends TestOperation * @see #packages(Collection) #packages(Collection) */ public TestNgOperation packages(String... name) { - packages.addAll(Arrays.stream(name).filter(this::isNotBlank).toList()); - return this; + return packages(List.of(name)); } /** @@ -544,10 +623,19 @@ public class TestNgOperation extends TestOperation * @see #packages(String...) #packages(String...) */ public TestNgOperation packages(Collection name) { - packages.addAll(name.stream().filter(this::isNotBlank).toList()); + packages_.addAll(name.stream().filter(this::isNotBlank).toList()); return this; } + /** + * Returns the suite packages to run. + * + * @return the set of packages + */ + public Set packages() { + return packages_; + } + /** * If specified, sets the default mechanism used to determine how to use parallel threads when running tests. * If not set, default mechanism is not to use parallel threads at all. @@ -558,7 +646,7 @@ public class TestNgOperation extends TestOperation * @see Parallel */ public TestNgOperation parallel(Parallel mechanism) { - options.put("-parallel", mechanism.name().toLowerCase(Locale.getDefault())); + options_.put("-parallel", mechanism.name().toLowerCase(Locale.getDefault())); return this; } @@ -570,7 +658,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation port(int port) { if (port >= 1) { - options.put("-port", String.valueOf(port)); + options_.put("-port", String.valueOf(port)); } return this; } @@ -584,7 +672,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation propagateDataProviderFailureAsTestFailure(Boolean isPropagateDataProviderFailure) { - options.put("-propagateDataProviderFailureAsTestFailure", String.valueOf(isPropagateDataProviderFailure)); + options_.put("-propagateDataProviderFailureAsTestFailure", String.valueOf(isPropagateDataProviderFailure)); return this; } @@ -596,7 +684,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation reporter(String reporter) { if (isNotBlank(reporter)) { - options.put("-reporter", reporter); + options_.put("-reporter", reporter); } return this; } @@ -609,7 +697,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation shareThreadPoolForDataProviders(boolean shareThreadPoolForDataProviders) { if (shareThreadPoolForDataProviders) { - options.put("-shareThreadPoolForDataProviders", String.valueOf(shareThreadPoolForDataProviders)); + options_.put("-shareThreadPoolForDataProviders", "true"); } return this; } @@ -621,10 +709,49 @@ public class TestNgOperation extends TestOperation * * @param directory one or more directories * @return this operation instance - * @see #sourceDir(String...) #sourceDir(String...) + * @see #sourceDir(Collection) */ public TestNgOperation sourceDir(String... directory) { - options.put("-sourcedir", String.join(";", Arrays.stream(directory).filter(this::isNotBlank).toList())); + return sourceDir(List.of(directory)); + } + + /** + * The directories where your javadoc annotated test sources are. This option is only necessary + * if you are using javadoc type annotations. (e.g. {@code "src/test"} or + * {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}). + * + * @param directory one or more directories + * @return this operation instance + * @see #sourceDirFiles(Collection) + */ + public TestNgOperation sourceDir(File... directory) { + return sourceDirFiles(List.of(directory)); + } + + /** + * The directories where your javadoc annotated test sources are. This option is only necessary + * if you are using javadoc type annotations. (e.g. {@code "src/test"} or + * {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}). + * + * @param directory one or more directories + * @return this operation instance + * @see #sourceDirPaths(Collection) + */ + public TestNgOperation sourceDir(Path... directory) { + return sourceDirPaths(List.of(directory)); + } + + /** + * The directories where your javadoc annotated test sources are. This option is only necessary + * if you are using javadoc type annotations. (e.g. {@code "src/test"} or + * {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}). + * + * @param directory the list of directories + * @return this operation instance + * @see #sourceDir(String...) + */ + public TestNgOperation sourceDir(Collection directory) { + options_.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList())); return this; } @@ -635,11 +762,23 @@ public class TestNgOperation extends TestOperation * * @param directory the list of directories * @return this operation instance - * @see #sourceDir(String...) #sourceDir(String...) + * @see #sourceDir(File...) */ - public TestNgOperation sourceDir(Collection directory) { - options.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList())); - return this; + public TestNgOperation sourceDirFiles(Collection directory) { + return sourceDir(directory.stream().map(File::getAbsolutePath).toList()); + } + + /** + * The directories where your javadoc annotated test sources are. This option is only necessary + * if you are using javadoc type annotations. (e.g. {@code "src/test"} or + * {@code "src/test/org/testng/eclipse-plugin", "src/test/org/testng/testng"}). + * + * @param directory the list of directories + * @return this operation instance + * @see #sourceDir(Path...) + */ + public TestNgOperation sourceDirPaths(Collection directory) { + return sourceDirFiles(directory.stream().map(Path::toFile).toList()); } /** @@ -651,9 +790,7 @@ public class TestNgOperation extends TestOperation * @see #spiListenersToSkip(Collection) #spiListenersToSkip(Collection) */ public TestNgOperation spiListenersToSkip(String... listenerToSkip) { - options.put("-spilistenerstoskip", - String.join(",", Arrays.stream(listenerToSkip).filter(this::isNotBlank).toList())); - return this; + return spiListenersToSkip(List.of(listenerToSkip)); } /** @@ -665,7 +802,7 @@ public class TestNgOperation extends TestOperation * @see #spiListenersToSkip(String...) #spiListenersToSkip(String...) */ public TestNgOperation spiListenersToSkip(Collection listenerToSkip) { - options.put("-spilistenerstoskip", + options_.put("-spilistenerstoskip", String.join(",", listenerToSkip.stream().filter(this::isNotBlank).toList())); return this; } @@ -679,7 +816,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation suiteName(String name) { if (isNotBlank(name)) { - options.put("-suitename", '"' + name + '"'); + options_.put("-suitename", '"' + name + '"'); } return this; } @@ -693,7 +830,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation suiteThreadPoolSize(int poolSize) { if (poolSize >= 0) { - options.put("-suitethreadpoolsize", String.valueOf(poolSize)); + options_.put("-suitethreadpoolsize", String.valueOf(poolSize)); } return this; } @@ -708,8 +845,7 @@ public class TestNgOperation extends TestOperation * @see #suites(Collection) #suites(Collection) */ public TestNgOperation suites(String... suite) { - suites.addAll(Arrays.stream(suite).filter(this::isNotBlank).toList()); - return this; + return suites(List.of(suite)); } /** @@ -722,10 +858,19 @@ public class TestNgOperation extends TestOperation * @see #suites(String...) #suites(String...) */ public TestNgOperation suites(Collection suite) { - suites.addAll(suite.stream().filter(this::isNotBlank).toList()); + suites_.addAll(suite.stream().filter(this::isNotBlank).toList()); return this; } + /** + * Returns the suites to run. + * + * @return the set of suites + */ + public Set suites() { + return suites_; + } + /** * Create a test file and delete it on exit. * @@ -747,8 +892,7 @@ public class TestNgOperation extends TestOperation * @see #testClass(Collection) #testClass(Collection) */ public TestNgOperation testClass(String... aClass) { - options.put("-testclass", String.join(",", Arrays.stream(aClass).filter(this::isNotBlank).toList())); - return this; + return testClass(List.of(aClass)); } /** @@ -761,7 +905,7 @@ public class TestNgOperation extends TestOperation * @see #testClass(String...) #testClass(String...) */ public TestNgOperation testClass(Collection aClass) { - options.put("-testclass", String.join(",", aClass.stream().filter(this::isNotBlank).toList())); + options_.put("-testclass", String.join(",", aClass.stream().filter(this::isNotBlank).toList())); return this; } @@ -773,8 +917,7 @@ public class TestNgOperation extends TestOperation * @see #testClasspath(String...) #testClasspath(String...) */ public TestNgOperation testClasspath(String... entry) { - testClasspath.addAll(Arrays.stream(entry).filter(this::isNotBlank).toList()); - return this; + return testClasspath(List.of(entry)); } /** @@ -785,10 +928,19 @@ public class TestNgOperation extends TestOperation * @see #testClasspath(String...) #testClasspath(String...) */ public TestNgOperation testClasspath(Collection entry) { - testClasspath.addAll(entry.stream().filter(this::isNotBlank).toList()); + testClasspath_.addAll(entry.stream().filter(this::isNotBlank).toList()); return this; } + /** + * Returns the classpath entries used for running tests. + * + * @return the set of test classpath + */ + public Set testClasspath() { + return testClasspath_; + } + /** * Specifies a jar file that contains test classes. If a {@code testng.xml} file is found at the root of that * jar file, it will be used, otherwise, all the test classes found in this jar file will be considered test @@ -799,7 +951,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation testJar(String jar) { if (isNotBlank(jar)) { - options.put("-testjar", jar); + options_.put("-testjar", jar); } return this; } @@ -813,7 +965,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation testName(String name) { if (isNotBlank(name)) { - options.put("-testname", '"' + name + '"'); + options_.put("-testname", '"' + name + '"'); } return this; } @@ -826,9 +978,7 @@ public class TestNgOperation extends TestOperation * @see #testNames(Collection) #testNames(Collection) */ public TestNgOperation testNames(String... name) { - options.put("-testnames", - Arrays.stream(name).filter(this::isNotBlank).map(s -> '"' + s + '"').collect(Collectors.joining(","))); - return this; + return testNames(List.of(name)); } /** @@ -839,7 +989,7 @@ public class TestNgOperation extends TestOperation * @see #testName(String) #testName(String) */ public TestNgOperation testNames(Collection name) { - options.put("-testnames", + options_.put("-testnames", name.stream().filter(this::isNotBlank).map(s -> '"' + s + '"').collect(Collectors.joining(","))); return this; } @@ -852,7 +1002,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation testRunFactory(String factory) { if (isNotBlank(factory)) { - options.put("-testrunfactory", factory); + options_.put("-testrunfactory", factory); } return this; } @@ -867,7 +1017,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation threadCount(int count) { if (count >= 0) { - options.put("-threadcount", String.valueOf(count)); + options_.put("-threadcount", String.valueOf(count)); } return this; } @@ -880,7 +1030,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation threadPoolFactoryClass(String factoryClass) { if (isNotBlank(factoryClass)) { - options.put("-threadpoolfactoryclass", factoryClass); + options_.put("-threadpoolfactoryclass", factoryClass); } return this; } @@ -894,7 +1044,7 @@ public class TestNgOperation extends TestOperation * @return this operation instance */ public TestNgOperation useDefaultListeners(Boolean isDefaultListener) { - options.put("-usedefaultlisteners", String.valueOf(isDefaultListener)); + options_.put("-usedefaultlisteners", String.valueOf(isDefaultListener)); return this; } @@ -906,7 +1056,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation useGlobalThreadPool(boolean useGlobalThreadPool) { if (useGlobalThreadPool) { - options.put("-useGlobalThreadPool", String.valueOf(useGlobalThreadPool)); + options_.put("-useGlobalThreadPool", "true"); } return this; } @@ -920,7 +1070,7 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation verbose(int level) { if (level >= 0) { - options.put("-verbose", String.valueOf(level)); + options_.put("-verbose", String.valueOf(level)); } return this; } @@ -929,11 +1079,11 @@ public class TestNgOperation extends TestOperation var temp = tempFile(); try (var bufWriter = Files.newBufferedWriter(Paths.get(temp.getPath()))) { bufWriter.write("" + - "" + - "" + - "" + - ""); - for (var p : packages) { + "" + + "" + + "" + + ""); + for (var p : packages_) { bufWriter.write(String.format("", p)); } bufWriter.write(""); @@ -951,11 +1101,35 @@ public class TestNgOperation extends TestOperation */ public TestNgOperation xmlPathInJar(String path) { if (isNotBlank(path)) { - options.put("-xmlpathinjar", path); + options_.put("-xmlpathinjar", path); } return this; } + /** + * This attribute should contain the path to a valid XML file inside the test jar + * (e.g. {@code "resources/testng.xml"}). The default is {@code testng.xml}, which means a file called + * {@code testng.xml} at the root of the jar file. This option will be ignored unless a test jar is specified. + * + * @param path the path + * @return this operation instance + */ + public TestNgOperation xmlPathInJar(File path) { + return xmlPathInJar(path.getAbsolutePath()); + } + + /** + * This attribute should contain the path to a valid XML file inside the test jar + * (e.g. {@code "resources/testng.xml"}). The default is {@code testng.xml}, which means a file called + * {@code testng.xml} at the root of the jar file. This option will be ignored unless a test jar is specified. + * + * @param path the path + * @return this operation instance + */ + public TestNgOperation xmlPathInJar(Path path) { + return xmlPathInJar(path.toFile()); + } + /** * Parallel Mechanisms */ diff --git a/src/test/java/rife/bld/extension/TestNgExample.java b/src/test/java/rife/bld/extension/TestNgExample.java index c2dc3e0..faa223a 100644 --- a/src/test/java/rife/bld/extension/TestNgExample.java +++ b/src/test/java/rife/bld/extension/TestNgExample.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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. @@ -22,8 +22,9 @@ package rife.bld.extension; * @author Erik C. Thauvin * @since 1.0 */ -@SuppressWarnings("PMD.TestClassWithoutTestCases") +@SuppressWarnings({"PMD.TestClassWithoutTestCases", "unused"}) class TestNgExample { + @SuppressWarnings("SameReturnValue") public String getMessage() { return "Hello World!"; } diff --git a/src/test/java/rife/bld/extension/TestNgExampleTest.java b/src/test/java/rife/bld/extension/TestNgExampleTest.java index a2c35b9..6d3c9b0 100644 --- a/src/test/java/rife/bld/extension/TestNgExampleTest.java +++ b/src/test/java/rife/bld/extension/TestNgExampleTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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. @@ -25,6 +25,7 @@ import org.testng.annotations.Test; * @author Erik C. Thauvin * @since 1.0 */ +@SuppressWarnings("unused") class TestNgExampleTest { private final TestNgExample example = new TestNgExample(); diff --git a/src/test/java/rife/bld/extension/TestNgOperationTest.java b/src/test/java/rife/bld/extension/TestNgOperationTest.java index f216e13..d4f3193 100644 --- a/src/test/java/rife/bld/extension/TestNgOperationTest.java +++ b/src/test/java/rife/bld/extension/TestNgOperationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 the original author or authors. + * Copyright 2023-2025 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,10 +16,18 @@ package rife.bld.extension; +import org.assertj.core.api.AutoCloseableSoftAssertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; import rife.bld.Project; +import rife.bld.blueprints.BaseProjectBlueprint; import rife.bld.operations.exceptions.ExitStatusException; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.List; import static org.assertj.core.api.Assertions.*; @@ -38,47 +46,125 @@ class TestNgOperationTest { @Test void testAlwaysRunListeners() { var op = new TestNgOperation().alwaysRunListeners(false); - assertThat(op.options.get("-alwaysrunlisteners")).isEqualTo("false"); + assertThat(op.options().get("-alwaysrunlisteners")).isEqualTo("false"); op = new TestNgOperation().alwaysRunListeners(true); - assertThat(op.options.get("-alwaysrunlisteners")).isEqualTo("true"); + assertThat(op.options().get("-alwaysrunlisteners")).isEqualTo("true"); + } + + @Test + @EnabledOnOs(OS.LINUX) + void testCheckAllParameters() throws IOException { + var args = Files.readAllLines(Paths.get("src", "test", "resources", "testng-args.txt")); + + assertThat(args).isNotEmpty(); + + var params = new TestNgOperation() + .fromProject(new BaseProjectBlueprint(new File("examples"), "com.example", "examples", "Examples")) + .alwaysRunListeners(true) + .dataProviderThreadCount(1) + .dependencyInjectorFactory("injectorfactory") + .directory("dir") + .excludeGroups("group") + .failWhenEverythingSkipped(true) + .failurePolicy(TestNgOperation.FailurePolicy.SKIP) + .generateResultsPerSuite(true) + .groups("group1", "group2") + .ignoreMissedTestName(true) + .includeAllDataDrivenTestsWhenSkipping(true) + .listener("listener") + .listenerComparator("comparator") + .listenerFactory("factory") + .log(1) + .methodSelectors("selector") + .methods("methods") + .mixed(true) + .objectFactory("objectFactory") + .overrideIncludedMethods("method") + .parallel(TestNgOperation.Parallel.TESTS) + .propagateDataProviderFailureAsTestFailure(true) + .reporter("reporter") + .shareThreadPoolForDataProviders(true) + .spiListenersToSkip("listenter") + .suiteName("name") + .suiteThreadPoolSize(1) + .testClass("class") + .testJar("jar") + .testName("name") + .testNames("names") + .testRunFactory("runFactory") + .threadCount(1) + .threadPoolFactoryClass("poolClass") + .useDefaultListeners(true) + .useGlobalThreadPool(true) + .verbose(1) + .xmlPathInJar("jarPath") + .executeConstructProcessCommandList(); + + try (var softly = new AutoCloseableSoftAssertions()) { + for (var p : args) { + var found = false; + for (var a : params) { + if (a.startsWith(p)) { + found = true; + break; + } + } + softly.assertThat(found).as(p + " not found.").isTrue(); + } + } + } @Test void testClass() { var op = new TestNgOperation().testClass(FOO, BAR); - assertThat(op.options.get("-testclass")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-testclass")).isEqualTo(String.format("%s,%s", FOO, BAR)); new TestNgOperation().testClass(List.of(FOO, BAR)); - assertThat(op.options.get("-testclass")).as("as list") + assertThat(op.options().get("-testclass")).as("as list") .isEqualTo(String.format("%s,%s", FOO, BAR)); } + @Test + void testClasspath() { + var op = new TestNgOperation().testClasspath(FOO, BAR); + assertThat(op.testClasspath()).containsExactly(BAR, FOO); + } + @Test void testDataProviderThreadCount() { var op = new TestNgOperation().dataProviderThreadCount(1); - assertThat(op.options.get("-dataproviderthreadcount")).isEqualTo("1"); + assertThat(op.options().get("-dataproviderthreadcount")).isEqualTo("1"); } @Test void testDependencyInjectorFactory() { var op = new TestNgOperation().dependencyInjectorFactory(FOO); - assertThat(op.options.get("-dependencyinjectorfactory")).isEqualTo(FOO); + assertThat(op.options().get("-dependencyinjectorfactory")).isEqualTo(FOO); } @Test void testDirectory() { + var foo = new File("FOO"); + var op = new TestNgOperation().directory(FOO); - assertThat(op.options.get("-d")).isEqualTo(FOO); + assertThat(op.options().get("-d")).as("as string").isEqualTo(FOO); + + op = new TestNgOperation().directory(foo); + assertThat(op.options().get("-d")).as("as file").isEqualTo(foo.getAbsolutePath()); + + op = new TestNgOperation().directory(foo.toPath()); + assertThat(op.options().get("-d")).as("as path").isEqualTo(foo.getAbsolutePath()); } @Test void testExcludeGroups() { var op = new TestNgOperation().excludeGroups(FOO, BAR); - assertThat(op.options.get("-excludegroups")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-excludegroups")).isEqualTo(String.format("%s,%s", FOO, BAR)); op = new TestNgOperation().excludeGroups(List.of(FOO, BAR)); - assertThat(op.options.get("-excludegroups")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-excludegroups")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test @@ -97,10 +183,9 @@ class TestNgOperationTest { assertThatCode(() -> new TestNgOperation().fromProject(new Project()) - .testClass("rife.bld.extension.TestNgExampleTest") - .methods("rife.bld.extension.TestNgExampleTest.verifyHello") + .methods("rife.bld.extension.TestNgExampleTest.foo") .execute()) - .as("with methods").doesNotThrowAnyException(); + .as("with methods").isInstanceOf(ExitStatusException.class); assertThatCode(() -> new TestNgOperation().fromProject(new Project()) @@ -135,276 +220,304 @@ class TestNgOperationTest { @Test void testFailWheneverEverythingSkipped() { var op = new TestNgOperation().failWhenEverythingSkipped(false); - assertThat(op.options.get("-failwheneverythingskipped")).isEqualTo("false"); + assertThat(op.options().get("-failwheneverythingskipped")).isEqualTo("false"); op = new TestNgOperation().failWhenEverythingSkipped(true); - assertThat(op.options.get("-failwheneverythingskipped")).isEqualTo("true"); + assertThat(op.options().get("-failwheneverythingskipped")).isEqualTo("true"); } @Test void testFailurePolicy() { var op = new TestNgOperation().failurePolicy(TestNgOperation.FailurePolicy.CONTINUE); - assertThat(op.options.get("-configfailurepolicy")).isEqualTo("continue"); + assertThat(op.options().get("-configfailurepolicy")).isEqualTo("continue"); op = new TestNgOperation().failurePolicy(TestNgOperation.FailurePolicy.SKIP); - assertThat(op.options.get("-configfailurepolicy")).isEqualTo("skip"); + assertThat(op.options().get("-configfailurepolicy")).isEqualTo("skip"); } @Test void testGenerateResultsPerSuite() { var op = new TestNgOperation().generateResultsPerSuite(false); - assertThat(op.options.get("-generateResultsPerSuite")).isEqualTo("false"); + assertThat(op.options().get("-generateResultsPerSuite")).isEqualTo("false"); op = new TestNgOperation().generateResultsPerSuite(true); - assertThat(op.options.get("-generateResultsPerSuite")).isEqualTo("true"); + assertThat(op.options().get("-generateResultsPerSuite")).isEqualTo("true"); } @Test void testGroups() { var op = new TestNgOperation().groups(FOO, BAR); - assertThat(op.options.get("-groups")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-groups")).isEqualTo(String.format("%s,%s", FOO, BAR)); + + op.groups(List.of("group3", "group4")); + assertThat(op.options().get("-groups")).isEqualTo("group3,group4"); + } @Test void testIgnoreMissedTestName() { var op = new TestNgOperation().ignoreMissedTestName(false); - assertThat(op.options.get("-ignoreMissedTestNames")).isEqualTo("false"); + assertThat(op.options().get("-ignoreMissedTestNames")).isEqualTo("false"); op = new TestNgOperation().ignoreMissedTestName(true); - assertThat(op.options.get("-ignoreMissedTestNames")).isEqualTo("true"); + assertThat(op.options().get("-ignoreMissedTestNames")).isEqualTo("true"); } @Test void testIncludeAllDataDrivenTestsWhenSkipping() { var op = new TestNgOperation().includeAllDataDrivenTestsWhenSkipping(false); - assertThat(op.options.get("-includeAllDataDrivenTestsWhenSkipping")).isEqualTo("false"); + assertThat(op.options().get("-includeAllDataDrivenTestsWhenSkipping")).isEqualTo("false"); op = new TestNgOperation().includeAllDataDrivenTestsWhenSkipping(true); - assertThat(op.options.get("-includeAllDataDrivenTestsWhenSkipping")).isEqualTo("true"); + assertThat(op.options().get("-includeAllDataDrivenTestsWhenSkipping")).isEqualTo("true"); } @Test void testJar() { var op = new TestNgOperation().testJar(FOO); - assertThat(op.options.get("-testjar")).isEqualTo(FOO); + assertThat(op.options().get("-testjar")).isEqualTo(FOO); } @Test void testJunit() { var op = new TestNgOperation().jUnit(false); - assertThat(op.options.get("-junit")).isEqualTo("false"); + assertThat(op.options().get("-junit")).isEqualTo("false"); op = new TestNgOperation().jUnit(true); - assertThat(op.options.get("-junit")).isEqualTo("true"); + assertThat(op.options().get("-junit")).isEqualTo("true"); } @Test void testListener() { var ops = new TestNgOperation().listener(FOO, BAR); - assertThat(ops.options.get("-listener")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-listener")).isEqualTo(String.format("%s,%s", FOO, BAR)); ops = new TestNgOperation().listener(List.of(FOO, BAR)); - assertThat(ops.options.get("-listener")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-listener")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test void testMethodDetectors() { var op = new TestNgOperation().methodSelectors(FOO, BAR); - assertThat(op.options.get("-methodselectors")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-methodselectors")).isEqualTo(String.format("%s,%s", FOO, BAR)); op = new TestNgOperation().methodSelectors(List.of(FOO, BAR)); - assertThat(op.options.get("-methodselectors")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.options().get("-methodselectors")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test void testMethods() { var op = new TestNgOperation().methods(FOO, BAR); - assertThat(op.options.get("-methods")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.methods()).containsExactly(BAR, FOO); new TestNgOperation().methods(List.of(FOO, BAR)); - assertThat(op.options.get("-methods")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(op.methods()).containsExactly(BAR, FOO); } @Test void testMixed() { var op = new TestNgOperation().mixed(false); - assertThat(op.options.get("-mixed")).isEqualTo("false"); + assertThat(op.options().get("-mixed")).isEqualTo("false"); op = new TestNgOperation().mixed(true); - assertThat(op.options.get("-mixed")).isEqualTo("true"); + assertThat(op.options().get("-mixed")).isEqualTo("true"); } @Test void testName() { var op = new TestNgOperation().testName(FOO); - assertThat(op.options.get("-testname")).isEqualTo("\"" + FOO + '\"'); + assertThat(op.options().get("-testname")).isEqualTo("\"" + FOO + '\"'); } @Test void testNames() { var ops = new TestNgOperation().testNames(FOO, BAR); - assertThat(ops.options.get("-testnames")).isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR)); + assertThat(ops.options().get("-testnames")).isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR)); new TestNgOperation().testNames(List.of(FOO, BAR)); - assertThat(ops.options.get("-testnames")).as("as list").isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR)); + assertThat(ops.options().get("-testnames")).as("as list").isEqualTo(String.format("\"%s\",\"%s\"", FOO, BAR)); } @Test void testObjectFactory() { var ops = new TestNgOperation().objectFactory(FOO, BAR); - assertThat(ops.options.get("-objectfactory")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-objectfactory")).isEqualTo(String.format("%s,%s", FOO, BAR)); ops = new TestNgOperation().objectFactory(List.of(FOO, BAR)); - assertThat(ops.options.get("-objectfactory")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-objectfactory")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test void testOverrideIncludedMethods() { var ops = new TestNgOperation().overrideIncludedMethods(FOO, BAR); - assertThat(ops.options.get("-overrideincludedmethods")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-overrideincludedmethods")).isEqualTo(String.format("%s,%s", FOO, BAR)); ops = new TestNgOperation().overrideIncludedMethods(List.of(FOO, BAR)); - assertThat(ops.options.get("-overrideincludedmethods")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-overrideincludedmethods")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test void testPackages() { var op = new TestNgOperation().packages(FOO, BAR); - assertThat(op.packages).contains(FOO).contains(BAR); + assertThat(op.packages()).contains(FOO).contains(BAR); op = new TestNgOperation().packages(List.of(FOO, BAR)); - assertThat(op.packages).as("as list").contains(FOO).contains(BAR); + assertThat(op.packages()).as("as list").contains(FOO).contains(BAR); } @Test void testParallel() { var op = new TestNgOperation().parallel(TestNgOperation.Parallel.TESTS); - assertThat(op.options.get("-parallel")).isEqualTo("tests"); + assertThat(op.options().get("-parallel")).isEqualTo("tests"); op = new TestNgOperation().parallel(TestNgOperation.Parallel.METHODS); - assertThat(op.options.get("-parallel")).isEqualTo("methods"); + assertThat(op.options().get("-parallel")).isEqualTo("methods"); op = new TestNgOperation().parallel(TestNgOperation.Parallel.CLASSES); - assertThat(op.options.get("-parallel")).isEqualTo("classes"); + assertThat(op.options().get("-parallel")).isEqualTo("classes"); } @Test void testPort() { var op = new TestNgOperation().port(1); - assertThat(op.options.get("-port")).isEqualTo("1"); + assertThat(op.options().get("-port")).isEqualTo("1"); } @Test void testPropagateDataProviderFailureAsTestFailure() { var op = new TestNgOperation().propagateDataProviderFailureAsTestFailure(false); - assertThat(op.options.get("-propagateDataProviderFailureAsTestFailure")).isEqualTo("false"); + assertThat(op.options().get("-propagateDataProviderFailureAsTestFailure")).isEqualTo("false"); op = new TestNgOperation().propagateDataProviderFailureAsTestFailure(true); - assertThat(op.options.get("-propagateDataProviderFailureAsTestFailure")).isEqualTo("true"); + assertThat(op.options().get("-propagateDataProviderFailureAsTestFailure")).isEqualTo("true"); } @Test void testReported() { var op = new TestNgOperation().reporter(FOO); - assertThat(op.options.get("-reporter")).isEqualTo(FOO); + assertThat(op.options().get("-reporter")).isEqualTo(FOO); } @Test void testRunFactory() { var op = new TestNgOperation().testRunFactory(FOO); - assertThat(op.options.get("-testrunfactory")).isEqualTo(FOO); + assertThat(op.options().get("-testrunfactory")).isEqualTo(FOO); } @Test void testShareThreadPoolForDataProviders() { var op = new TestNgOperation().shareThreadPoolForDataProviders(true); - assertThat(op.options.get("-shareThreadPoolForDataProviders")).isEqualTo("true"); + assertThat(op.options().get("-shareThreadPoolForDataProviders")).isEqualTo("true"); op = new TestNgOperation().shareThreadPoolForDataProviders(false); - assertThat(op.options.get("-shareThreadPoolForDataProviders")).isNull(); + assertThat(op.options().get("-shareThreadPoolForDataProviders")).isNull(); } @Test void testSourceDir() { + var foo = new File(FOO); + var bar = new File(BAR); + + var foobar = String.format("%s;%s", FOO, BAR); var op = new TestNgOperation().sourceDir(FOO, BAR); - assertThat(op.options.get("-sourcedir")).isEqualTo(String.format("%s;%s", FOO, BAR)); + assertThat(op.options().get("-sourcedir")).as("String...").isEqualTo(foobar); op = new TestNgOperation().sourceDir(List.of(FOO, BAR)); - assertThat(op.options.get("-sourcedir")).as("as list").isEqualTo(String.format("%s;%s", FOO, BAR)); + assertThat(op.options().get("-sourcedir")).as("List(String...)").isEqualTo(foobar); + + foobar = String.format("%s;%s", foo.getAbsolutePath(), bar.getAbsolutePath()); + op = new TestNgOperation().sourceDir(foo, bar); + assertThat(op.options().get("-sourcedir")).as("File...").isEqualTo(foobar); + + op = new TestNgOperation().sourceDirFiles(List.of(foo, bar)); + assertThat(op.options().get("-sourcedir")).as("List(String...)").isEqualTo(foobar); + + op = new TestNgOperation().sourceDir(foo.toPath(), bar.toPath()); + assertThat(op.options().get("-sourcedir")).as("Path...").isEqualTo(foobar); + + op = new TestNgOperation().sourceDirPaths(List.of(foo.toPath(), bar.toPath())); + assertThat(op.options().get("-sourcedir")).as("List(Path...)").isEqualTo(foobar); } @Test void testSpiListenersToSkip() { var ops = new TestNgOperation().spiListenersToSkip(FOO, BAR); - assertThat(ops.options.get("-spilistenerstoskip")).isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-spilistenerstoskip")).isEqualTo(String.format("%s,%s", FOO, BAR)); ops = new TestNgOperation().spiListenersToSkip(List.of(FOO, BAR)); - assertThat(ops.options.get("-spilistenerstoskip")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); + assertThat(ops.options().get("-spilistenerstoskip")).as("as list").isEqualTo(String.format("%s,%s", FOO, BAR)); } @Test void testSuiteName() { var op = new TestNgOperation().suiteName(FOO); - assertThat(op.options.get("-suitename")).isEqualTo("\"" + FOO + '\"'); + assertThat(op.options().get("-suitename")).isEqualTo("\"" + FOO + '\"'); } @Test void testSuiteThreadPoolSize() { var op = new TestNgOperation().suiteThreadPoolSize(1); - assertThat(op.options.get("-suitethreadpoolsize")).isEqualTo("1"); + assertThat(op.options().get("-suitethreadpoolsize")).isEqualTo("1"); } @Test void testSuites() { var op = new TestNgOperation().suites(FOO, BAR); - assertThat(op.suites).contains(FOO).contains(BAR); + assertThat(op.suites()).contains(FOO).contains(BAR); op = new TestNgOperation().suites(List.of(FOO, BAR)); - assertThat(op.suites).as("as list").contains(FOO).contains(BAR); + assertThat(op.suites()).as("as list").contains(FOO).contains(BAR); } @Test void testThreadCount() { var op = new TestNgOperation().threadCount(1); - assertThat(op.options.get("-threadcount")).isEqualTo("1"); + assertThat(op.options().get("-threadcount")).isEqualTo("1"); } @Test void testThreadPoolFactoryClass() { var op = new TestNgOperation().threadPoolFactoryClass(FOO); - assertThat(op.options.get("-threadpoolfactoryclass")).isEqualTo(FOO); + assertThat(op.options().get("-threadpoolfactoryclass")).isEqualTo(FOO); } @Test void testUseDefaultListeners() { var op = new TestNgOperation().useDefaultListeners(false); - assertThat(op.options.get("-usedefaultlisteners")).isEqualTo("false"); + assertThat(op.options().get("-usedefaultlisteners")).isEqualTo("false"); op = new TestNgOperation().useDefaultListeners(true); - assertThat(op.options.get("-usedefaultlisteners")).isEqualTo("true"); + assertThat(op.options().get("-usedefaultlisteners")).isEqualTo("true"); } @Test void testUseGlobalThreadPool() { var op = new TestNgOperation().useGlobalThreadPool(true); - assertThat(op.options.get("-useGlobalThreadPool")).isEqualTo("true"); + assertThat(op.options().get("-useGlobalThreadPool")).isEqualTo("true"); op = new TestNgOperation().useGlobalThreadPool(false); - assertThat(op.options.get("-useGlobalThreadPool")).isNull(); + assertThat(op.options().get("-useGlobalThreadPool")).isNull(); } @Test void testVerbose() { var op = new TestNgOperation().log(1); - assertThat(op.options.get("-log")).isEqualTo("1"); + assertThat(op.options().get("-log")).isEqualTo("1"); op = new TestNgOperation().verbose(1); - assertThat(op.options.get("-verbose")).isEqualTo("1"); + assertThat(op.options().get("-verbose")).isEqualTo("1"); } @Test void testXmlPathInJar() { + var foo = new File(FOO); var op = new TestNgOperation().xmlPathInJar(FOO); - assertThat(op.options.get("-xmlpathinjar")).isEqualTo(FOO); + assertThat(op.options().get("-xmlpathinjar")).as("as string").isEqualTo(FOO); + + op = new TestNgOperation().xmlPathInJar(foo); + assertThat(op.options().get("-xmlpathinjar")).as("as file").isEqualTo(foo.getAbsolutePath()); + + op = new TestNgOperation().xmlPathInJar(foo.toPath()); + assertThat(op.options().get("-xmlpathinjar")).as("as path").isEqualTo(foo.getAbsolutePath()); } } diff --git a/src/test/resources/testng-args.txt b/src/test/resources/testng-args.txt new file mode 100644 index 0000000..8eec8d5 --- /dev/null +++ b/src/test/resources/testng-args.txt @@ -0,0 +1,38 @@ +-alwaysrunlisteners +-configfailurepolicy +-d +-dataproviderthreadcount +-dependencyinjectorfactory +-excludegroups +-failwheneverythingskipped +-generateResultsPerSuite +-groups +-ignoreMissedTestNames +-includeAllDataDrivenTestsWhenSkipping +-listener +-listenercomparator +-listenerfactory +-log +-methods +-methodselectors +-mixed +-objectfactory +-overrideincludedmethods +-parallel +-propagateDataProviderFailureAsTestFailure +-reporter +-shareThreadPoolForDataProviders +-spilistenerstoskip +-suitename +-suitethreadpoolsize +-testclass +-testjar +-testname +-testnames +-testrunfactory +-threadcount +-threadpoolfactoryclass +-usedefaultlisteners +-useGlobalThreadPool +-verbose +-xmlpathinjar diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml index 8ad378e..ef68357 100644 --- a/src/test/resources/testng.xml +++ b/src/test/resources/testng.xml @@ -3,6 +3,10 @@ + + + + \ No newline at end of file