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
Support JSON as source for parameterized tests arguments #101
Comments
Since this issue is more than a year old now, which of the suggested approaches would be preferred? |
i like the idea of a top level container, as it is quiet intuitive, and the testdata always belongs together. furthermore with the toplevel container in an array, we could also define a default object outside of the container, with default values. Sometimes you need all to have some data, and it needs to be the same. So we could utilize this, without duplicating data. just an idea. {
defaults: {
customer: {},
contracts: {}
}
data: [{
customer: {},
contracts: {}
}]
} But i think multiple files are impractical, as you do not see data belonging together, and you always should ensure that they do contain the same amount of datasets anyways. |
JSON-parsing should not be reimplemented for this issue, but also JUnit Pioneer doesn't want to take on additional run-time dependencies, which means this issue can not be resolved within this project. If a PR is offered for it, we will not merge it but instead take the new sources, documentation, etc. and spin it out into its own project. (That might of course take some time, so don't pick this up if you're looking for a quick win. 😉 ) |
I'd like to give this a go. What is my current thinking about this is the following. We would expect the json files to contain array of values or a single object: Array of values:
Single object:
Then using
Basically if you have one parameter we try to map into that object. If you have multiple parameters then it would be treated like you want to deconstruct that object. If you have multiple files then it would be treated as
I agree with @aepfli about this one. Trying to combine different files makes it more complex and I am not sure that it is worth it. Btw regarding JUnit Pioneer doesn't want to take on additional run-time dependencies. What about doing it with an optional dependency and having support for using different json parsing tools. Something similar to what JsonUnit does with its Converter. In any case, I would work in such a way that you can provide your implementation and have different ways of parsing the JSON. |
I like your approach, @filiphr. Having a single JS object per invocation makes more sense than what I proposed above. I also like deconstruction in Regarding @aepfli's proposal for default data, I think we should not implement that in the first try but that raises the question whether we already want to prepare for such a scenario by requiring the actual data on a top-level ParameterizedTest
@JsonSource(value = "customers.json", data = "the-customers")
void testCustomer(Customer customer) { /*...*/ } {
"the-customers": [
{ ... }
]
} It could default to a constant |
The thing with the dependencies is a bit more complicated. I'd need to look into your proposal at another time. But that wouldn't touch the code you write, so you can already go ahead with that. Let us know when you do. :) |
I like the
I went ahead and did PR #492. Documentation is missing, but I wanted to first get your feeling about the proposal before diving into docs. |
As I see it, we essentially offer three ways to provide JSON:
At the moment #492 splits this across two annotations and two provider classes, just like Jupiter does with the CSV source. I think there's a more uniform approach possible. First and foremost, I think there should only be one "core provider" that, given some JSON (node?) and other arguments (location?) turns JSON into Jupiter's As to annotations, I see three options:
Jupiter's machinery requires there to be one We usually try to stay close to Jupiter and one could argue that class path resources are also files and should thus be lumped into the same annotation, but I find that latter argument somewhat unconvincing. The former holds more water. Then again, if we think we can do better, we should try. |
One of Pioneer's cornerstones is not to add to user's dependency hell and so we don't want to require any run-time dependencies beyond JUnit (and its dependencies). There are features that we can't (reasonably) implement without additional dependencies, though: * integration with other frameworks (e.g. Playwright, see #426) * ease of use for complex functionality (e.g. JSON parsing, see #101) There are various options to take on such dependencies and different lenses through which to view them - for details see #502. In the end we decided to add optional dependencies to the main project because: * while the impact on user's dependency hell isn't zero, it should be reasonably close to that * it has the least complexity for us when it comes to setting up and maintaining different subprojects * the features are easy to discover by users Closes: #502 PR: #593
I thought that we were waiting for other people from the JUnit Pioneer team to respond to the last comment. I personally prefer to be as close as possible to JUnit Jupiter, since it reduces the complexity and it keeps it simple for the users to use the annotations. JUnit Jupiter currently has:
Therefore for the JSON support I think that we need to have the following:
Apart from the argument that this is similar to Jupiter, the
or even something like (if text blocks are not OK)
Sharing the common logic in an abstract "core provider" is completely fine and makes sense to me. |
I 100% agree with your Regarding two-vs-three annotations, I definitely like three annotations, i.e. one per use case, better. It seems cleaner and makes those easier to use as well (because they can rely on Then of course, there's the symmetry with JUnit Jupiter, which is definitely nice to have as it makes it easier for users to adopt these features. Weighing ease-of-learning (two annotations) against ease-of-use (three annotations), I lean towards the latter and would go with three annotations. Second question: What do you think? If both answers are on line with mine, you can just go ahead and refactor accordingly. Otherwise let's |
Implement an
ArgumentConverter
that parses JSON and anArgumentSource
that parses JSON files and passes them as arguments to a parameterized test.This is pretty straightforward for a single file and parameter:
It's a little unclear how to parse files for two parameters, though. There could be one file per parameter...
... but then customer/contract pairs would be far apart and hard to identify by looking at the files.
Alternatively, there could be a top-level container...
... and the parser takes them apart when resolving parameter:
The text was updated successfully, but these errors were encountered: