-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
ParameterizedTest.java
326 lines (310 loc) · 13.4 KB
/
ParameterizedTest.java
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
315
316
317
318
319
320
321
322
323
324
325
326
/*
* Copyright 2015-2024 the original author or authors.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v2.0 which
* accompanies this distribution and is available at
*
* https://www.eclipse.org/legal/epl-v20.html
*/
package org.junit.jupiter.params;
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
import static org.apiguardian.api.API.Status.STABLE;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apiguardian.api.API;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.provider.ArgumentsSource;
/**
* {@code @ParameterizedTest} is used to signal that the annotated method is a
* <em>parameterized test</em> method.
*
* <p>Such methods must not be {@code private} or {@code static}.
*
* <h2>Arguments Providers and Sources</h2>
*
* <p>{@code @ParameterizedTest} methods must specify at least one
* {@link org.junit.jupiter.params.provider.ArgumentsProvider ArgumentsProvider}
* via {@link org.junit.jupiter.params.provider.ArgumentsSource @ArgumentsSource}
* or a corresponding composed annotation (e.g., {@code @ValueSource},
* {@code @CsvSource}, etc.). The provider is responsible for providing a
* {@link java.util.stream.Stream Stream} of
* {@link org.junit.jupiter.params.provider.Arguments Arguments} that will be
* used to invoke the parameterized test method.
*
* <h2>Formal Parameter List</h2>
*
* <p>A {@code @ParameterizedTest} method may declare additional parameters at
* the end of the method's parameter list to be resolved by other
* {@link org.junit.jupiter.api.extension.ParameterResolver ParameterResolvers}
* (e.g., {@code TestInfo}, {@code TestReporter}, etc). Specifically, a
* parameterized test method must declare formal parameters according to the
* following rules.
*
* <ol>
* <li>Zero or more <em>indexed arguments</em> must be declared first.</li>
* <li>Zero or more <em>aggregators</em> must be declared next.</li>
* <li>Zero or more arguments supplied by other {@code ParameterResolver}
* implementations must be declared last.</li>
* </ol>
*
* <p>In this context, an <em>indexed argument</em> is an argument for a given
* index in the {@code Arguments} provided by an {@code ArgumentsProvider} that
* is passed as an argument to the parameterized method at the same index in the
* method's formal parameter list. An <em>aggregator</em> is any parameter of type
* {@link org.junit.jupiter.params.aggregator.ArgumentsAccessor ArgumentsAccessor}
* or any parameter annotated with
* {@link org.junit.jupiter.params.aggregator.AggregateWith @AggregateWith}.
*
* <h2>Argument Conversion</h2>
*
* <p>Method parameters may be annotated with
* {@link org.junit.jupiter.params.converter.ConvertWith @ConvertWith}
* or a corresponding composed annotation to specify an <em>explicit</em>
* {@link org.junit.jupiter.params.converter.ArgumentConverter ArgumentConverter}.
* Otherwise, JUnit Jupiter will attempt to perform an <em>implicit</em>
* conversion to the target type automatically (see the User Guide for further
* details).
*
* <h2>Composed Annotations</h2>
*
* <p>{@code @ParameterizedTest} may also be used as a meta-annotation in order
* to create a custom <em>composed annotation</em> that inherits the semantics
* of {@code @ParameterizedTest}.
*
* <h2>Inheritance</h2>
*
* <p>{@code @ParameterizedTest} methods are inherited from superclasses as long
* as they are not <em>overridden</em> according to the visibility rules of the
* Java language. Similarly, {@code @ParameterizedTest} methods declared as
* <em>interface default methods</em> are inherited as long as they are not
* overridden.
*
* <h2>Test Execution Order</h2>
*
* <p>By default, test methods will be ordered using an algorithm that is
* deterministic but intentionally nonobvious. This ensures that subsequent runs
* of a test suite execute test methods in the same order, thereby allowing for
* repeatable builds. In this context, a <em>test method</em> is any instance
* method that is directly annotated or meta-annotated with {@code @Test},
* {@code @RepeatedTest}, {@code @ParameterizedTest}, {@code @TestFactory}, or
* {@code @TestTemplate}.
*
* <p>Although true <em>unit tests</em> typically should not rely on the order
* in which they are executed, there are times when it is necessary to enforce
* a specific test method execution order — for example, when writing
* <em>integration tests</em> or <em>functional tests</em> where the sequence of
* the tests is important, especially in conjunction with
* {@link org.junit.jupiter.api.TestInstance @TestInstance(Lifecycle.PER_CLASS)}.
*
* <p>To control the order in which test methods are executed, annotate your
* test class or test interface with
* {@link org.junit.jupiter.api.TestMethodOrder @TestMethodOrder} and specify
* the desired {@link org.junit.jupiter.api.MethodOrderer MethodOrderer}
* implementation.
*
* @since 5.0
* @see org.junit.jupiter.params.provider.Arguments
* @see org.junit.jupiter.params.provider.ArgumentsProvider
* @see org.junit.jupiter.params.provider.ArgumentsSource
* @see org.junit.jupiter.params.provider.CsvFileSource
* @see org.junit.jupiter.params.provider.CsvSource
* @see org.junit.jupiter.params.provider.EnumSource
* @see org.junit.jupiter.params.provider.MethodSource
* @see org.junit.jupiter.params.provider.ValueSource
* @see org.junit.jupiter.params.aggregator.ArgumentsAccessor
* @see org.junit.jupiter.params.aggregator.AggregateWith
* @see org.junit.jupiter.params.converter.ArgumentConverter
* @see org.junit.jupiter.params.converter.ConvertWith
*/
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@API(status = STABLE, since = "5.7")
@TestTemplate
@ExtendWith(ParameterizedTestExtension.class)
@SuppressWarnings("exports")
public @interface ParameterizedTest {
/**
* Placeholder for the {@linkplain org.junit.jupiter.api.TestInfo#getDisplayName
* display name} of a {@code @ParameterizedTest} method: <code>{displayName}</code>
*
* @since 5.3
* @see #name
*/
String DISPLAY_NAME_PLACEHOLDER = "{displayName}";
/**
* Placeholder for the current invocation index of a {@code @ParameterizedTest}
* method (1-based): <code>{index}</code>
*
* @since 5.3
* @see #name
* @see #DEFAULT_DISPLAY_NAME
*/
String INDEX_PLACEHOLDER = "{index}";
/**
* Placeholder for the complete, comma-separated arguments list of the
* current invocation of a {@code @ParameterizedTest} method:
* <code>{arguments}</code>
*
* @since 5.3
* @see #name
*/
String ARGUMENTS_PLACEHOLDER = "{arguments}";
/**
* Placeholder for the complete, comma-separated named arguments list
* of the current invocation of a {@code @ParameterizedTest} method:
* <code>{argumentsWithNames}</code>
*
* <p>Argument names will be retrieved via the {@link java.lang.reflect.Parameter#getName()}
* API if the byte code contains parameter names — for example, if
* the code was compiled with the {@code -parameters} command line argument
* for {@code javac}.
*
* @since 5.6
* @see #name
* @see #ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER
*/
String ARGUMENTS_WITH_NAMES_PLACEHOLDER = "{argumentsWithNames}";
/**
* Placeholder for the name of the argument set for the current invocation
* of a {@code @ParameterizedTest} method: <code>{argumentSetName}</code>.
*
* <p>This placeholder can be used when the current set of arguments was created via
* {@link org.junit.jupiter.params.provider.Arguments#argumentSet(String, Object...)
* argumentSet()}.
*
* @since 5.11
* @see #name
* @see #ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER
* @see org.junit.jupiter.params.provider.Arguments#argumentSet(String, Object...)
*/
@API(status = EXPERIMENTAL, since = "5.11")
String ARGUMENT_SET_NAME_PLACEHOLDER = "{argumentSetName}";
/**
* Placeholder for either {@link #ARGUMENT_SET_NAME_PLACEHOLDER} or
* {@link #ARGUMENTS_WITH_NAMES_PLACEHOLDER}, depending on whether the
* current set of arguments was created via
* {@link org.junit.jupiter.params.provider.Arguments#argumentSet(String, Object...)
* argumentSet()}: <code>{argumentSetNameOrArgumentsWithNames}</code>.
*
* @since 5.11
* @see #name
* @see #ARGUMENT_SET_NAME_PLACEHOLDER
* @see #ARGUMENTS_WITH_NAMES_PLACEHOLDER
* @see #DEFAULT_DISPLAY_NAME
* @see org.junit.jupiter.params.provider.Arguments#argumentSet(String, Object...)
*/
@API(status = EXPERIMENTAL, since = "5.11")
String ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER = "{argumentSetNameOrArgumentsWithNames}";
/**
* Default display name pattern for the current invocation of a
* {@code @ParameterizedTest} method: {@value}
*
* <p>Note that the default pattern does <em>not</em> include the
* {@linkplain #DISPLAY_NAME_PLACEHOLDER display name} of the
* {@code @ParameterizedTest} method.
*
* @since 5.3
* @see #name
* @see #DISPLAY_NAME_PLACEHOLDER
* @see #INDEX_PLACEHOLDER
* @see #ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER
*/
String DEFAULT_DISPLAY_NAME = "[" + INDEX_PLACEHOLDER + "] "
+ ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER;
/**
* The display name to be used for individual invocations of the
* parameterized test; never blank or consisting solely of whitespace.
*
* <p>Defaults to <code>{@value ParameterizedTestExtension#DEFAULT_DISPLAY_NAME}</code>.
*
* <p>If the default display name flag
* (<code>{@value ParameterizedTestExtension#DEFAULT_DISPLAY_NAME}</code>)
* is not overridden, JUnit will:
* <ul>
* <li>Look up the {@value ParameterizedTestExtension#DISPLAY_NAME_PATTERN_KEY}
* <em>configuration parameter</em> and use it if available. The configuration
* parameter can be supplied via the {@code Launcher} API, build tools (e.g.,
* Gradle and Maven), a JVM system property, or the JUnit Platform configuration
* file (i.e., a file named {@code junit-platform.properties} in the root of
* the class path). Consult the User Guide for further information.</li>
* <li>Otherwise, <code>{@value #DEFAULT_DISPLAY_NAME}</code> will be used.</li>
* </ul>
*
* <h4>Supported placeholders</h4>
* <ul>
* <li><code>{@value #DISPLAY_NAME_PLACEHOLDER}</code></li>
* <li><code>{@value #INDEX_PLACEHOLDER}</code></li>
* <li><code>{@value #ARGUMENT_SET_NAME_PLACEHOLDER}</code></li>
* <li><code>{@value #ARGUMENTS_PLACEHOLDER}</code></li>
* <li><code>{@value #ARGUMENTS_WITH_NAMES_PLACEHOLDER}</code></li>
* <li><code>{@value #ARGUMENT_SET_NAME_OR_ARGUMENTS_WITH_NAMES_PLACEHOLDER}</code></li>
* <li><code>"{0}"</code>, <code>"{1}"</code>, etc.: an individual argument (0-based)</li>
* </ul>
*
* <p>For the latter, you may use {@link java.text.MessageFormat} patterns
* to customize formatting (for example, {@code {0,number,#.###}}). Please
* note that the original arguments are passed when formatting, regardless
* of any implicit or explicit argument conversions.
*
* <p>Note that
* <code>{@value ParameterizedTestExtension#DEFAULT_DISPLAY_NAME}</code> is
* a flag rather than a placeholder.
*
* @see java.text.MessageFormat
*/
String name() default ParameterizedTestExtension.DEFAULT_DISPLAY_NAME;
/**
* Configure whether all arguments of the parameterized test that implement {@link AutoCloseable}
* will be closed after {@link org.junit.jupiter.api.AfterEach @AfterEach} methods
* and {@link org.junit.jupiter.api.extension.AfterEachCallback AfterEachCallback}
* extensions have been called for the current parameterized test invocation.
*
* <p>Defaults to {@code true}.
*
* <p><strong>WARNING</strong>: if an argument that implements {@code AutoCloseable}
* is reused for multiple invocations of the same parameterized test method,
* you must set {@code autoCloseArguments} to {@code false} to ensure that
* the argument is not closed between invocations.
*
* @since 5.8
* @see java.lang.AutoCloseable
*/
@API(status = STABLE, since = "5.10")
boolean autoCloseArguments() default true;
/**
* Configure whether at least one set of arguments is required for this
* parameterized test.
*
* <p>Set this attribute to {@code false} if the absence of arguments is
* expected in some cases and should not cause a test failure.
*
* <p>Defaults to {@code true}.
*
* @since 5.12
*/
@API(status = EXPERIMENTAL, since = "5.12")
boolean requireArguments() default true;
/**
* Configure how the number of arguments provided by an {@link ArgumentsSource} are validated.
*
* <p>Defaults to {@link ArgumentCountValidationMode#DEFAULT}.
*
* <p>When an {@link ArgumentsSource} provides more arguments than declared by the test method,
* there might be a bug in the test method or the {@link ArgumentsSource}.
* By default, the additional arguments are ignored.
* {@code argumentCountValidation} allows you to control how additional arguments are handled.
* The default can be configured via the {@value ArgumentCountValidator#ARGUMENT_COUNT_VALIDATION_KEY}
* configuration parameter (see the User Guide for details on configuration parameters).
*
* @since 5.12
* @see ArgumentCountValidationMode
*/
@API(status = EXPERIMENTAL, since = "5.12")
ArgumentCountValidationMode argumentCountValidation() default ArgumentCountValidationMode.DEFAULT;
}