根据参数获取失败的测试用例计数

时间:2016-06-08 08:23:16

标签: java junit

我正在尝试根据给定的参数运行测试用例,并且还获得与每个给定参数相对应的输出。我可以使用JUnit Parameterized Test基于提供的参数运行测试用例。我的Test类如下:

@RunWith(Parameterized.class)
public class NumberChecker {

    private final Integer inputNumber;
    private final Boolean isPrime;    
    private final Long sumOfDigits;

    public NumberChecker(Integer inputNumber, Boolean expectedResult, Long sumOfDigits) {
        this.inputNumber = inputNumber;
        this.isPrime = expectedResult;
        this.sumOfDigits = sumOfDigits;
    }

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

    @Test
    public void testPrimeNumberChecker() {
        assertEquals(isPrime, PrimeNumberChecker.validate(inputNumber));
    }

    @Test
    public void testSumOfDigits() {
        assertEquals(sumOfDigits, SumOfDigits.calculate(inputNumber));
    }

    @Test
    public void testFail() {
        fail("This is a failed test case for parameter " + inputNumber);
    }
}

但是我无法获得参数输出。以下是我的TestRunner类的片段:

printDash();
System.out.println("TEST RESULTS");
printDash();
System.out.println("Passed: " + (result.wasSuccessful() ? "YES" : "NO"));
System.out.println("Total Test Cases: " + result.getRunCount());
System.out.print("Successful: " + (result.getRunCount() - result.getFailureCount() - result.getIgnoreCount()));
System.out.print("  Ignored: " + result.getIgnoreCount());
System.out.println("  Failed: " + result.getFailureCount());
System.out.println("Run Time: " + ((double) result.getRunTime() / 1000) + " seconds");
printDash();

这给了我以下输出:

--------------------------------------------------------------------------------
TEST RESULTS
--------------------------------------------------------------------------------
Passed: NO
Total Test Cases: 15
Successful: 10  Ignored: 0  Failed: 5
Run Time: 0.078 seconds
--------------------------------------------------------------------------------

我想要的输出是:

Parameter: 2
    Passed: NO
    Test Cases: 3
    Successful: 2  Ignored: 0  Failed: 1

Parameter: 6
    Passed: NO
    Test Cases: 3
    Successful: 2  Ignored: 0  Failed: 1

Parameter: 19
    Passed: NO
    Test Cases: 3
    Successful: 2  Ignored: 0  Failed: 1

等等。

这可行吗?如果是的话,如何实现?

更新:我还应该能够打印输出,不仅可以测试失败的测试用例,还可以通过测试用例。如下:

Parameter: 22
    Passed: YES
    Test Cases: 3
    Successful: 3  Ignored: 0  Failed: 0

相关:为了在github上添加issue之前和之后的参数化运行注释而引发旧的junit-team

2 个答案:

答案 0 :(得分:1)

我想出的解决方案(尽管不是最合适的解决方案)是维护与每个参数有关的测试结果的 Collection 。我创建了以下类来维护这些数据:

services:
app.exception_listener:
    class: AppBundle\EventListener\ExceptionListener
    arguments: ['@router']
    tags:
        - { name: kernel.event_listener, event: kernel.exception }

以上只是我提出的一个基本例子;您可以添加更多信息,例如失败的测试用例列表,忽略的测试用例数等等。

现在,在测试类中,添加一个静态集合来维护参数测试结果,如下所示:

public class ParameterResult {        
    private int success = 0;
    private int fail = 0;    

    public int getSuccess() {
        return success;
    }    
    public void addSuccess() {
        this.success += 1;
    }    
    public int getFail() {
        return fail;
    }    
    public void addFail() {
        this.fail  += 1;
    }        
}

我使用了private static final Map<Integer, ParameterResult> parameterResults = new HashMap<>();

每当调用测试类的构造函数时,都会将ParameterResult的对象添加到集合中。

HashMap

此处,if (!parameterResults.containsKey(inputNumber)) { ParameterResult curParameterResult = new ParameterResult(); parameterResults.put(inputNumber, curParameterResult); } 是进行检查的参数。

按如下方式填充测试结果:

inputNumber

在执行完所有测试用例后显示测试结果。

@Test
public void testPrimeNumberChecker() {
    try {
        assertEquals(isPrime, PrimeNumberChecker.validate(inputNumber));
        parameterResults.get(inputNumber).addSuccess();
    } catch (AssertionError e) {
        parameterResults.get(inputNumber).addFail();
        throw e;
    }
}

我很乐意听取别人的意见。主要是,这样做的缺点是什么?而且,它可以改进吗?

答案 1 :(得分:0)

据我所知,Parametrized亚军并没有提供这样的输出。相反,您可以使用Theories

@RunWith(Theories.class)
public class NumberChecker  {

    @DataPoints
    public static Integer[] inputNumber(){
        return new Integer[]{2, 6, 19, 22, 23};
    };
    @DataPoints
    public static Boolean[] isPrime(){
        return new Boolean[]{true, false};
    };
    @DataPoints
    public static Long[] sumOfDigits(){
        return new Long[]{2l, 6l, 10l, 4l, 5l};
    };

    @Theory
    public void testPrimeNumberChecker(int inputNumber, boolean isPrime) {
        assertEquals(isPrime, PrimeNumberChecker.validate(inputNumber));
    }

    @Theory
    public void testSumOfDigits(int inputNumber, long sumOfDigits) {
        assertEquals(sumOfDigits, SumOfDigits.calculate(inputNumber));
    }
}

您将获得@Theory失败的以下输出

  

测试失败:NumberChecker.testPrimeNumberChecker   testPrimeNumberChecker(&#34; 2&#34;,&#34; true&#34;)

     

测试运行:1,失败:1,错误:0,跳过:0

不同之处在于测试将与所有可能的参数组合一起运行,而不仅仅是您明确声明的参数组合。但您可以使用Assumptions来过滤数据点。

您可以做的另外一件事也可以使用Parametrized在测试名称中使用参数。

@Parameters(name = "inputNumber: {0}, isPrime: {1}, sumOfDigits: {2}")

在这种情况下,测试名称将显示您的参数。