2016-02-29 107 views
1

,为了避免重复测试类进行简单的集成测试了很多,我想创建一个参数化通用测试类,如下面的例子:如何在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[]> 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> {}  

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

+0

任何堆栈跟踪,记录,不管?你有对象[] []参数,但正在创建新的对象[] – Gaskoin

+0

@Gaskoin修正它。另外,Eclipse不提供运行这个测试类的选项,所以没有堆栈跟踪。 –

+0

Eclipse JUnit runner将运行在类型擦除的字节码上,因此MovementTest具有泛型类型参数并不重要。你在使用相对较新版本的eclipse吗?项目路径中是JUnit 4吗?在eclipse Luna中,参数化测试 - 即使是泛型类型参数 - 我都没有问题。 –

回答

3

#1

您可以使用JUnitParametrized亚军。其工作原理如下:

@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(好)

还有更好的办法(我是这么认为的),使用JUnitParameterslink),只取一看:

@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) 
     ); 
    } 
} 

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

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

[OK] JUnitParams。[1]测试行2,2(shouldContainNumber)

更全面的为什么最好可以在项目网站上找到列表:

  • 更加明确 - 参数数量是在测试方法参数,可以不类字段
  • 更少的代码 - 你并不需要一个构造函数来设置参数
  • 你可以用非parametrised方法在一个类中拌匀parametrised
  • PARAMS可为CSV串或从参数提供一流的,只要你想
  • 参数提供商类可以有很多的参数提供方法通过,这样就可以组不同的情况
  • 你可以有一个测试方法,提供的参数(无外部类或静态了)
  • ,你可以看到你的IDE实际参数值(在JUnit的Parametrised这只是一个参数的连续数)
+0

是的,这是一个非常基本的参数化测试,我们正在使用它很多。但是,这并不能满足我对特定情况的需求。这里强调的是“通用”。 –

+0

@SME_Dev看看更新的答案 –

+0

明天我会去看图书馆。看起来很有前途。谢谢。 –

相关问题