-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce support for parameterized containers (classes, records, etc) #878
Comments
I can imagine supporting something like @ArgumentSource(...)
class MyTest {
@ParameterizedTest
void feature1() { ... }
@ParameterizedTest
void feature2() { ... }
} Would that suit your needs? |
I think that is a good solution. |
For real-life examples, see GaugeTest and most of the other tests in its package. |
@ParameterizedTest
on class types for TCKs
@jkschneider Do you have time to work on a PR? |
If a parameter source annotation is placed on an individual method in a type that's been annotated like this would it make sense for the more specific annotation to take precedence? |
Yes as a matter of determinism? I think in practice, this would not be the way I'd recommend folks structure their test. |
Is this feature on the roadmap? I can't migrate to 5 without it. |
...unless someone knows of a workaround. |
@wrlyonsjr I flipped it around with Micrometer's TCK by defining an abstract class with my test methods, each of which takes an implementation of Then there is a corresponding test for each implementation of The approach has the disadvantage that you can't run the TCK abstract class from the IDE and execute the tests for all implementations, but this is the best I could do. |
It seems like my problem could be solved with TestTemplate et al. |
Moved to 5.1 backlog due to repeated requests for a feature like this at conferences, etc. |
Let me share my experience with parameterized tests in the new JUnit. Hope that helps to clarify the uses cases and requirements for Parameterized classes. I think that this feature will be universally useful, not for TCK only. I see its ultimate goal in bringing down the cost of defining multiple tests sharing the same parameters source. Currently, the following code is duplicated:
Having to repeat that code discourages the users to write short, focused tests. On top of that, if developers do have a luxury of copy-pasting that code, reviewers and maintainers have to read all of it. As an alternative, I've tried a dynamic test for a simple use case (little setup code, no teardown), but got both a personal impression and some reviews from colleagues that it's "overcomplicated". Uses casesA perfect use case for this feature, in my opinion, is the following:
|
I think supporting something like I'm out of ideas where you'd put formatting strings for parameters that are shared for all parameterized tests, though. |
@marcphilipp , I can think of a class-level annotation with If no one on the core team is planning to work on this issue soon, I may try to implement an MVP. I am new to the code base, and have a couple of questions about the requirements:
@CsvSource(/* primary parameters, injected into constructor/BeforeEach/fields */)
class FooTest {
/** Invoked for each parameter in the source specified at the class level */
@ParameterizedTest
void foo() { }
/**
* Invoked for the cartesian product of parameters from
* the source specified at the class level
* and parameters from the source at the method level.
*/
@ParameterizedTest
@ValueSource(/* secondary parameters for #bar only */)
void bar(int secondaryParameter) { }
} ? |
Team Decision: during the face-to-face meeting this past week, we came up with the following use cases that we would ideally like to support. @ParameterizedContainer
@CsvSource(textBlock = """
apple, 1
banana, 2
""")
class ConstructorInjectionTestCase {
private final String fruit;
private final int score;
ConstructorInjectionTestCase(String fruit, int score) {
this.fruit = fruit;
this.score = score;
}
@Test
void test() {
// Assert something based on fruit and score
}
} @ParameterizedContainer
@CsvSource(textBlock = """
apple, 1
banana, 2
""")
class FieldInjectionTestCase {
@Parameter(0)
private String fruit;
@Parameter(1)
private int score;
@Test
void test() {
// Assert something based on fruit and score
}
} @ParameterizedContainer
@CsvSource(textBlock = """
apple, 1
banana, 2
""")
record CsvSourceRecordTestCase(String fruit, int score) {
@Test
void test() {
// Assert something based on fruit and score
}
} @ParameterizedContainer
@MethodSource("fruitScores")
record MethodSourceRecordTestCase(String fruit, int score) {
static Stream<Arguments> fruitScores() {
return Stream.of(
arguments("apple", 1),
arguments("banana", 2));
}
@Test
void test() {
// Assert something based on fruit and score
}
} It turns out that Java records and Kotlin data classes would make a nice fit for parameterized containers. 😄 We are not yet making any promises about the final API, but the above is currently our goal. |
Looks great! 👍🏾 And the synergy with records is just so good! 😃 Would |
For the @ParameterizedContainer
@InstanceSource("instances")
record FruitScoreTests(String fruit, int score) {
static Stream<FruitScoreTests> instances() {
return Stream.of(
new FruitScoreTests("apple", 1),
new FruitScoreTests("banana", 2));
}
@Test
void test() {
// Assert something based on fruit and score
}
} |
Yeah, the entire JUnit team is looking forward to being able to use parameterized records in real life. The moment I typed up that example during our brainstorming, we were all collectively like "Oooooh, I want that!". 😉
Yes, #871 is actually a prerequisite for
|
Blocked until #871 is completed. See #878 (comment) for details. |
Hey, wait a minute! How did you copy that from my computer? 😛 Disclaimer: For the And also "for the Speaking of which, @sormuras, feel free to create a separate issue to officially propose and track that. |
Making the test class a record is a neat trick. But this is presumably incompatible with having other fields in the class which are initialised in their declaration or an |
Thanks Tom for |
### What changes were proposed in this pull request? add mysql 5.7 to integerate IT ### Why are the changes needed? junit5 doesn't support class level ParameterizedTest, junit-team/junit5#878 . so use a separate class. Fix: #1367 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? integrate test
Overview
Currently, the target of
@ParameterizedTest
is constrained to methods. When creating technology compatibility kits, it would be awesome to be able to apply this (or a similar annotation) to the test class so that all tests in that class are parameterized the same way.Proposal
Rather than:
Something like:
Related Issues
The text was updated successfully, but these errors were encountered: