Skip to content

Commit 61344e5

Browse files
mpkorstanjerunningcode
authored andcommitted
Introduce junit-platform-suite-engine (junit-team#2416)
Implements a test engine that allows declarative execution of test suites using the `@Suite` annotation. Internally the Suite Engine uses the JUnit Platform Launcher. The engine works adding the test descriptors of the discovered engines and tests as children to its own test descriptor. ```java package org.junit.platform.suite; import org.junit.platform.suite.api.SelectPackages; @suite @SelectPackages("org.junit.suite.testcases") class SelectPackageSuite { } ``` Is equivalent to: ```java import org.junit.platform.engine.discovery.DiscoverySelectors; import org.junit.platform.launcher.Launcher; import org.junit.platform.launcher.LauncherDiscoveryRequest; import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder; import org.junit.platform.launcher.core.LauncherFactory; public class Main { public static void main(String[] args) { Launcher launcher = LauncherFactory.create(); LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request() .selectors(DiscoverySelectors.selectPackage("org.junit.suite.testcases")) .build(); launcher.execute(request); } } ``` Resolves junit-team#744.
1 parent 65008db commit 61344e5

File tree

92 files changed

+2794
-388
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+2794
-388
lines changed

build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ val platformProjects by extra(listOf(
4242
project(":junit-platform-launcher"),
4343
project(":junit-platform-reporting"),
4444
project(":junit-platform-runner"),
45+
project(":junit-platform-suite"),
4546
project(":junit-platform-suite-api"),
47+
project(":junit-platform-suite-commons"),
48+
project(":junit-platform-suite-engine"),
4649
project(":junit-platform-testkit")
4750
))
4851

@@ -76,6 +79,8 @@ val jacocoTestProjects = listOf(
7679
project(":junit-jupiter-migrationsupport"),
7780
project(":junit-jupiter-params"),
7881
project(":junit-platform-runner"),
82+
project(":junit-platform-suite-commons"),
83+
project(":junit-platform-suite-engine"),
7984
project(":junit-vintage-engine"),
8085
project(":platform-tests")
8186
)

documentation/documentation.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dependencies {
4141
testImplementation(project(":junit-jupiter-migrationsupport"))
4242
testImplementation(project(":junit-platform-console"))
4343
testImplementation(project(":junit-platform-runner"))
44+
testImplementation(project(":junit-platform-suite"))
4445
testImplementation(project(":junit-platform-testkit"))
4546
testImplementation("org.jetbrains.kotlin:kotlin-stdlib")
4647

documentation/src/docs/asciidoc/link-attributes.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ endif::[]
4343
:LegacyXmlReportGeneratingListener: {javadoc-root}/org.junit.platform.reporting/org/junit/platform/reporting/legacy/xml/LegacyXmlReportGeneratingListener.html[LegacyXmlReportGeneratingListener]
4444
// Platform Runner
4545
:JUnitPlatform-Runner: {javadoc-root}/org.junit.platform.runnner/org/junit/platform/runner/JUnitPlatform.html[JUnitPlatform]
46-
// Platform Suite API
46+
// Platform Suite
4747
:suite-api-package: {javadoc-root}/org.junit.platform.suite.api/org/junit/platform/suite/api/package-summary.html[org.junit.platform.suite.api]
48+
:junit-platform-suite-engine {javadoc-root}/org.junit.platform.suite.engine/org/junit/platform/suite/engine/package-summary.html[junit-platform-suite-engine]
4849
// Platform Test Kit
4950
:testkit-engine-package: {javadoc-root}/org.junit.platform.testkit/org/junit/platform/testkit/engine/package-summary.html[org.junit.platform.testkit.engine]
5051
:EngineExecutionResults: {javadoc-root}/org.junit.platform.testkit/org/junit/platform/testkit/engine/EngineExecutionResults.html[EngineExecutionResults]

documentation/src/docs/asciidoc/release-notes/release-notes-5.8.0-M1.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ on GitHub.
4545
`LauncherSession` in order to allow for executing global setup and teardown code exactly
4646
once via the new `LauncherSessionListener` interface that can be registered via Java’s
4747
`{ServiceLoader}` mechanism.
48-
48+
* New `junit-platform-suite-engine` to execute declarative test suites using the JUnit
49+
Platform Launcher.
50+
* Added additional selectors to the `junit-platform-suite-api`
4951

5052
[[release-notes-5.8.0-M1-junit-jupiter]]
5153
=== JUnit Jupiter

documentation/src/docs/asciidoc/user-guide/advanced-topics.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
include::launcher-api.adoc[]
55

6+
include::junit-platform-suite-engine.adoc[]
7+
68
include::testkit.adoc[]
79

810
////

documentation/src/docs/asciidoc/user-guide/appendix.adoc

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,17 @@ artifacts are deployed to Sonatype's {snapshot-repo}[snapshots repository] under
5050
`junit-platform-runner`::
5151
Runner for executing tests and test suites on the JUnit Platform in a JUnit 4
5252
environment. See <<running-tests-junit-platform-runner>> for details.
53+
`junit-platform-suite`::
54+
JUnit Platform Suite artifact that transitively pulls in dependencies on
55+
`junit-platform-suite-api`, `junit-platform-suite-engine` for simplified
56+
dependency management in build tools such as Gradle and Maven.
5357
`junit-platform-suite-api`::
5458
Annotations for configuring test suites on the JUnit Platform. Supported by the
55-
<<running-tests-junit-platform-runner,JUnitPlatform runner>> and possibly by
56-
third-party `TestEngine` implementations.
59+
<<junit-platform-suite-engine,JUnit Platform Suite Engine>> and
60+
<<running-tests-junit-platform-runner,JUnitPlatform runner>>.
61+
`junit-platform-suite-engine`::
62+
Engine to execute suites on the JUnit Platform. See
63+
<<junit-platform-suite-engine,JUnit Platform Suite Engine>> for details.
5764
`junit-platform-testkit`::
5865
Provides support for executing a test plan for a given `TestEngine` and then
5966
accessing the results via a fluent API to verify the expected results.
@@ -148,7 +155,10 @@ package org.junit.platform {
148155
[junit-platform-launcher] as launcher
149156
[junit-platform-reporting] as reporting
150157
[junit-platform-runner] as runner
158+
[junit-platform-suite] as suite
151159
[junit-platform-suite-api] as suite_api
160+
[junit-platform-suite-commons] as suite_commons
161+
[junit-platform-suite-engine] as suite_engine
152162
[junit-platform-testkit] as testkit
153163
}
154164
@@ -173,15 +183,15 @@ jupiter ..> jupiter_api
173183
jupiter ..> jupiter_params
174184
jupiter ..> jupiter_engine
175185
176-
jupiter_api ..> opentest4j
177-
jupiter_api ..> commons
186+
jupiter_api ....> opentest4j
187+
jupiter_api ...> commons
178188
179-
jupiter_engine ..> engine
189+
jupiter_engine ...> engine
180190
jupiter_engine ..> jupiter_api
181191
182192
jupiter_params ..> jupiter_api
183193
jupiter_migration_support ..> jupiter_api
184-
jupiter_migration_support ..> junit4
194+
jupiter_migration_support ...> junit4
185195
186196
console ..> launcher
187197
console ..> reporting
@@ -190,18 +200,25 @@ launcher ..> engine
190200
191201
jfr ..> launcher
192202
193-
engine ..> opentest4j
203+
engine ....> opentest4j
194204
engine ..> commons
195205
196206
reporting ..> launcher
197207
198-
runner ..> launcher
199-
runner ..> suite_api
200-
runner ..> junit4
208+
runner ..> suite_commons
209+
runner ...> junit4
201210
202-
testkit ..> opentest4j
211+
suite ..> suite_api
212+
suite ..> suite_engine
213+
214+
suite_engine ..> suite_commons
215+
216+
suite_commons ..> launcher
217+
suite_commons ..> suite_api
218+
219+
testkit ....> opentest4j
203220
testkit ..> launcher
204221
205-
vintage_engine ..> engine
222+
vintage_engine ...> engine
206223
vintage_engine ..> junit4
207224
----
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[[junit-platform-suite-engine]]
2+
=== JUnit Platform Suite Engine
3+
4+
The JUnit Platform supports declarative definition and execution of suites of tests from
5+
_any_ test engine using the Junit Platform.
6+
7+
==== Setup
8+
9+
In addition to _at least one_ other test engine, you need the following artifacts and
10+
their dependencies on the classpath. See <<dependency-metadata>> for details regarding
11+
group IDs, artifact IDs, and versions.
12+
13+
===== Explicit Dependencies
14+
15+
* `junit-platform-suite-api` in _test_ scope
16+
* `junit-platform-suite-engine` in _test runtime_ scope: implementation of the
17+
`TestEngine` API for the declarative Junit Platform
18+
Suites
19+
20+
NOTE: Both dependencies are aggregated in `junit-platform-suite` which can be used in
21+
_test_ scope.
22+
23+
===== Transitive Dependencies
24+
25+
* `junit-platform-suite-commons` in _test_ scope
26+
* `junit-platform-launcher` in _test_ scope
27+
* `junit-platform-engine` in _test_ scope
28+
* `junit-platform-commons` in _test_ scope
29+
* `opentest4j` in _test_ scope
30+
31+
==== Test Suite
32+
33+
By annotating a class with `@Suite` it is marked as a test suite on the JUnit Platform.
34+
As seen in the following example, selector and filter annotations can then be used to
35+
control the contents of the suite.
36+
37+
[source,java,indent=0]
38+
----
39+
include::{testDir}/example/SuiteDemo.java[tags=user_guide]
40+
----
41+
42+
.Additional Configuration Options
43+
NOTE: There are more configuration options for discovering and filtering tests than just
44+
`@SelectPackages`. Please consult the Javadoc of the `{suite-api-package}` package for
45+
further details.

documentation/src/docs/asciidoc/user-guide/launcher-api.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ JUnit currently provides two `{TestEngine}` implementations.
7777
* `{junit-jupiter-engine}`: The core of JUnit Jupiter.
7878
* `{junit-vintage-engine}`: A thin layer on top of JUnit 4 to allow running _vintage_
7979
tests with the launcher infrastructure.
80+
* `{junit-platform-suite-engine}`: To execute declarative suites of tests with the
81+
launcher infrastructure.
82+
8083

8184
Third parties may also contribute their own `TestEngine` by implementing the interfaces
8285
in the {junit-platform-engine} module and _registering_ their engine. By default, engine

documentation/src/docs/asciidoc/user-guide/running-tests.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ You need the following artifacts and their dependencies on the classpath. See
630630
===== Transitive Dependencies
631631

632632
* `junit-platform-suite-api` in _test_ scope
633+
* `junit-platform-suite-commons` in _test_ scope
633634
* `junit-platform-launcher` in _test_ scope
634635
* `junit-platform-engine` in _test_ scope
635636
* `junit-platform-commons` in _test_ scope
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2015-2021 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package example;
12+
13+
//tag::user_guide[]
14+
import org.junit.platform.suite.api.SelectPackages;
15+
import org.junit.platform.suite.api.Suite;
16+
import org.junit.platform.suite.api.SuiteDisplayName;
17+
18+
@Suite
19+
@SuiteDisplayName("JUnit Platform Suite Demo")
20+
@SelectPackages("example")
21+
//end::user_guide[]
22+
@org.junit.platform.suite.api.ExcludeTags("exclude")
23+
//tag::user_guide[]
24+
public class SuiteDemo {
25+
}
26+
//end::user_guide[]

junit-platform-commons/src/module/org.junit.platform.commons/module-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
org.junit.platform.reporting,
3333
org.junit.platform.runner,
3434
org.junit.platform.suite.api,
35+
org.junit.platform.suite.engine,
3536
org.junit.platform.testkit,
3637
org.junit.vintage.engine;
3738
exports org.junit.platform.commons.support;
@@ -46,6 +47,8 @@
4647
org.junit.platform.reporting,
4748
org.junit.platform.runner,
4849
org.junit.platform.suite.api,
50+
org.junit.platform.suite.commons,
51+
org.junit.platform.suite.engine,
4952
org.junit.platform.testkit,
5053
org.junit.vintage.engine;
5154
}

junit-platform-engine/src/main/java/org/junit/platform/engine/UniqueId.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import static java.util.Collections.singletonList;
1414
import static java.util.Collections.unmodifiableList;
15+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
1516
import static org.apiguardian.api.API.Status.STABLE;
1617

1718
import java.io.Serializable;
@@ -162,6 +163,24 @@ public final UniqueId append(Segment segment) {
162163
return new UniqueId(this.uniqueIdFormat, baseSegments);
163164
}
164165

166+
/**
167+
* Construct a new {@code UniqueId} by appending a new {@link Segment}, based
168+
* on the supplied {@code engineId}, to the end of this {@code UniqueId}.
169+
*
170+
* <p>This {@code UniqueId} will not be modified.
171+
*
172+
* <p>The engine ID will be stored in a {@link Segment} with
173+
* {@link Segment#getType type} {@value ENGINE_SEGMENT_TYPE}.
174+
*
175+
* @param engineId the engine ID; never {@code null} or blank
176+
*
177+
* @since 1.8
178+
*/
179+
@API(status = EXPERIMENTAL, since = "1.8")
180+
public UniqueId appendEngine(String engineId) {
181+
return append(new Segment(ENGINE_SEGMENT_TYPE, engineId));
182+
}
183+
165184
/**
166185
* Determine if the supplied {@code UniqueId} is a prefix for this
167186
* {@code UniqueId}.

junit-platform-engine/src/main/java/org/junit/platform/engine/discovery/DiscoverySelectors.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,8 @@ public static ModuleSelector selectModule(String moduleName) {
343343
*/
344344
@API(status = EXPERIMENTAL, since = "1.1")
345345
public static List<ModuleSelector> selectModules(Set<String> moduleNames) {
346-
Preconditions.notNull(moduleNames, "moduleNames must not be null");
347-
Preconditions.containsNoNullElements(moduleNames, "individual module name must not be null");
346+
Preconditions.notNull(moduleNames, "Module names must not be null");
347+
Preconditions.containsNoNullElements(moduleNames, "Individual module name must not be null");
348348

349349
// @formatter:off
350350
return moduleNames.stream()

junit-platform-launcher/src/main/java/org/junit/platform/launcher/core/DefaultLauncher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class DefaultLauncher implements InternalLauncher {
5858
Preconditions.notNull(postDiscoveryFilters, "PostDiscoveryFilter array must not be null");
5959
Preconditions.containsNoNullElements(postDiscoveryFilters,
6060
"PostDiscoveryFilter array must not contain null elements");
61-
this.discoveryOrchestrator = new EngineDiscoveryOrchestrator(EngineIdValidator.validate(testEngines),
61+
this.discoveryOrchestrator = new EngineDiscoveryOrchestrator(testEngines,
6262
unmodifiableCollection(postDiscoveryFilters), launcherDiscoveryListenerRegistry);
6363
}
6464

0 commit comments

Comments
 (0)