Compare commits

...

55 commits

Author SHA1 Message Date
f43b3e18d2
Add OS matrix for Ubuntu, Windows and macOS 2025-03-25 21:48:14 -07:00
0f7a7cf090
Fix non-system specific path separator 2025-03-25 21:46:59 -07:00
9625db4b62
JDK 24 2025-03-18 23:42:02 -07:00
8d4e858035
Add generic installation instructions 2025-03-18 13:02:25 -07:00
f2b7863bb2
Bump JUnit to version 5.12.1 2025-03-18 13:00:56 -07:00
d95cb2990d
Bump PMD extension to version 1.2.1 2025-03-18 13:00:43 -07:00
b9b7b0fb44
Bump bld to version 2.2.1 2025-02-24 23:21:06 -08:00
98ea8a7812
Bump JUnit to version 5.12.0 2025-02-24 23:20:51 -08:00
4a0ad1aebe
Version 1.0.2 2025-02-12 23:00:19 -08:00
f12eb82f99
Bump TestNG to 7.11.0 2025-02-12 22:58:44 -08:00
8e2a2fa2fd
Fix copyright template 2025-02-12 22:57:38 -08:00
0133572c46
Bump AssertJ to version 3.27.3 2025-02-12 22:55:11 -08:00
c72607ff65
Bump PMD extension to 1.2.0 2025-02-12 22:49:34 -08:00
69cf0da32a
Update pages action to latest versions 2025-02-12 22:48:11 -08:00
d41df03d08
Version 1.0.1 2025-01-14 11:45:21 -08:00
e4c47afcfc
Updated copyright for 2025 2025-01-14 11:45:09 -08:00
8632c7525c
Bumped bld to version 2.2.0 2025-01-14 11:42:49 -08:00
69d20a0ed1
Bumped Exec extension to version 1.0.4 2025-01-14 11:36:12 -08:00
d59d109aa9
Bumped Jacoco extension to version 0.9.9 2025-01-14 11:36:12 -08:00
251c8abb6a
Bumped AssertJ to version 3.27.2 2025-01-14 11:31:44 -08:00
61d32ca117
Bumped PMD extension to version 1.1.9 2024-12-28 18:13:59 -08:00
807ccffe0e
Bumped JUnit to version 5.11.4 2024-12-28 18:13:38 -08:00
1ff935aa7e
Bumped AssertJ to version 3.27.0 2024-12-28 18:13:16 -08:00
0f5dae6cdc
Updated dependencies
Updated dependencies

Bumped JUnit version to 5.11.3
Bumped PMD extension version to 1.1.7
Bumped JDK to version 23 (GitHub CI Workflow)
2024-10-28 10:15:48 -07:00
a46ad60a66
Added GitHub repository 2024-10-28 10:14:38 -07:00
450c2df0f5
Added soft assertions 2024-10-28 10:13:14 -07:00
e2695625fd
Version 1.0.0 2024-08-30 13:38:04 -07:00
f2cf1b18bb
Minor cleanups 2024-08-30 13:37:43 -07:00
fd950f223d
Updated extensions dependencies 2024-08-30 13:07:22 -07:00
c35b3cefcd
Bumped bld to version 2.1.0 2024-08-29 22:42:11 -07:00
4e44484157
Cleaned up API to match bld operations aand options APIs 2024-08-28 14:10:22 -07:00
994bc399d6
Bumpled JUnit to version 5.11.0 2024-08-28 14:07:45 -07:00
d4931cc3af
Version 0.9.9 2024-07-28 23:02:18 -07:00
f462b1eca8
Bumpled bld to version 2.0.1 2024-07-28 22:56:38 -07:00
1ebc093bbc
Bumped bld to version 2.0.0-SNAPSHOT 2024-07-23 08:35:29 -07:00
0cb08be61a
Bumped PMD extension to version 1.1.2 2024-07-03 16:00:26 -07:00
7aedfc790e
Added array for the methods argument 2024-06-27 20:34:43 -07:00
8db60b473c
Log error messages and throw exit status exceptions to stop processing 2024-06-27 20:33:04 -07:00
4fa74c3efd
Bumped JUnit to version 5.10.3 2024-06-27 20:19:24 -07:00
177ad3d961
Added methods to access the map of options and sets 2024-06-22 21:13:28 -07:00
057bb39247
Bumped extensions depdencies
Exec extension to version 1.0.1
JaCoCo extension to version 0.9.5
PMD extension to version 1.1.0
2024-06-22 21:11:16 -07:00
0156100013
Execute cliargs script before running tests 2024-05-28 14:22:50 -07:00
cd34bb182c
Cleaned up cliargs script 2024-05-27 22:51:12 -07:00
0a869da1d5
Read parameters from resource file 2024-05-27 20:27:15 -07:00
b0cf0f5035
Added script to list parameters 2024-05-27 16:22:55 -07:00
6020dde8eb
Added test to check all parameters 2024-05-26 14:52:58 -07:00
273dbc014b
Bumped assertj-core to version 3.26.0 2024-05-26 14:48:31 -07:00
a5ce6ab0ec
Fixed report file location URL 2024-05-11 15:22:17 -07:00
cf879d30db
Bumped bld to version 1.9.1 2024-05-09 21:33:28 -07:00
b1db44062a
Added support for TestNG 7.10.2 2024-04-28 09:44:15 -07:00
155052a861
Bumped PMD extensions to version 0.9.9 2024-04-28 09:41:19 -07:00
f822d4489e
Bumped TestNG to version 7.10.1 2024-04-09 13:35:35 -07:00
d74ee9d819
Added supprot for TestNG 7.10.0 2024-04-07 14:23:35 -07:00
645e6d104a
Added visual diff parameter 2024-04-07 14:23:07 -07:00
f9cbd63bce
Only log java command and arguments on Level.FINE 2024-04-04 02:34:23 -07:00
35 changed files with 754 additions and 304 deletions

View file

@ -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

View file

@ -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

1
.gitignore vendored
View file

@ -55,3 +55,4 @@ atlassian-ide-plugin.xml
.idea/httpRequests
local.properties
test-output

6
.idea/bld.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

View file

@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright 2023-Copyright &amp;#36;today.yearamp;#36;today.year the original author or authors.&#10; &#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; https://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="notice" value="Copyright 2023-&amp;#36;today.year the original author or authors.&#10; &#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; https://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
<option name="myName" value="Apache License" />
</copyright>
</component>
</component>

13
.idea/icon.svg generated Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 179 108" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-210.511,-96.3382)">
<g transform="matrix(1,0,0,1,-23.3386,-649.816)">
<g transform="matrix(0.221288,0,0,0.24,73.9536,390.254)">
<path d="M722.568,1482.92L722.568,1921.1L808.968,1921.1L808.968,1888.7C822.168,1907.9 846.168,1930.1 893.568,1930.1C933.168,1930.1 961.968,1917.5 985.368,1893.5C1012.97,1865.9 1027.37,1827.5 1027.37,1786.1C1027.37,1741.7 1011.17,1705.1 985.368,1680.5C961.968,1658.3 928.968,1644.5 892.368,1644.5C862.968,1644.5 830.568,1654.1 808.968,1683.5L808.968,1482.92L722.568,1482.92ZM871.368,1718.9C888.768,1718.9 903.768,1723.7 917.568,1736.9C930.168,1748.9 938.568,1766.3 938.568,1787.9C938.568,1807.7 930.168,1825.1 917.568,1837.1C904.368,1849.7 887.568,1855.7 872.568,1855.7C856.368,1855.7 837.168,1849.1 823.368,1835.9C813.168,1826.3 803.568,1810.1 803.568,1787.9C803.568,1765.1 812.568,1749.5 822.768,1738.7C836.568,1724.3 852.768,1718.9 871.368,1718.9Z" style="fill:rgb(35,146,255);fill-rule:nonzero;"/>
<rect x="1083.77" y="1482.92" width="86.4" height="438.182" style="fill:rgb(250,144,82);fill-rule:nonzero;"/>
<path d="M1531.37,1482.92L1444.97,1482.92L1444.97,1683.5C1423.37,1654.1 1390.97,1644.5 1361.57,1644.5C1324.97,1644.5 1291.97,1658.3 1268.57,1680.5C1242.77,1705.1 1226.57,1741.7 1226.57,1786.1C1226.57,1827.5 1240.97,1865.9 1268.57,1893.5C1291.97,1917.5 1320.77,1930.1 1360.37,1930.1C1407.77,1930.1 1431.77,1907.9 1444.97,1888.7L1444.97,1921.1L1531.37,1921.1L1531.37,1482.92ZM1382.57,1718.9C1401.17,1718.9 1417.37,1724.3 1431.17,1738.7C1441.37,1749.5 1450.37,1765.1 1450.37,1787.9C1450.37,1810.1 1440.77,1826.3 1430.57,1835.9C1416.77,1849.1 1397.57,1855.7 1381.37,1855.7C1366.37,1855.7 1349.57,1849.7 1336.37,1837.1C1323.77,1825.1 1315.37,1807.7 1315.37,1787.9C1315.37,1766.3 1323.77,1748.9 1336.37,1736.9C1350.17,1723.7 1365.17,1718.9 1382.57,1718.9Z" style="fill:rgb(35,146,255);fill-rule:nonzero;"/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -2,12 +2,12 @@
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-1.9.0.jar!/" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-1.9.0-sources.jar!/" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />

View file

@ -7,7 +7,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -8,7 +8,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -8,7 +8,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -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"
]
}

View file

@ -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,6 +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, 9, 0)));
scope(test).include(dependency("org.testng", "testng", version(7, 11, 0)));
```

View file

@ -1,12 +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
diff $TMPOLD $TMPNEW
rm -rf $TMPNEW $TMPOLD

View file

@ -7,9 +7,9 @@
<!-- BEST PRACTICES -->
<rule ref="category/java/bestpractices.xml">
<exclude name="AvoidPrintStackTrace"/>
<exclude name="JUnit4TestShouldUseTestAnnotation"/>
<exclude name="JUnitTestContainsTooManyAsserts"/>
<exclude name="GuardLogStatement"/>
<exclude name="UnitTestContainsTooManyAsserts"/>
<exclude name="UnitTestShouldUseTestAnnotation"/>
</rule>
<rule ref="category/java/bestpractices.xml/MissingOverride">

6
examples/.idea/bld.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

View file

@ -2,12 +2,12 @@
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-1.9.0.jar!/" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-1.9.0-sources.jar!/" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />

View file

@ -7,7 +7,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -8,7 +8,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -8,7 +8,7 @@
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -3,6 +3,10 @@
<component name="EntryPointsManager">
<pattern value="com.example.ExamplesBuild" method="testng" />
<pattern value="com.example.ExampleTest" method="testFail" />
<pattern value="com.example.ExamplesBuild" method="jacoco" />
<pattern value="com.example.ExamplesTest" />
<pattern value="com.example.ExamplesTest" method="foo" />
<pattern value="com.example.ExamplesTest" method="verifyHello" />
</component>
<component name="PDMPlugin">
<option name="customRuleSets">

View file

@ -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"
]
}

Binary file not shown.

View file

@ -1,8 +1,8 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.extensions=com.uwyn.rife2:bld-testng:0.9.5
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

View file

@ -6,8 +6,10 @@ 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;
import java.util.logging.Logger;
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
import static rife.bld.dependencies.Scope.test;
@ -15,41 +17,52 @@ import static rife.bld.dependencies.Scope.test;
/**
* Example build.
*
* <ul style="list-style-type:none">
* <li>{@code ./bld compile test}</li>
* <li>{@code ./bld compile jacoco}</li>
* </ul>
* <pre>{@code
* ./bld compile test
* ./bld compile jacoco
* }</pre>
*/
public class ExamplesBuild extends BaseProject {
@Override
public TestOperation<?, ?> testOperation() {
return new TestNgOperation()
.fromProject(this)
.packages("com.example");
}
public ExamplesBuild() {
pkg = "com.example";
name = "Examples";
version = version(0, 1, 0);
javaRelease = 17;
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL);
scope(test).include(dependency("org.testng", "testng", version(7, 9, 0)));
scope(test).include(dependency("org.testng", "testng", version(7, 11, 0)));
}
public static void main(String[] args) {
// Enable detailed logging for the JaCoCo extension
var level = Level.ALL;
var logger = Logger.getLogger("rife.bld.extension");
var consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(level);
logger.addHandler(consoleHandler);
logger.setLevel(level);
logger.setUseParentHandlers(false);
new ExamplesBuild().start(args);
}
@BuildCommand(summary = "Generates Jacoco Reports")
public void jacoco() throws IOException {
public void jacoco() throws Exception {
new JacocoReportOperation()
.fromProject(this)
.execute();
}
@Override
public TestOperation<?, ?> testOperation() {
return new TestNgOperation()
.fromProject(this)
.packages("com.example");
}
}

Binary file not shown.

View file

@ -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

16
scripts/checkcliargs.sh Executable file
View file

@ -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

9
scripts/cliargs.sh Executable file
View file

@ -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"

View file

@ -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, 5);
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, 9, 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();
}
}

View file

@ -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<TestNgOperation, List<String>> {
private static final Logger LOGGER = Logger.getLogger(TestNgOperation.class.getName());
/**
* The methods to run.
*/
private final Set<String> methods_ = new HashSet<>();
/**
* The run options.
*/
protected final Map<String, String> options = new ConcurrentHashMap<>();
private final Map<String, String> options_ = new ConcurrentHashMap<>();
/**
* The suite packages to run.
*/
protected final Set<String> packages = new HashSet<>();
private final Set<String> packages_ = new HashSet<>();
/**
* The suites to run.
*/
protected final Set<String> suites = new HashSet<>();
private final Set<String> suites_ = new HashSet<>();
/**
* The classpath entries used for running tests.
*/
protected final Set<String> testClasspath = new HashSet<>();
private BaseProject project;
private final Set<String> 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<TestNgOperation, List<String>
* @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<TestNgOperation, List<String>
*/
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<TestNgOperation, List<String>
*/
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<TestNgOperation, List<String>
*/
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
*
* <p>Default is {@code build/test-output})</p>
*
* @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
*
* <p>Default is {@code build/test-output})</p>
*
* @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<TestNgOperation, List<String>
* @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,60 +174,90 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #excludeGroups(String...) #excludeGroups(String...)
*/
public TestNgOperation excludeGroups(Collection<String> 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<String> 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<String> 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.INFO)) {
LOGGER.info(String.join(" ", args));
LOGGER.info(String.format("Report will be saved in file://%s", new File(options.get("-d"))));
args.add(javaTool());
args.addAll(javaOptions());
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;
@ -200,7 +271,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
@Override
public TestNgOperation fromProject(BaseProject project) {
this.project = project;
project_ = project;
directory(Path.of(project.buildDirectory().getPath(), "test-output").toString());
return this;
}
@ -212,7 +283,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation failWhenEverythingSkipped(Boolean isFailAllSkipped) {
options.put("-failwheneverythingskipped", String.valueOf(isFailAllSkipped));
options_.put("-failwheneverythingskipped", String.valueOf(isFailAllSkipped));
return this;
}
@ -224,12 +295,13 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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 consider failures in Data Providers as test failures.
* Should TestNG generate results on a per-suite basis by creating a subdirectory for each suite and dumping
* results into it.
*
* <p>Default is {@code false}</p>.
*
@ -237,7 +309,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation generateResultsPerSuite(Boolean resultsPerSuite) {
options.put("-generateResultsPerSuite", String.valueOf(resultsPerSuite));
options_.put("-generateResultsPerSuite", String.valueOf(resultsPerSuite));
return this;
}
@ -251,8 +323,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -265,7 +336,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #groups(String...) #groups(String...)
*/
public TestNgOperation groups(Collection<String> 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;
}
@ -279,7 +350,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation ignoreMissedTestName(Boolean isIgnoreMissedTestNames) {
options.put("-ignoreMissedTestNames", String.valueOf(isIgnoreMissedTestNames));
options_.put("-ignoreMissedTestNames", String.valueOf(isIgnoreMissedTestNames));
return this;
}
@ -292,7 +363,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation includeAllDataDrivenTestsWhenSkipping(Boolean isIncludeDrivenTestsWhenSkipping) {
options.put("-includeAllDataDrivenTestsWhenSkipping", String.valueOf(isIncludeDrivenTestsWhenSkipping));
options_.put("-includeAllDataDrivenTestsWhenSkipping", String.valueOf(isIncludeDrivenTestsWhenSkipping));
return this;
}
@ -312,10 +383,18 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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<File> 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}
@ -325,8 +404,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -338,7 +416,30 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #listener(String...) #listener(String...)
*/
public TestNgOperation listener(Collection<String> 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;
}
/**
* An implementation of {@code ListenerComparator} that will be used by TestNG to determine order of execution for
* listeners.
*
* @param listenerComparator the listener comparator
* @return this operation instance
*/
public TestNgOperation listenerComparator(String listenerComparator) {
options_.put("-listenercomparator", listenerComparator);
return this;
}
/**
* The factory used to create TestNG listeners.
*
* @param listenerFactory the listener factory
* @return this operation instance
*/
public TestNgOperation listenerFactory(String listenerFactory) {
options_.put("-listenerfactory", listenerFactory);
return this;
}
@ -351,7 +452,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation log(int level) {
if (level >= 0) {
options.put("-log", String.valueOf(level));
options_.put("-log", String.valueOf(level));
}
return this;
}
@ -366,9 +467,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -381,7 +480,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #methodSelectors(String...) #methodSelectors(String...)
*/
public TestNgOperation methodSelectors(Collection<String> 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;
}
@ -395,8 +494,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -409,10 +507,19 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #methods(String...) #methods(String...)
*/
public TestNgOperation methods(Collection<String> 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<String> methods() {
return methods_;
}
/**
* Mixed mode autodetects the type of current test and run it with appropriate runner.
*
@ -422,34 +529,48 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation mixed(Boolean isMixed) {
options.put("-mixed", String.valueOf(isMixed));
options_.put("-mixed", String.valueOf(isMixed));
return this;
}
/**
* The list of {@code .class} files or class names implementing {@code ITestRunnerFactory}.
* <p>
* 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}.
* <p>
* 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<String> 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<String, String> options() {
return options_;
}
/**
* The list of fully qualified class names of listeners that should be skipped from being wired in via
* Service Loaders.
@ -459,9 +580,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -473,7 +592,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #overrideIncludedMethods(String...) #overrideIncludedMethods(String...)
*/
public TestNgOperation overrideIncludedMethods(Collection<String> 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;
}
@ -489,8 +608,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -505,10 +623,19 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #packages(String...) #packages(String...)
*/
public TestNgOperation packages(Collection<String> 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<String> 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.
@ -519,7 +646,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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;
}
@ -531,7 +658,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation port(int port) {
if (port >= 1) {
options.put("-port", String.valueOf(port));
options_.put("-port", String.valueOf(port));
}
return this;
}
@ -545,7 +672,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation propagateDataProviderFailureAsTestFailure(Boolean isPropagateDataProviderFailure) {
options.put("-propagateDataProviderFailureAsTestFailure", String.valueOf(isPropagateDataProviderFailure));
options_.put("-propagateDataProviderFailureAsTestFailure", String.valueOf(isPropagateDataProviderFailure));
return this;
}
@ -557,7 +684,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation reporter(String reporter) {
if (isNotBlank(reporter)) {
options.put("-reporter", reporter);
options_.put("-reporter", reporter);
}
return this;
}
@ -570,7 +697,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation shareThreadPoolForDataProviders(boolean shareThreadPoolForDataProviders) {
if (shareThreadPoolForDataProviders) {
options.put("-shareThreadPoolForDataProviders", String.valueOf(shareThreadPoolForDataProviders));
options_.put("-shareThreadPoolForDataProviders", "true");
}
return this;
}
@ -582,10 +709,49 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*
* @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<String> directory) {
options_.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList()));
return this;
}
@ -596,11 +762,23 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*
* @param directory the list of directories
* @return this operation instance
* @see #sourceDir(String...) #sourceDir(String...)
* @see #sourceDir(File...)
*/
public TestNgOperation sourceDir(Collection<String> directory) {
options.put("-sourcedir", String.join(";", directory.stream().filter(this::isNotBlank).toList()));
return this;
public TestNgOperation sourceDirFiles(Collection<File> 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<Path> directory) {
return sourceDirFiles(directory.stream().map(Path::toFile).toList());
}
/**
@ -612,9 +790,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -626,7 +802,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #spiListenersToSkip(String...) #spiListenersToSkip(String...)
*/
public TestNgOperation spiListenersToSkip(Collection<String> listenerToSkip) {
options.put("-spilistenerstoskip",
options_.put("-spilistenerstoskip",
String.join(",", listenerToSkip.stream().filter(this::isNotBlank).toList()));
return this;
}
@ -640,7 +816,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation suiteName(String name) {
if (isNotBlank(name)) {
options.put("-suitename", '"' + name + '"');
options_.put("-suitename", '"' + name + '"');
}
return this;
}
@ -654,7 +830,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation suiteThreadPoolSize(int poolSize) {
if (poolSize >= 0) {
options.put("-suitethreadpoolsize", String.valueOf(poolSize));
options_.put("-suitethreadpoolsize", String.valueOf(poolSize));
}
return this;
}
@ -669,8 +845,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -683,10 +858,19 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #suites(String...) #suites(String...)
*/
public TestNgOperation suites(Collection<String> 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<String> suites() {
return suites_;
}
/**
* Create a test file and delete it on exit.
*
@ -708,8 +892,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -722,7 +905,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #testClass(String...) #testClass(String...)
*/
public TestNgOperation testClass(Collection<String> 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;
}
@ -734,8 +917,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -746,10 +928,19 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #testClasspath(String...) #testClasspath(String...)
*/
public TestNgOperation testClasspath(Collection<String> 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<String> 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
@ -760,7 +951,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation testJar(String jar) {
if (isNotBlank(jar)) {
options.put("-testjar", jar);
options_.put("-testjar", jar);
}
return this;
}
@ -774,7 +965,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation testName(String name) {
if (isNotBlank(name)) {
options.put("-testname", '"' + name + '"');
options_.put("-testname", '"' + name + '"');
}
return this;
}
@ -787,9 +978,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @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));
}
/**
@ -800,7 +989,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @see #testName(String) #testName(String)
*/
public TestNgOperation testNames(Collection<String> name) {
options.put("-testnames",
options_.put("-testnames",
name.stream().filter(this::isNotBlank).map(s -> '"' + s + '"').collect(Collectors.joining(",")));
return this;
}
@ -813,7 +1002,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation testRunFactory(String factory) {
if (isNotBlank(factory)) {
options.put("-testrunfactory", factory);
options_.put("-testrunfactory", factory);
}
return this;
}
@ -828,7 +1017,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation threadCount(int count) {
if (count >= 0) {
options.put("-threadcount", String.valueOf(count));
options_.put("-threadcount", String.valueOf(count));
}
return this;
}
@ -841,7 +1030,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation threadPoolFactoryClass(String factoryClass) {
if (isNotBlank(factoryClass)) {
options.put("-threadpoolfactoryclass", factoryClass);
options_.put("-threadpoolfactoryclass", factoryClass);
}
return this;
}
@ -855,7 +1044,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
* @return this operation instance
*/
public TestNgOperation useDefaultListeners(Boolean isDefaultListener) {
options.put("-usedefaultlisteners", String.valueOf(isDefaultListener));
options_.put("-usedefaultlisteners", String.valueOf(isDefaultListener));
return this;
}
@ -867,7 +1056,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation useGlobalThreadPool(boolean useGlobalThreadPool) {
if (useGlobalThreadPool) {
options.put("-useGlobalThreadPool", String.valueOf(useGlobalThreadPool));
options_.put("-useGlobalThreadPool", "true");
}
return this;
}
@ -881,7 +1070,7 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
public TestNgOperation verbose(int level) {
if (level >= 0) {
options.put("-verbose", String.valueOf(level));
options_.put("-verbose", String.valueOf(level));
}
return this;
}
@ -890,11 +1079,11 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
var temp = tempFile();
try (var bufWriter = Files.newBufferedWriter(Paths.get(temp.getPath()))) {
bufWriter.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<!DOCTYPE suite SYSTEM \"https://testng.org/testng-1.0.dtd\">" +
"<suite name=\"bld Default Suite\" verbose=\"2\">" +
"<test name=\"All Packages\">" +
"<packages>");
for (var p : packages) {
"<!DOCTYPE suite SYSTEM \"https://testng.org/testng-1.0.dtd\">" +
"<suite name=\"bld Default Suite\" verbose=\"2\">" +
"<test name=\"All Packages\">" +
"<packages>");
for (var p : packages_) {
bufWriter.write(String.format("<package name=\"%s\"/>", p));
}
bufWriter.write("</packages></test></suite>");
@ -912,11 +1101,35 @@ public class TestNgOperation extends TestOperation<TestNgOperation, List<String>
*/
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
*/

View file

@ -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 <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.0
*/
@SuppressWarnings("PMD.TestClassWithoutTestCases")
@SuppressWarnings({"PMD.TestClassWithoutTestCases", "unused"})
class TestNgExample {
@SuppressWarnings("SameReturnValue")
public String getMessage() {
return "Hello World!";
}

View file

@ -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 <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.0
*/
@SuppressWarnings("unused")
class TestNgExampleTest {
private final TestNgExample example = new TestNgExample();

View file

@ -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 rife.bld.Project; // NOPMD
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());
}
}

View file

@ -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

View file

@ -3,6 +3,10 @@
<test name="simple test">
<classes>
<class name="rife.bld.extension.TestNgExample"/>
<methods>
<exclude name="foo"/>
</methods>
</class>
</classes>
</test>
</suite>