如何在Eclipse中运行通用的参数化JUnit测试? [英] How to run a generic parameterized JUnit test in Eclipse?

查看:156
本文介绍了如何在Eclipse中运行通用的参数化JUnit测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了避免大量冗余的测试类进行简单的集成测试,我想创建一个参数化的泛型测试类,如下例所示:

  @RunWith(Parameterized.class)
public class MovementTest< V extends Vehicle,T extends Track< V>> {

private final V testVehicle;

private final T testTrack;

public MovementTest(V vehicle,T track){
testVehicle = vehicle;
testTrack = track;
}

@Test
public void testMovement(){
testVehicle.moveAlong(testTrack);
}

@Parameters
public static Iterable< Object []>提供测试样例(){
Object [] [] params = {
{new Car(),new Highway()},
{new Train(),new RailRoadTrack()}
};
return Arrays.asList(params);
}
}

public interface Vehicle {
abstract void moveAlong(Track t);
}

public interface Track< E extends Vehicle> {}

public class Train implements Vehicle {
@Override
public void moveAlong(Track t){}
}

public class RailRoadTrack实现轨道<列车> {}

public class Car implements Vehicle {
@Override
public void moveAlong(Track t){}
}

public class高速公路履带车> {}

不幸的是,这个测试类是不可运行的。有没有一个简洁的方法来实现相似的东西?

解决方案

#1



您可以使用 JUnit 参数化转轮。它的工作原理如下:

  @RunWith(Parameterized.class)
public class ParametrizedTest {

private final String text;
private final int number;

public ParametrizedTest(String text,int number){
this.text = text;
this.number = number;
}

@Test
public void shouldContainNumber(){
assertTrue(text.contains(String.valueOf(number)));
}

@ Parameterized.Parameters
public static Iterable< Object []> params(){
return Arrays.asList(
new Object [] [] {
{test string 1,1},
{test string 2,2 }
}
);
}
}

您可以阅读有关此解决方案的更多信息 here



#2(更好)



使用 JUnitParameters 链接),只需看一下:

  @RunWith(JUnitParamsRunner.class)
public class JUnitParamsTest {

@Test
@Parameters
public void shouldContainNumber(String text,int number){
assertTrue(text.contains(String.valueOf(number)));


public Object [] parametersForShouldContainNumber(){
return $(
$(test string 1,1),
$(测试字符串2,2)
);
}
}

请注意,提供参数的方法名称必须适合测试名称这个解决方案似乎更好,因为(不仅)你在执行后得到更好的测试名称:


[OK] JUnitParams。测试字符串1,1(shouldContainNumber)



[OK] JUnitParams。[1]测试字符串2,2(shouldContainNumber)


在项目网站上可以找到更好的列表:



  • 更明确 - 参数在测试方法参数中,而不是类字段

  • - 您不需要构造函数来设置参数

  • 您可以将参数与非参数化方法混合在一个类中

  • params可以被传递作为CSV字符串或参数提供程序类

  • 参数提供程序类可以提供尽可能多的参数提供方法,以便您可以对不同的案例进行分组

  • 您可以有一个提供参数的测试方法(不再需要外部类或静态)
  • 您可以在IDE中看到实际的参数值(在JUnit的参数中,它只是连续数量的参数)



To avoid alot of redundant test classes for simple integration testing, I'd like to create a parameterized generic test class like the following example:

@RunWith(Parameterized.class)
public class MovementTest<V extends Vehicle, T extends Track<V>> {

    private final V testVehicle;

    private final T testTrack;

    public MovementTest(V vehicle, T track){
        testVehicle = vehicle;
        testTrack = track;
    }

    @Test
    public void testMovement(){
        testVehicle.moveAlong(testTrack);
    }

    @Parameters
    public static Iterable<Object[]> provideTestExamples(){
        Object[][] params = {
            { new Car(), new Highway() },
            { new Train(), new RailRoadTrack() }
        };
        return Arrays.asList(params);
    }
}

public interface Vehicle {
    abstract void moveAlong(Track t);
}

public interface Track<E extends Vehicle> { }    

public class Train implements Vehicle {
    @Override
    public void moveAlong(Track t) {}
}

public class RailRoadTrack implements Track<Train> {}

public class Car implements Vehicle {
    @Override
    public void moveAlong(Track t) { }
}

public class Highway implements Track<Car> {}    

Unfortunately, this test class is not runnable. Is there a concise way to implement something alike?

解决方案

#1

You can use JUnit's Parametrized runner. It works as follows:

@RunWith(Parameterized.class)
public class ParametrizedTest {

    private final String text;
    private final int number;

    public ParametrizedTest(String text, int number) {
        this.text = text;
        this.number = number;
    }

    @Test
    public void shouldContainNumber() {
        assertTrue(text.contains(String.valueOf(number)));
    }

    @Parameterized.Parameters
    public static Iterable<Object[]> params() {
        return Arrays.asList(
                new Object[][]{
                        {"test string 1", 1},
                        {"test string 2", 2}
                }
        );
    }
}

You can read more about this solution here

#2 (better)

There's also better way (I think so) using JUnitParameters (link), just take a look:

@RunWith(JUnitParamsRunner.class)
public class JUnitParamsTest{

    @Test
    @Parameters
    public void shouldContainNumber(String text, int number) {
        assertTrue(text.contains(String.valueOf(number)));
    }

    public Object[] parametersForShouldContainNumber() {
        return $(
                $("test string 1", 1),
                $("test string 2", 2)
        );
    }
}

Note that name of method which supplies parameters has to fit test name. This solution seems better because (not only) you get better tests names after execution:

[OK] JUnitParams.[0] test string 1, 1 (shouldContainNumber)

[OK] JUnitParams.[1] test string 2, 2 (shouldContainNumber)

More comprehensive list of why it's better can be found at project site:

  • more explicit - params are in test method params, not class fields
  • less code - you don't need a constructor to set up parameters
  • you can mix parametrised with non-parametrised methods in one class
  • params can be passed as a CSV string or from a parameters provider class
  • parameters provider class can have as many parameters providing methods as you want, so that you can group different cases
  • you can have a test method that provides parameters (no external classes or statics anymore)
  • you can see actual parameter values in your IDE (in JUnit's Parametrised it's only consecutive numbers of parameters)

这篇关于如何在Eclipse中运行通用的参数化JUnit测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆