junit 使用数据提供器编写Java测试

vjhs03f7  于 2022-11-11  发布在  Java
关注(0)|答案(5)|浏览(130)

我目前正在做我的第一个Java项目,我想完全TDD它。我使用JUnit来编写测试。显然JUnit不支持数据提供者,这使得用20个不同版本的参数测试同一个方法相当烦人。支持数据提供者的最流行/标准的Java测试工具是什么?我遇到了TestNG,但是不知道这个有多受欢迎,或者它与其他选择相比如何。
如果有一种方法可以获得这种行为,那就是使用JUnit的一种好方法,那么这种方法也可能有效。

zour9fqk

zour9fqk1#

我在我们公司的同事用TestNG风格为JUnit编写了一个免费的DataProvider,您可以找到on github (https://github.com/TNG/junit-dataprovider)
我们在非常大的项目中使用它,它对我们来说工作得很好。它比JUnit的Parameterized有一些优势,因为它将减少单独类的开销,你也可以执行单个测试。
示例如下所示

@DataProvider
public static Object[][] provideStringAndExpectedLength() {
    return new Object[][] {
        { "Hello World", 11 },
        { "Foo", 3 }
    };
}

@Test
@UseDataProvider( "provideStringAndExpectedLength" )
public void testCalculateLength( String input, int expectedLength ) {
    assertThat( calculateLength( input ) ).isEqualTo( expectedLength );
}

**编辑:**从v1.7开始,它还支持其他提供数据的方式(字符串、列表),并且可以内联提供程序,因此不一定需要单独的方法。

在github的手册页上可以找到一个完整的工作示例。它还有一些其他的特性,比如收集实用类中的提供者,并从其他类中访问它们等等。手册页非常详细,我相信你会在那里找到任何问题的答案。

nmpmafwu

nmpmafwu2#

JUnit 4有参数化的测试,它和php数据提供者做同样的事情

@RunWith(Parameterized.class)
public class MyTest{ 
     @Parameters
    public static Collection<Object[]> data() {
           /*create and return a Collection
             of Objects arrays here. 
             Each element in each array is 
             a parameter to your constructor.
            */

    }

    private int a,b,c;

    public MyTest(int a, int b, int c) {
            this.a= a;
            this.b = b;
            this.c = c;
    }

    @Test
    public void test() {
          //do your test with a,b
    }

    @Test
    public void testC(){
        //you can have multiple tests 
        //which all will run

        //...test c
    }
}
bsxbgnwa

bsxbgnwa3#

根据您对灵活性和可读性的需求,您可以选择Parameterized- junit的内置选项,dkatzel对此进行了描述。其他选项是由外部库(如zohhak)提供的外部junit runner,它可以让您执行以下操作:

@TestWith({
        "clerk,      45'000 USD, GOLD",
        "supervisor, 60'000 GBP, PLATINUM"
    })
    public void canAcceptDebit(Employee employee, Money money, ClientType clientType) {
        assertTrue(   employee.canAcceptDebit(money, clientType)   );
    }

或者功能稍有不同的junitParams。只要选择最适合你的

qvtsj1bj

qvtsj1bj4#

您可以使用JUnit 5的ParameterizedTest。下面是https://www.petrikainulainen.net/programming/testing/junit-5-tutorial-writing-parameterized-tests/的一个示例:

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

@DisplayName("Should pass the method parameters provided by the sumProvider() method")
class MethodSourceExampleTest {

    @DisplayName("Should calculate the correct sum")
    @ParameterizedTest(name = "{index} => a={0}, b={1}, sum={2}")
    @MethodSource("sumProvider")
    void sum(int a, int b, int sum) {
        assertEquals(sum, a + b);
    }

    private static Stream<Arguments> sumProvider() {
        return Stream.of(
                Arguments.of(1, 1, 2),
                Arguments.of(2, 3, 5)
        );
    }
}

可以从注解、方法甚至CSV文件中加载测试参数。

g0czyy6m

g0czyy6m5#

这里有另一个选择。你不必使用谷歌Guava,这只是我的实现。
这里使用了与@dkatzel的答案相同的@Parameters,但是@Parameters注解针对特定的测试方法,而不是类接受参数,因此您可以挑选哪些方法使用这组参数。

import java.util.Collection;

import com.google.common.collect.ImmutableList;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JUnitParamsRunner.class)
public class FrobTester {
    @SuppressWarnings("unused")
    private Collection validfrobAndGorpValues() {
        return ImmutableList.of(
            new Object[] {"frob28953", 28953},
            new Object[] {"oldfrob-189-255", 1890255}
        );
    }

    @Test
    @Parameters(method = "validfrobAndGorpValues")
    public void whenGivenFrobString_thenGorpIsCorrect(
        String frobString,
        int expectedGorpValue
    ) {
        // Arrange
        Frob frob = new Frob(frobString);

        // Act
        var actualGorpValue = frob.getGorpValue();

        // Assert
        Assert.assertEquals(actualGorpValue, expectedGorpValue);
    }
}

相关问题