/
junit.apt.vm
314 lines (254 loc) · 11.2 KB
/
junit.apt.vm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
------
Using JUnit
------
Kristian Rosenvold <krosenvold@apache.org>
------
2010-10-10
------
~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements. See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership. The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied. See the License for the
~~ specific language governing permissions and limitations
~~ under the License.
~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html
Using JUnit
* Configuring JUnit
To get started with JUnit, you need to add the required version of JUnit to your project:
+---+
<dependencies>
[...]
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
+---+
This is the only step that is required to get started - you can now create tests in your test source directory
(e.g., <<<src/test/java>>>).
* Different Generations of JUnit support
Surefire supports three different generations of JUnit: JUnit 3.8.x, JUnit 4.x (serial provider) and JUnit 4.7 (junit-core provider
with parallel support). The provider is selected based on the JUnit version in your project and the configuration parameters (for parallel).
* Upgrade Check for JUnit 4.x
As of Surefire version 2.7, the algorithm for choosing which tests to run
has changed. From 2.7 and on, only valid JUnit tests are run for all versions of JUnit, where older versions
of the plugin would also run invalid tests that satisfied the naming convention.
When upgrading from a Surefire version prior to 2.7, the build can be run with
the flag <<<-Dsurefire.junit4.upgradecheck>>>. This will perform a check and notify you of any invalid tests that
will not be run with this version of Surefire (and the build fails). This is only meant to be used as a tool
when upgrading to check that all expected tests will be run. It is a transitional
feature that will be removed in a future version of surefire.
* Provider Selection
If nothing is configured, Surefire detects which JUnit version to use by the following algorithm:
+---+
if the JUnit 5 Platform Engine is present in the project
use junit-platform
if the JUnit version in the project >= 4.7 and the <<<parallel>>> configuration parameter has ANY value
use junit47 provider
if JUnit >= 4.0 is present
use junit4 provider
else
use junit3.8.1
+---+
Please note that the "else" part of this algorithm is also a FAQ response:
You depend on the appropriate version of JUnit being present in the project dependencies, or Surefire may choose the wrong
provider. If, for instance, one of your dependencies pulls in JUnit 3.8.1 you risk that surefire chooses the
3.8.1 provider, which will not support annotations or any of the 4.x features.
Use <<<mvn dependency:tree>>>, POM dependency ordering and/or exclusion of transitive dependencies to fix this problem.
** Manually Specifying a Provider
You can also manually force a specific provider by adding it as a dependency to ${thisPlugin} itself:
+---+
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</plugin>
[...]
</plugins>
+---+
When using this technique there is no check that the proper test-frameworks are present on your project's
classpath. Failing to add the proper test-frameworks will result in a build failure.
* Running Tests in Parallel
From JUnit 4.7 onwards you can run your tests in parallel. To do this, you must set the
<<<parallel>>> parameter, and may change the <<<threadCount>>> or <<<useUnlimitedThreads>>> attribute.
For example:
+---+
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
</configuration>
</plugin>
[...]
</plugins>
+---+
If your tests specify any value for the <<<parallel>>> attribute and your project uses JUnit 4.7+, your request will be routed to
the concurrent JUnit provider, which uses the JUnit JUnitCore test runner.
This is particularly useful for slow tests that can have high concurrency.
As of Surefire 2.7, no additional dependencies are needed to use the full set of options with parallel.
As of Surefire 2.16, new thread-count attributes are introduced, namely <<<threadCountSuites>>>, <<<threadCountClasses>>> and
<<<threadCountMethods>>>. Additionally, the new attributes <<<parallelTestsTimeoutInSeconds>>> and
<<<parallelTestsTimeoutForcedInSeconds>>> are used to shut down the parallel execution after an elapsed timeout, and
the attribute <<<parallel>>> specifies new values.
See also {{{./fork-options-and-parallel-execution.html}Fork Options and Parallel Test Execution}}.
* Using Custom Listeners and Reporters
The junit4 and junit47 providers provide support for attaching custom <<<RunListeners>>> to your tests.
You can configure multiple custom listeners like this:
+---+
<dependencies>
[...]
<dependency>
<groupId>your-junit-listener-artifact-groupid</groupId>
<artifactId>your-junit-listener-artifact-artifactid</artifactId>
<version>your-junit-listener-artifact-version</version>
<scope>test</scope>
</dependency>
[...]
</dependencies>
[...]
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<properties>
<property>
<name>listener</name>
<value>com.mycompany.MyResultListener,com.mycompany.MyResultListener2</value>
</property>
</properties>
</configuration>
</plugin>
[...]
</plugins>
+---+
For more information on JUnit, see the {{{http://www.junit.org}JUnit web site}}.
You can implement JUnit listener interface <<<org.junit.runner.notification.RunListener>>> in
a separate test artifact <<<your-junit-listener-artifact>>> with scope=test, or in project test source code
<<<src/test/java>>>. You can filter test artifacts by the parameter <<<dependenciesToScan>>> to load its classes
in current ClassLoader of surefire-junit* providers.
Since JUnit 4.12 thread safe listener class should be annotated by
<<<org.junit.runner.notification.RunListener.ThreadSafe>>> which avoids unnecessary locks in JUnit.
* Using a Security Manager (JUnit3 only)
As long as <<<forkCount>>> is not 0 and you use JUnit3, you can run your tests with a Java security manager enabled.
The class name of the security manager must be sent as a system property variable to the JUnit3 provider.
The JDK 17 deprecated the class <<<java.lang.SecurityManager>>> and the security manager is not fully supported
since JDK 18. The JUnit3 provider fails with enabled system property <<surefire.security.manager>>> in JDK 18+.
JUnit4 uses mechanisms internally that are not compatible with the tested
security managers and thus this means of configuring a security manager with JUnit4 is not supported
by Surefire.
+---+
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<systemPropertyVariables>
<surefire.security.manager>java.lang.SecurityManager</surefire.security.manager>
</systemPropertyVariables>
</configuration>
</plugin>
[...]
</plugins>
+---+
* Using a Security Manager (All providers)
Alternatively you can define a policy file that allows all providers to run with Surefire
and configure it using the <<<argLine>>> parameter and two system properties:
+---+
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<argLine>-Djava.security.manager -Djava.security.policy=${basedir}/src/test/resources/java.policy</argLine>
</configuration>
</plugin>
[...]
</plugins>
+---+
The disadvantage of this solution is that the policy changes will affect the tests too, which make the
security environment less realistic.
* Using JUnit Categories
JUnit 4.8 introduced the notion of Categories. You can use JUnit categories by using the <<<groups>>> parameter. As long as
the JUnit version in the project is 4.8 or higher, the presence of the "groups" parameter will automatically make Surefire select
the junit47 provider, which supports groups.
+---+
<plugins>
[...]
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<configuration>
<groups>com.mycompany.SlowTests</groups>
</configuration>
</plugin>
[...]
</plugins>
+---+
This will execute only those tests annotated with the <<<@Category(com.mycompany.SlowTests.class)>>> annotation and those tests
annotated with <<<@Category(com.mycompany.SlowerTests.class)>>> if class/interface <<<SlowerTests>>> is subclass of <<<SlowTests>>>:
+---+
public interface SlowTests{}
public interface SlowerTests extends SlowTests{}
+---+
+---+
public class AppTest {
@Test
@Category(com.mycompany.SlowTests.class)
public void testSlow() {
System.out.println("slow");
}
@Test
@Category(com.mycompany.SlowerTests.class)
public void testSlower() {
System.out.println("slower");
}
@Test
@Category(com.mycompany.FastTests.class)
public void testSlow() {
System.out.println("fast");
}
}
+---+
The <<<@Category>>> annotation can also be applied at class-level.
Multiple categories can be specified by comma-delimiting them in the <<<groups>>> parameter in which case tests annotated with
any of the categories will be executed.
For more information on JUnit, see the {{{http://www.junit.org}JUnit web site}}.
Since version 2.18.1 and JUnit 4.12, the <<<@Category>>> annotation type is automatically inherited from
superclasses, see <<<@java.lang.annotation.Inherited>>>. Make sure that test class inheritance still makes sense
together with <<<@Category>>> annotation of the JUnit 4.12 or higher appeared in superclass.