带参数的JUnit测试

时间:2017-05-03 05:30:08

标签: java junit arguments parameterized

我开发了一个Web基础应用程序,它以某种方式让用户只需输入值而不是编写完整的JUnit测试来提交测试用例。

我现在使用的方法是为每个提交生成一个测试类,然后编译并运行。

例如假设我们有一个类似下面的类:

public class CalculatorO
{    
    public  boolean isPrime( int n )
    {
        if (n < 2) {
            return false;
        }
        int count = 0;
        for (int i = 1; i <= n; i++) {
            if (n % i == 0) {
                count++;
            }
        }
        if (count == 2) {
            return true;
        } else {
            return false;
        }
    }
}

作为oracle,还有另一个类似下面的人:

public class CalculatorM0
{    
    public  boolean isPrime( int n )
    {
        if (n < 2) {
            return false;
        }
        int count = 0;
        for (int i = 1; i <= n; i++) {
            if (n * i == 0) {
                count++;
            }
        }
        if (count == 2) {
            return true;
        } else {
            return false;
        }
    }    
}

作为测试的主题。然后我生成一个测试模板如下:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
import org.junit.Test;

public class {{TestClassName}} {
  @Test
  public void {{MethodName}}() {
    int AO = {{valueA}};


    int AM = {{valueA}};

    {{OriginalClassName}} {{OriginalClassNameLower}} = new {{OriginalClassName}}();
    {{MutantClassName}} {{MutantClassNameLower}} = new {{MutantClassName}}();

    {{MethodReturnType}} resultO = {{OriginalClassNameLower}}.{{MethodName}}(AO);
    {{MethodReturnType}} resultM = {{MutantClassNameLower}}.{{MethodName}}(AM);

    assertEquals(resultO, resultM);     
  }
}

然后例如当用户提交数字3作为输入值时,我操纵测试模板如下:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
import org.junit.Test;

public class CalculatorOCalculatorM0Test30099 {
  @Test
  public void isPrime() {
    int AO = 3;     
    int AM = 3;

    CalculatorO calculatorO = new CalculatorO();
    CalculatorM3 calculatorM3 = new CalculatorM3();

    boolean resultO = calculatorO.isPrime(AO);
    boolean resultM = calculatorM3.isPrime(AM);

    assertEquals(resultO, resultM);     
  }
}

然后我编译测试用例并运行它。

主要问题是这个循环经常发生,并且由于加载到服务器的负载,由于文件被创建和编译,服务器面临内存不足问题并且崩溃很多。

我正在寻找一种方法来创建一次测试用例并构建一次,然后为每个带参数的输入运行它。

我的意思是这样的:

java -cp .;../../JUnitLibs/junit-4.12.jar;../../JUnitLibs/hamcrest-core-1.3.jar org.junit.runner.JUnitCore CalculatorOCalculatorM0Test30099 > CalculatorOCalculatorM0Test30099Result -input 3

1 个答案:

答案 0 :(得分:1)

一个简单的解决方案:

  • 我会使用properties在命令行上传递这些参数
  • 将@BeforeClass方法添加到测试用例中......然后转到属性,并从那里读取所有必需的值。

换句话说:你用一些-Darg1:value1值来调用你的测试用例;并且您的测试用例会查找“arg1”;并将提供的值存储到一些字段 AO和AM中。

当然,你必须稍微修改你的代码;这里棘手的部分可能是变量类型(属性都是字符串;但你可能想要int,float,...变量)。继续前进,您可以简单地创建一个提供类似方法的帮助程序类:

public static class PropertyWrapper {
  int getInt(String propertyName) { ...

然后将您的模式替换为类似

的模式
int AO = PropertyWrapper.getInt({{valueAPropertyName}});

当然,只有当不同的 JVM运行不同的用户请求时,这才能轻松实现。含义:当你有两个 java运行,并为每个运行提供不同的 args时,每个单元测试都会看到不同的值。当你有一个 JVM应该用不同的参数多次运行这个测试时,事情变得更加复杂。然后,您将使getInt()方法具有值的列表;并一个接一个地返回;或类似的东西。