英文:
JUnit5 multiple sources for different arguments (cartesian product)
问题
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvFileSource;
class CartesianProductTest {
@ParameterizedTest
@CsvFileSource(resources = { "values.csv" })
void testIt(int input, int expected) {
otherParams().forEach(otherParam -> {
assertEquals(expected, methodUnderTest(input, otherParam));
});
}
static Stream<Arguments> otherParams() {
return csvOtherParams().map(otherParam -> Arguments.of(otherParam));
}
@CsvFileSource(resources = { "otherparam.csv" })
static Stream<Integer> csvOtherParams() {/* get somehow from Annotation */}
}
Please note that the code snippet provided here is a translation of the code you provided, with the necessary parts for translations and explanations removed as per your request. If you have any further questions or need additional assistance, feel free to ask.
英文:
I am trying to write a test with JUnit 5 which should test multiple combinations of some parameters. Essentially I want to test some cartesian product of inputs from different sources. Consider the following test:
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
class CartesianProductTest {
@ParameterizedTest
@CsvFileSource(resources = { "values.csv" })
void testIt(int input, int expected, int otherParameter) {
assertEquals(expected, methodUnderTest(input, otherParameter));
}
}
The problem is now that I only have input
and expected
in the values.csv
and the otherParameter
should be tested for some fixed values that methodUnderTest()
always returns the expected value for all these values. Somehow I have to provide a cartesian product of all the values in my CSV and all the values otherParameter
can take. I looked at https://stackoverflow.com/a/57648088/7962200 but this needs to either hardcode all my test cases or read the CSV manually to provide a Stream of the values. I thought more of something like
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.CsvFileSource;
class CartesianProductTest {
@ParameterizedTest
@MethodSource
void testIt(int input, int expected, int otherParameter) {
assertEquals(expected, methodUnderTest(input, otherParameter));
}
static Stream<Arguments> testIt() {
return csvValues().flatMap(csv ->
otherParams().map(otherParam -> Arguments.of(csv, otherParam)));
}
@CsvFileSource(resources = { "values.csv" })
static Stream<Arguments> csvValues() {/* get somehow from Annotation */}
@CsvFileSource(resources = { "otherparam.csv" })
static Stream<Arguments> otherParams() {/* get somehow from Annotation */}
}
答案1
得分: 1
以下是翻译好的内容:
对于我的用例,我能够做类似这样的事情:
import com.google.common.collect.Lists;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class SampleTest {
@ParameterizedTest
@MethodSource
void testSomething(List<String> list) {
System.out.println(list);
// 做一些操作
// 断言一些内容
}
private static Stream<List<String>> testSomething() {
List<String> one = Arrays.asList("waz", "yaz", "zaz");
List<String> two = Arrays.asList("foo", "bar");
List<List<String>> product = Lists.cartesianProduct(one, two);
return product.stream();
}
}
你将需要将你的 .csv 文件读入一些 List
或类似的数据结构中。当然,从注解中获取 .csv 文件的名称可能是一个挑战;也许自定义注解可以帮助,但我没有深入研究过。
可能也值得关注的是:Introduce ArgumentsProvider that computes the cartesian product of collections of datapoints,这将引导你到 JUnit Pioneer。
<details>
<summary>英文:</summary>
For my use-case I was able to do something like this:
import com.google.common.collect.Lists;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class SampleTest {
@ParameterizedTest
@MethodSource
void testSomething(List<String> list) {
System.out.println(list);
// do something
// assert something
}
private static Stream<List<String>> testSomething() {
List<String> one = Arrays.asList("waz", "yaz", "zaz");
List<String> two = Arrays.asList("foo", "bar");
List<List<String>> product = Lists.cartesianProduct(one, two);
return product.stream();
}
}
You would have to read your .csv into some `List` or something similar. Of course getting the name of the .csv from an annotation could be a challenge; maybe [Custom Annotation][1] could help, but I did not dig that far.
Possibly also worth looking at: [Introduce ArgumentsProvider that computes the cartesian product of collections of datapoints][2], which will lead you to [JUnit Pioneer][3].
[1]: https://www.baeldung.com/parameterized-tests-junit-5#8-custom-annotation
[2]: https://github.com/junit-team/junit5/issues/1427
[3]: https://github.com/junit-pioneer/junit-pioneer
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论