如何每次使用不同的测试数据多次运行相同的JUnit测试?

use*_*469 0 java junit unit-testing

我刚刚开始进行单元测试.我从教程点网站上的pdf做了junit教程.所以我的问题是,我想测试我的调车场算法和我的RPNEvaluator.

构造函数(以及任何其他可帮助您处理上下文的变量)如下所示:

ShuntingYard.java:

private ArrayList<String> tokens = new ArrayList<String>();
public ShuntingYard(ArrayList<String> tokens) {
    this.tokens = tokens;
}
Run Code Online (Sandbox Code Playgroud)

RPNEvaluator.java:

private Queue<String> polishExpression;
public RPNEvaluator(Queue<String> exp) {
    polishExpression = exp;
}
Run Code Online (Sandbox Code Playgroud)

ShuntingYard.java有一个名为toRpn()的方法,它将获取一个ArrayList并在经过一些处理后返回一个Queue.

RPNEvaluator有一个名为evaluate的方法,它将采用Queue类型并在经过一些处理后返回一个double.

有了Junit,我正在尝试编写一些单元测试,我想知道这个开始是否是最好的方法:

package testSuite;

import static org.junit.Assert.fail;

import java.util.ArrayList;

import org.junit.Before;
import org.junit.Test;

public class ExpressionEvaluationTest {

    /**
     * Initialise the lists to be used
     */
    @Before
    public void beforeTest() {
        ArrayList<String> exprOne = new ArrayList<String>();
        exprOne.add("3");
        exprOne.add("+");
        exprOne.add("4");
        exprOne.add("*");
        exprOne.add("2");
        exprOne.add("/");
        exprOne.add("(");
        exprOne.add("1");
        exprOne.add("-");
        exprOne.add("5");
        exprOne.add(")");
        exprOne.add("^");
        exprOne.add("2");
        exprOne.add("^");
        exprOne.add("3");

        ArrayList<String> exprTwo = new ArrayList<String>();
        exprTwo.add("80");
        exprTwo.add("+");
        exprTwo.add("2");

        ArrayList<String> exprThree = new ArrayList<String>();
        exprThree.add("2");
        exprThree.add("/");
        exprThree.add("1");
        exprThree.add("*");
        exprThree.add("4");

        ArrayList<String> exprFour = new ArrayList<String>();
        exprFour.add("11");
        exprFour.add("-");
        exprFour.add("(");
        exprFour.add("2");
        exprFour.add("*");
        exprFour.add("4");
        exprFour.add(")");

        ArrayList<String> exprFive = new ArrayList<String>();
        exprFive.add("120");
        exprFive.add("/");
        exprFive.add("(");
        exprFive.add("10");
        exprFive.add("*");
        exprFive.add("4");
        exprFive.add(")");

        ArrayList<String> exprSix = new ArrayList<String>();
        exprSix.add("600");
        exprSix.add("*");
        exprSix.add("2");
        exprSix.add("+");
        exprSix.add("20");
        exprSix.add("/");
        exprSix.add("4");
        exprSix.add("*");
        exprSix.add("(");
        exprSix.add("5");
        exprSix.add("-");
        exprSix.add("3");
        exprSix.add(")");

    }

    @Test
    public void test() {

    }

}
Run Code Online (Sandbox Code Playgroud)

我打算把它放在before()方法中:ShuntingYard sy = new ShuntingYard(/ arraylist here /);

然后在测试中,将列表传递给算法.我的问题是,我认为我要走很远的路,拥有参数化注释并将这些列表作为参数列表传递会更好吗?

还有一个问题:如果对任何ArrayLists的测试通过,那么我确信我可以对RPNEvaluator评估方法执行后续测试.我希望我没有暧昧.

非常感谢帮助.

Mik*_*e B 5

我会稍微改变一下.而不是仅创建几组测试数据并每次调用相同的测试将其分解为有意义的事物.而不是编写一个名为test()write的测试,为每个方面编写几个单独的测试ShuntingYard.例如:

@Test public void 
itDoesntDivideByZero()
{
    ArrayList<String> divideByZeroExpression = Arrays.asList("5", "0", "/");
    // Add code to call your method with this data here
    // Add code to verify your results here
}

@Test public void 
itCanAdd()
{
    ArrayList<String> simpleAdditionExpression = Arrays.asList("1", "2", "+");
    // Add code to call your method with this data here
    // Add code to verify your results here
}
Run Code Online (Sandbox Code Playgroud)

等等.这将使您的JUnit输出更容易阅读.如果出现故障,您在尝试添加时会发现它失败,或者在尝试评估会导致除以零的表达式时失败等等.按照您原来的方式进行操作,您只会知道它test()方法失败了.

这里的每个测试都做了三件事:

  1. 安排测试数据
  2. 对该数据执行某些操作
  3. 断言行动结果与预期一致

这个Arrange, Assert, Act习惯用法在自动化测试中很常见.您可能也会看到它被Given, When, Then称为"给定这些条件,当我调用此方法时,我应该得到这个结果".

尝试摆脱编写一个测试来测试整个类或方法的心态.编写测试来测试方法的一部分.考虑这个课程:

public class Adder {
    public int addOneTo(int someNumber) {
        return someNumber + 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

您最终可能会得到一个看起来像这样的测试套件:

@Test public void
itAddsOne()
{
    int numberToAddTo = 1;
    int result = new Adder().addOneTo(numberToAddTo);
    assertEquals("One plus one is two", 2, result);
}

@Test(expected="NullPointerException.class") public void
itChokesOnNulls()
{
   new Adder().addOneTo((Integer)null);
}

@Test public void
itDoesntOverflow()
{
    int result = new Adder().addOneTo(Integer.MAX_VALUE);
    // do whatever here to make sure it worked correctly
}
Run Code Online (Sandbox Code Playgroud)

等等.