Skip to content

Commit

Permalink
Merge branch 'main' into feature/enable-specific-global-extensions-in…
Browse files Browse the repository at this point in the history
…-junit
  • Loading branch information
YongGoose authored Nov 29, 2024
2 parents 13645f0 + 5f1159d commit 9daa88a
Show file tree
Hide file tree
Showing 213 changed files with 3,054 additions and 1,488 deletions.
2 changes: 1 addition & 1 deletion .github/actions/run-gradle/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ runs:
distribution: temurin
java-version: 21
check-latest: true
- uses: gradle/actions/setup-gradle@473878a77f1b98e2b5ac4af93489d1656a80a5ed # v4
- uses: gradle/actions/setup-gradle@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4
with:
cache-encryption-key: ${{ inputs.encryptionKey }}
- shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
- name: Check out repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Initialize CodeQL
uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3
uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3
with:
languages: ${{ matrix.language }}
tools: linked
Expand All @@ -47,4 +47,4 @@ jobs:
-Dscan.tag.CodeQL \
allMainClasses
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3
uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3
2 changes: 1 addition & 1 deletion .github/workflows/gradle-dependency-submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ jobs:
java-version: 21
check-latest: true
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@473878a77f1b98e2b5ac4af93489d1656a80a5ed # v4
uses: gradle/actions/dependency-submission@cc4fc85e6b35bafd578d5ffbc76a5518407e1af0 # v4
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
jacocoRootReport \
--no-configuration-cache # Disable configuration cache due to https://github.com/diffplug/spotless/issues/2318
- name: Upload to Codecov.io
uses: codecov/codecov-action@5c47607acb93fed5485fdbf7232e8a31425f672a # v5
uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ossf-scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3
with:
sarif_file: results.sarif
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ gradle-app.setting
coverage.db*
.metadata
/.sdkmanrc
/.tool-versions

checksums*
10 changes: 4 additions & 6 deletions documentation/documentation.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import junitbuild.javadoc.ModuleSpecificJavadocFileOption
import org.asciidoctor.gradle.base.AsciidoctorAttributeProvider
import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask
import org.gradle.api.tasks.PathSensitivity.RELATIVE
import java.nio.file.Files
import org.jetbrains.kotlin.incremental.deleteRecursivelyOrThrow

plugins {
alias(libs.plugins.asciidoctorConvert)
Expand Down Expand Up @@ -147,7 +147,7 @@ tasks {

val consoleLauncherTestReportsDir = project.layout.buildDirectory.dir("console-launcher-test-results")
val consoleLauncherTestEventXmlFiles =
files(consoleLauncherTestReportsDir.map { it.asFileTree.matching { include("junit-platform-events-*.xml") } })
files(consoleLauncherTestReportsDir.map { it.asFileTree.matching { include("**/open-test-report.xml") } })

val consoleLauncherTest by registering(RunConsoleLauncher::class) {
args.addAll("execute")
Expand All @@ -157,7 +157,6 @@ tasks {
argumentProviders.add(CommandLineArgumentProvider {
listOf(
"--reports-dir=${consoleLauncherTestReportsDir.get()}",
"--config=junit.platform.reporting.output.dir=${consoleLauncherTestReportsDir.get()}",
)
})
args.addAll("--include-classname", ".*Tests")
Expand All @@ -166,16 +165,15 @@ tasks {
args.addAll("--exclude-tag", "timeout")

doFirst {
consoleLauncherTestEventXmlFiles.files.forEach {
Files.delete(it.toPath())
}
consoleLauncherTestReportsDir.get().asFile.deleteRecursivelyOrThrow()
}

finalizedBy(generateOpenTestHtmlReport)
}

generateOpenTestHtmlReport {
mustRunAfter(consoleLauncherTest)
inputs.files(consoleLauncherTestEventXmlFiles).withPathSensitivity(RELATIVE).skipWhenEmpty()
argumentProviders += CommandLineArgumentProvider {
consoleLauncherTestEventXmlFiles.files.map { it.absolutePath }.toList()
}
Expand Down
3 changes: 3 additions & 0 deletions documentation/src/docs/asciidoc/link-attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ endif::[]
:DiscoverySelectors_selectPackage: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/DiscoverySelectors.html#selectPackage(java.lang.String)[selectPackage]
:DiscoverySelectors_selectUniqueId: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/DiscoverySelectors.html#selectUniqueId(java.lang.String)[selectUniqueId]
:DiscoverySelectors_selectUri: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/DiscoverySelectors.html#selectUri(java.lang.String)[selectUri]
:EngineDiscoveryRequest: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/EngineDiscoveryRequest.html[EngineDiscoveryRequest]
:FileSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/FileSelector.html[FileSelector]
:HierarchicalTestEngine: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/support/hierarchical/HierarchicalTestEngine.html[HierarchicalTestEngine]
:IterationSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/IterationSelector.html[IterationSelector]
:MethodSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/MethodSelector.html[MethodSelector]
:ModuleSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/ModuleSelector.html[ModuleSelector]
:NestedClassSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/NestedClassSelector.html[NestedClassSelector]
:NestedMethodSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/NestedMethodSelector.html[NestedMethodSelector]
:OutputDirectoryProvider: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/reporting/OutputDirectoryProvider.html[OutputDirectoryProvider]
:PackageSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/PackageSelector.html[PackageSelector]
:ParallelExecutionConfigurationStrategy: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/support/hierarchical/ParallelExecutionConfigurationStrategy.html[ParallelExecutionConfigurationStrategy]
:UniqueIdSelector: {javadoc-root}/org.junit.platform.engine/org/junit/platform/engine/discovery/UniqueIdSelector.html[UniqueIdSelector]
Expand Down Expand Up @@ -128,6 +130,7 @@ endif::[]
:Execution: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Execution.html[@Execution]
:Isolated: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Isolated.html[@Isolated]
:ResourceLock: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/ResourceLock.html[@ResourceLock]
:ResourceLockTarget: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/ResourceLockTarget.html[ResourceLockTarget]
:ResourceLocksProvider: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/ResourceLocksProvider.html[ResourceLocksProvider]
:Resources: {javadoc-root}/org.junit.jupiter.api/org/junit/jupiter/api/parallel/Resources.html[Resources]
// Jupiter Extension APIs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ on GitHub.
[[release-notes-5.11.2-junit-platform-bug-fixes]]
==== Bug Fixes

* Fix regression in parallel execution that was introduced in 5.10.4/5.11.1 regarding
global read-write locks. When such a lock was declared on descendants of top-level nodes
in the test tree, such as Cucumber scenarios, test execution failed.
* Fix regression in parallel execution that was introduced in 5.11.1 regarding global
read-write locks. When such a lock was declared on descendants of top-level nodes in the
test tree, such as Cucumber scenarios, test execution failed.


[[release-notes-5.11.2-junit-jupiter]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ JUnit repository on GitHub.
[[release-notes-5.12.0-M1-junit-platform-bug-fixes]]
==== Bug Fixes

* Fix support for disabling ANSI colors on the console when the `NO_COLOR` environment
variable is available.
* Enable auto-flushing of output in the `ConsoleLauncher` to fix issues with buffering,
in particular when using the `--details=testfeed` option.

[[release-notes-5.12.0-M1-junit-platform-deprecations-and-breaking-changes]]
==== Deprecations and Breaking Changes
Expand All @@ -38,11 +38,16 @@ JUnit repository on GitHub.
`--select-file` and `--select-resource`.
* `ConsoleLauncher` now accepts multiple values for all `--select` options.
* Add `--select-unique-id` support to ConsoleLauncher.
* Add `getOutputDirectoryProvider()` method to `EngineDiscoveryRequest` and `TestPlan` to
allow test engines to publish/attach files to containers and tests by calling
`EngineExecutionListener.fileEntryPublished(...)`. Registered `TestExecutionListeners`
can then access these files by overriding the `fileEntryPublished(...)` method.
* The following improvements have been made to the open-test-reporting XML output:
- Information about the Git repository, the current branch, the commit hash, and the
current worktree status are now included in the XML report, if applicable.
- A section containing JUnit-specific metadata about each test/container to the HTML
report is now written by open-test-reporting when added to the classpath/module path
- Information about published files is now included as attachments.


[[release-notes-5.12.0-M1-junit-jupiter]]
Expand Down Expand Up @@ -85,10 +90,13 @@ JUnit repository on GitHub.
* Extensions based on `TestTemplateInvocationContextProvider` can now allow returning zero
invocation contexts by overriding the new `mayReturnZeroTestTemplateInvocationContexts`
method.
* The new `@ParameterizedTest(requireArguments = false)` attribute allows to specify that
the absence of arguments is expected in some cases and should not cause a test failure.
* The new `@ParameterizedTest(allowZeroInvocations = true)` attribute allows to specify that
the absence of invocations is expected in some cases and should not cause a test failure.
* Allow determining "shared resources" at runtime via the new `@ResourceLock#providers`
attribute that accepts implementations of `ResourceLocksProvider`.
* Allow declaring "shared resources" for _direct_ child nodes via the new
`@ResourceLock(target = CHILDREN)` attribute. This may improve parallelization when
a test class declares a `READ` lock, but only a few methods hold a `READ_WRITE` lock.
* Extensions that implement `TestInstancePreConstructCallback`, `TestInstanceFactory`,
`TestInstancePostProcessor`, `ParameterResolver`, or `InvocationInterceptor` may
override the `getTestInstantiationExtensionContextScope()` method to enable receiving
Expand All @@ -107,6 +115,8 @@ JUnit repository on GitHub.
* When enabled via the `junit.jupiter.execution.timeout.threaddump.enabled` configuration
parameter, an implementation of `PreInterruptCallback` is registered that writes a
thread dump to `System.out` prior to interrupting a test thread due to a timeout.
* `TestReporter` now allows publishing files for a test method or test class which can be
used to include them in test reports, such as the Open Test Reporting format.


[[release-notes-5.12.0-M1-junit-vintage]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,46 @@

The `junit-platform-reporting` artifact contains `{TestExecutionListener}` implementations
that generate XML test reports in two flavors:
<<junit-platform-reporting-legacy-xml, legacy>> and
<<junit-platform-reporting-open-test-reporting, Open Test Reporting>>.
<<junit-platform-reporting-open-test-reporting, Open Test Reporting>> and
<<junit-platform-reporting-legacy-xml, legacy>>.

NOTE: The module also contains other `TestExecutionListener` implementations that can be
used to build custom reporting. See <<running-tests-listeners>> for details.

[[junit-platform-reporting-legacy-xml]]
==== Legacy XML format
[[junit-platform-reporting-output-directory]]
==== Output Directory

`{LegacyXmlReportGeneratingListener}` generates a separate XML report for each root in the
`{TestPlan}`. Note that the generated XML format is compatible with the de facto standard
for JUnit 4 based test reports that was made popular by the Ant build system.
The JUnit Platform provides an `{OutputDirectoryProvider}` via
`{EngineDiscoveryRequest}` and `{TestPlan}` to registered <<test-engines, test engines>>
and <<running-tests-listeners, listeners>>, respectively. Its root directory can be
configured via the following <<running-tests-config-params, configuration parameter>>:

The `LegacyXmlReportGeneratingListener` is used by the <<running-tests-console-launcher>>
as well.
`junit.platform.reporting.output.dir=<path>`::
Configure the output directory for reporting. By default, `build` is used if a Gradle
build script is found, and `target` if a Maven POM is found; otherwise, the current
working directory is used.

To create a unique output directory per test run, you can use the `\{uniqueNumber}`
placeholder in the path. For example, `reports/junit-\{uniqueNumber}` will create
directories like `reports/junit-8803697269315188212`. This can be useful when using
Gradle's or Maven's parallel execution capabilities which create multiple JVM forks
that run concurrently.

[[junit-platform-reporting-open-test-reporting]]
==== Open Test Reporting XML format
==== Open Test Reporting

`{OpenTestReportGeneratingListener}` writes an XML report for the entire execution in the
event-based format specified by {OpenTestReporting} which supports all features of the
JUnit Platform such as hierarchical test structures, display names, tags, etc.

The listener is auto-registered and can be configured via the following
<<running-tests-config-params>>:
<<running-tests-config-params, configuration parameter>>:

`junit.platform.reporting.open.xml.enabled=true|false`::
Enable/disable writing the report.
`junit.platform.reporting.output.dir=<path>`::
Configure the output directory for the reports. By default, `build` is used if a Gradle
build script is found, and `target` if a Maven POM is found; otherwise, the current
working directory is used.

If enabled, the listener creates an XML report file named
`junit-platform-events-<random-id>.xml` per test run in the configured output directory.
If enabled, the listener creates an XML report file named `open-test-report.xml` in the
configured <<junit-platform-reporting-output-directory, output directory>>.

TIP: The {OpenTestReportingCliTool} can be used to convert from the event-based format to
the hierarchical format which is more human-readable.
Expand Down Expand Up @@ -145,3 +150,13 @@ via the `--config-resource` option:
$ java -jar junit-platform-console-standalone-{platform-version}.jar <OPTIONS> \
--config-resource=configuration.properties
----

[[junit-platform-reporting-legacy-xml]]
==== Legacy XML format

`{LegacyXmlReportGeneratingListener}` generates a separate XML report for each root in the
`{TestPlan}`. Note that the generated XML format is compatible with the de facto standard
for JUnit 4 based test reports that was made popular by the Ant build system.

The `LegacyXmlReportGeneratingListener` is used by the <<running-tests-console-launcher>>
as well.
29 changes: 26 additions & 3 deletions documentation/src/docs/asciidoc/user-guide/writing-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1077,8 +1077,9 @@ include::{testDir}/example/TestInfoDemo.java[tags=user_guide]
* `{TestReporterParameterResolver}`: if a constructor or method parameter is of type
`{TestReporter}`, the `TestReporterParameterResolver` will supply an instance of
`TestReporter`. The `TestReporter` can be used to publish additional data about the
current test run. The data can be consumed via the `reportingEntryPublished()` method in
a `{TestExecutionListener}`, allowing it to be viewed in IDEs or included in reports.
current test run or attach files to it. The data can be consumed in a
`{TestExecutionListener}` via the `reportingEntryPublished()` or `fileEntryPublished()`
method, respectively. This allows them to be viewed in IDEs or included in reports.
+
In JUnit Jupiter you should use `TestReporter` where you used to print information to
`stdout` or `stderr` in JUnit 4. Using `@RunWith(JUnitPlatform.class)` will output all
Expand Down Expand Up @@ -2992,7 +2993,7 @@ Note that resources declared statically with `{ResourceLock}` annotation are com
resources added dynamically by `{ResourceLocksProvider}` implementations.

If the tests in the following example were run in parallel _without_ the use of
{ResourceLock}, they would be _flaky_. Sometimes they would pass, and at other times they
`{ResourceLock}`, they would be _flaky_. Sometimes they would pass, and at other times they
would fail due to the inherent race condition of writing and then reading the same JVM
System Property.

Expand Down Expand Up @@ -3029,6 +3030,28 @@ include::{testDir}/example/sharedresources/StaticSharedResourcesDemo.java[tags=u
include::{testDir}/example/sharedresources/DynamicSharedResourcesDemo.java[tags=user_guide]
----

Also, "static" shared resources can be declared for _direct_ child nodes via the `target`
attribute in the `{ResourceLock}` annotation, the attribute accepts a value from
the `{ResourceLockTarget}` enum.

Specifying `target = CHILDREN` in a class-level `{ResourceLock}` annotation
has the same semantics as adding an annotation with the same `value` and `mode`
to each test method and nested test class declared in this class.

This may improve parallelization when a test class declares a `READ` lock,
but only a few methods hold a `READ_WRITE` lock.

Tests in the following example would run in the `SAME_THREAD` if the `{ResourceLock}`
didn't have `target = CHILDREN`. This is because the test class declares a `READ`
shared resource, but one test method holds a `READ_WRITE` lock,
which would force the `SAME_THREAD` execution mode for all the test methods.

[source,java]
.Declaring shared resources for child nodes with `target` attribute
----
include::{testDir}/example/sharedresources/ChildrenSharedResourcesDemo.java[tags=user_guide]
----


[[writing-tests-built-in-extensions]]
=== Built-in Extensions
Expand Down
18 changes: 18 additions & 0 deletions documentation/src/test/java/example/TestReporterDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@

package example;

import static java.util.Collections.singletonList;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestReporter;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.api.parallel.Execution;
import org.junit.jupiter.api.parallel.ExecutionMode;

Expand All @@ -41,5 +46,18 @@ void reportMultipleKeyValuePairs(TestReporter testReporter) {
testReporter.publishEntry(values);
}

@Test
void reportFiles(TestReporter testReporter, @TempDir Path tempDir) throws Exception {

testReporter.publishFile("test1.txt", file -> Files.write(file, singletonList("Test 1")));

Path existingFile = Files.write(tempDir.resolve("test2.txt"), singletonList("Test 2"));
testReporter.publishFile(existingFile);

testReporter.publishFile("test3", dir -> {
Path nestedFile = Files.createDirectory(dir).resolve("nested.txt");
Files.write(nestedFile, singletonList("Nested content"));
});
}
}
// end::user_guide[]
Loading

0 comments on commit 9daa88a

Please sign in to comment.