JUnit5多个参数的不同来源(笛卡尔积)

huangapple go评论76阅读模式
英文:

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 = { &quot;values.csv&quot; })
    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&lt;Arguments&gt; testIt() {
         return csvValues().flatMap(csv -&gt;
             otherParams().map(otherParam -&gt; Arguments.of(csv, otherParam)));
    }

    @CsvFileSource(resources = { &quot;values.csv&quot; })
    static Stream&lt;Arguments&gt; csvValues() {/* get somehow from Annotation */}
    @CsvFileSource(resources = { &quot;otherparam.csv&quot; })
    static Stream&lt;Arguments&gt; 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&lt;String&gt; list) {
            System.out.println(list);
            // do something
            // assert something
        }
    
        private static Stream&lt;List&lt;String&gt;&gt; testSomething() {
            List&lt;String&gt; one = Arrays.asList(&quot;waz&quot;, &quot;yaz&quot;, &quot;zaz&quot;);
            List&lt;String&gt; two = Arrays.asList(&quot;foo&quot;, &quot;bar&quot;);
            List&lt;List&lt;String&gt;&gt; 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>



huangapple
  • 本文由 发表于 2020年8月25日 19:35:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/63577965.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定