有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java获取失败的测试用例计数(按参数)

我正试图根据给定的参数运行测试用例,并获得与每个给定参数对应的输出。通过使用JUnit Parameterized 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

相关:一个旧的issue,用于在github上的junit-team参数化运行注释之前和之后添加


共 (2) 个答案

  1. # 1 楼答案

    我提出的解决方案(虽然不是最合适的)是维护与每个参数相关的测试结果的集合。为了维护这些数据,我上了以下课程:

    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<>();
    

    我使用了HashMap

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

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

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

    @AfterClass
    public static void printResult() {
        if (!parameterResults.isEmpty()) {
            parameterResults.entrySet().stream().forEach(pR -> {
                System.out.println("\nParameter: " + pR.getKey());
                System.out.println("\tPassed: " + (pR.getValue().getFail() > 0 ? "NO" : "YES"));
                System.out.print("\tTest Cases: " + pR.getValue().getSuccess() + pR.getValue().getFail());
                System.out.print("  Successful: " + pR.getValue().getSuccess());
                System.out.println("  Failed: " + pR.getValue().getFail());
        }
    }
    

    我很想听听别人的意见。主要来说,这样做的缺点是什么?还有,它能改进吗

  2. # 2 楼答案

    正如我所知,Parametrizedrunner不提供这样的输出。相反,您可以使用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,您将获得以下输出

    Failed tests: NumberChecker.testPrimeNumberChecker testPrimeNumberChecker("2" , "true" )

    Tests run: 1, Failures: 1, Errors: 0, Skipped: 0

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

    您可以做的另一件事是,您还可以使用Parametrized在测试名称中使用参数

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

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