Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何参数化junit测试套件_Java_Junit4_Junit Runner - Fatal编程技术网

Java 如何参数化junit测试套件

Java 如何参数化junit测试套件,java,junit4,junit-runner,Java,Junit4,Junit Runner,可以在JUnit4中参数化TestSuite吗 为了将一个类声明为测试套件,我需要注释@RunWith(suite.class),但是同样的注释也需要将测试声明为参数化:@RunWith(parameterized.class),因此我不能将两者都添加到同一个类中 我在这个网站上发现了一个类似的例子,但没有多大帮助。到目前为止,我找到的所有示例都解释了如何参数化简单的单元测试,而不是完整的测试。我相信基本答案是否定的,因为正如您所说,@RunsWith只接受一个参数。我在如何处理这种情况上找到了

可以在JUnit4中参数化TestSuite吗

为了将一个类声明为测试套件,我需要注释
@RunWith(suite.class)
,但是同样的注释也需要将测试声明为参数化:
@RunWith(parameterized.class)
,因此我不能将两者都添加到同一个类中


我在这个网站上发现了一个类似的例子,但没有多大帮助。到目前为止,我找到的所有示例都解释了如何参数化简单的单元测试,而不是完整的测试。我相信基本答案是否定的,因为正如您所说,@RunsWith只接受一个参数。我在如何处理这种情况上找到了一个解决办法

我们不使用参数化测试,但是您可以像我们一样创建一个单独的套件,只列出测试类,参数化测试可以是其中的一部分。我修改了我们的测试套件,将一个参数化的测试类包含在套件中,它运行良好。我们创建了我们的套件,如下图所示,PrimeNumberCheckTest是我从web上获取的一个简单的工具

package com.jda.portfolio.api.rest.server;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({  com.mycompany.api.rest.server.resource.TestCartResourceJava.class, 
                 com.mycompany.api.rest.server.resource.TestCustomerResource.class,
                 com.mycompany.api.rest.server.resource.TestWizardProfileResource.class,
                 com.mycompany.api.rest.server.interceptor.TestBaseSearchInterceptor.class, 
                 com.mycompany.api.rest.server.resource.TestQueryParameters.class, 
                 com.mycompany.api.rest.server.expression.TestCartExpressionGenerator.class, 
                 com.mycompany.api.rest.server.expression.TestPreferenceExpressionGenerator.class, 
                 com.mycompany.api.rest.server.PrimeNumberCheckerTest.class, 
                 })
public class AllTests {}
这里是参数化测试用例的源代码

package com.jda.portfolio.api.rest.server:

import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Parameterized.class)
@SuiteClasses({PrimeNumberCheckerTest.class})
public class PrimeNumberCheckerTest {
  private Integer inputNumber;
  private Boolean expectedResult;
  private PrimeNumberChecker primeNumberChecker;

  @Before
  public void initialize() {
     primeNumberChecker = new PrimeNumberChecker();
  }

  // Each parameter should be placed as an argument here
  // Every time runner triggers, it will pass the arguments
  // from parameters we defined in primeNumbers() method
  public PrimeNumberCheckerTest(Integer inputNumber, 
     Boolean expectedResult) {
     this.inputNumber = inputNumber;
     this.expectedResult = expectedResult;
  }

  @Parameterized.Parameters
  public static Collection primeNumbers() {
     return Arrays.asList(new Object[][] {
        { 2, true },
        { 6, false },
        { 19, true },
        { 22, false },
        { 23, true }
     });
  }

  // This test will run five times since we have as many parameters defined
  @Test
  public void testPrimeNumberChecker() {
     System.out.println("Parameterized Number is : " + inputNumber);
     assertEquals(expectedResult, 
     primeNumberChecker.validate(inputNumber));
  }

我同意,使用提供的类是不可能的,但是有一些变通方法可以让您在大部分时间内达到目的,比如@mikemil's

我花了一些时间扩展套件,并将其委托给参数化,取得了部分成功;可以构建运行程序来完成您想要的任务,并且代码或多或少是在这两个类中为您编写的。这些类的交互方式(特别是
参数化的#getChildren()
的定义)使得很难扩展或委托这些类来完成您需要的任务,但是创建一个比extends
ParentRunner
更全新的类并从其他两个类中提取代码将相当容易


我会争取更多的时间稍后再来讨论这个问题。如果您在我开始之前构建了一个新的runner,请将其作为答案发布,我很乐意自己使用。

我能够参数化测试套件,并在套件的测试类成员中使用其数据,如下所示:

在JUTsuite:

@RunWith(Suite.class)
@Suite.SuiteClasses({ 
    JUT_test1.class,
})

public class JUTSuite{  
    // Declare all variables/objects you want to share with the test classes, e.g.
    protected static List<Fx> globalFxs;
    // This is the data list we'll use as parameters
    protected static List<Dx> globalDxs;

    @Parameters
    public static Collection<Object[]> data(){
        // Instantiate object list for parameters.  
        // Note: you must do it here and not in, say, @BeforeClass setup()
        // e.g.
        globalDxs=new ArrayList<Dx>(serverObj.values());

        Collection<Object[]> rows=new ArrayList<Object[]>();
        for(Dx d:globalDxs) {
            rows.add(new Object[]{d});
        }
        return rows;
    }

    @BeforeClass
    public static void setUp() throws Exception {
        // Instantiate/initialize all suite variables/objects to be shares with test classes
        // e.g. globalFxs=new ArrayList<Fx>();
    }

    @AfterClass
    public static void tearDown() throws Exception {
        // Clean up....
    }
}
@RunWith(Suite.class)
@Suite.SuiteClasses({
JUT_test1.class,
})
公营学校{
//声明要与测试类共享的所有变量/对象,例如。
受保护的静态列表globalFxs;
//这是我们将用作参数的数据列表
受保护的静态列表globalDxs;
@参数
公共静态收集数据(){
//实例化参数的对象列表。
//注意:您必须在此处执行此操作,而不是在@BeforeClass setup()中执行此操作
//例如。
globalDxs=newarraylist(serverObj.values());
集合行=新的ArrayList();
用于(Dx d:globalDxs){
添加(新对象[]{d});
}
返回行;
}
@课前
public static void setUp()引发异常{
//实例化/初始化要与测试类共享的所有套件变量/对象
//例如,globalFxs=newarraylist();
}
@下课
public static void tearDown()引发异常{
//清理。。。。
}
}
接下来,在测试类中:

@RunWith(Parameterized.class)
public class JUT_test1 {
    // declare local names (if desired) for suite-wide variable/objects 
    // e.g. 
    private static List<Fx> globalFxs;

    // This is the test parameter:      
    private Dx d;

    public JUT_test1(Dx d){
        this.d=d;
    }

    @Parameters
    public static Collection<Object[]> data(){
    // Note: we're calling the suite's data() method which has already executed.
        return JUTSuite.data();
    }

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    // (If desired)initialize local variables by referencing suite variables.
    // e.g.globalFxs=JUTSuite.globalFxs;
    }
}
@RunWith(参数化的.class)
公共类JUT_test1{
//为套件范围的变量/对象声明本地名称(如果需要)
//例如。
私有静态列表globalFxs;
//这是测试参数:
私人Dx-d;
公共JUT_测试1(Dx d){
这个。d=d;
}
@参数
公共静态收集数据(){
//注意:我们正在调用已经执行的套件的data()方法。
返回JUTSuite.data();
}
@课前
public static void setUpBeforeClass()引发异常{
//(如果需要)通过引用套件变量初始化局部变量。
//例如,globalFxs=JUTSuite.globalFxs;
}
}

你说得对:
套件
参数化
都是运行程序,一次只能使用一个
运行程序
。标准JUnit4不提供组合式转轮

您可以实现自己的Runner,也可以查看这个现成的库,它提供了一个
ParameterizedSuite
Runner:

参数化测试套件如下所示:

@RunWith(ParameterizedSuite.class)
@SuiteClasses({OneTest.class, TwoTest.class})
public class MyParameterizedTestSuite {
    @Parameters(name = "Parameters are {0} and {1}")
    public static Object[] params() {
        return new Object[][] {{'A',1}, {'B',2}, {'C',3}};
    }

最好的解决方案是,将西服类单独放在空白类中。 例如,我将登录测试作为参数化测试,并穿上套装(用于导航性能测量)

LoginPageTest实际上是参数化测试

@RunWith(Parameterized.class)
public class LoginPageTest
{...}

正如已经多次指出的,不可能用JUnit4提供的运行程序参数化测试套件

无论如何,我不建议让您的TestClass依赖于某些外部提供的状态。如果您想运行一个testclass呢

我建议将单独的测试类@参数化,并使用实用程序类提供参数:

@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class TestSuite {
    // suite
}

@RunWith(Parameterized.class}
public class Test1 {
    public Test1(Object param1) { /* ... */ }

    @Parameters
    public static Collection<Object[]> data() {
        return TestParameters.provideTestData()
    }

    @Test
    public void someTest() { /* ... */ }
}

@RunWith(Parameterized.class}
public class Test2 {
    public Test2(Object param1) { /* ... */ }

    @Parameters
    public static Collection<Object[]> data() {
        return TestParameters.provideTestData()
    }

    @Test
    public void someOtherTest() { /* ... */ }
}

class TestParameters {
    public static Collection<Object[]> provideTestData() {
        Collection<Object[]> data = new ...;
        // build testdata
    return data;
}
@RunWith(Suite.class)
@SuiteClass({Test1.class,Test2.class})
公共类测试套件{
//套房
}
@RunWith(参数化的.class}
公共类Test1{
公共测试1(对象参数1){/*…*/}
@参数
公共静态收集数据(){
返回TestParameters.provideTestData()
}
@试验
public void someTest(){/*…*/}
}
@RunWith(参数化的.class}
公共类Test2{
公共测试2(对象参数1){/*…*/}
@参数
公共静态收集数据(){
返回TestParameters.provideTestData()
}
@试验
public void someOtherTest(){/*…*/}
}
类测试参数{
公共静态集合提供测试数据(){
收集数据=新。。。;
//构建测试数据
返回数据;
}
也许这个答案有帮助:


它使用了
@RunWith(included.class)
,似乎解决了问题。

-1因为我认为您没有抓住要点。Sergio想对套件本身进行参数化,而不仅仅是执行一个参数化的测试。您发现了吗
@RunWith(Suite.class)
@SuiteClasses({ Test1.class, Test2.class })
public class TestSuite {
    // suite
}

@RunWith(Parameterized.class}
public class Test1 {
    public Test1(Object param1) { /* ... */ }

    @Parameters
    public static Collection<Object[]> data() {
        return TestParameters.provideTestData()
    }

    @Test
    public void someTest() { /* ... */ }
}

@RunWith(Parameterized.class}
public class Test2 {
    public Test2(Object param1) { /* ... */ }

    @Parameters
    public static Collection<Object[]> data() {
        return TestParameters.provideTestData()
    }

    @Test
    public void someOtherTest() { /* ... */ }
}

class TestParameters {
    public static Collection<Object[]> provideTestData() {
        Collection<Object[]> data = new ...;
        // build testdata
    return data;
}