有 Java 编程相关的问题?

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

给定长度的java随机字符串单元测试

我有一个生成伪随机数的程序(只允许使用小写、大写和数字)

/**
 * 
 * @return - returns a random digit (from 0 to 9)
 * 
 */
int randomDigits() {

    return (int) (Math.random() * 10);
}

/**
 * 
 * @return - returns a random lowercase (from "a" to "z")
 */
char randomLowerCase() {

    return (char) ('a' + Math.random() * 26);
}

/**
 * 
 * @return - returns a random uppercase (from "A" to "Z")
 */
char randomUpperCase() {

    return (char) ('A' + Math.random() * 26);
}

/**
 * 
 * @return - returns a random number between 1 and 3.
 * 
 */
char randomChoice() {

    return (char) ((char) (Math.random() * 3) + 1);
}

/**
 * 
 * @param length
 *            - the length of the random string.
 * @return - returns a combined random string. All elements are builder side
 *         by side.
 * 
 *         We use the randomChoice method to get randomly upper, lower and
 *         digits.
 */
public String stringBuilder(int length) {
    StringBuilder result = new StringBuilder();
    int len = length;

    for (int i = 0; i < len; i++) {
        int ch = randomChoice();
        if (ch == 1) {
            result.append(randomDigits());
        }
        if (ch == 2) {
            result.append(randomLowerCase());
        }
        if (ch == 3) {
            result.append(randomUpperCase());

        }
    }
    return result.toString();

}

我怎样才能对代码进行测试。我尝试测试数字的范围(从0到9)

    int minRange = 0;
    int maxRange = 0;

    for (int i = 0; i < 100000; i++) {
        int result = item.randomDigits();
        if (result == 52) {
            minRange++;

        } else {
            if (result == 19) {
                maxRange++;

            }
        }
    }
    LOGGER.info("The min range in the digit is 0, and in the test appeared: {}", minRange);
    LOGGER.info("The max range in the digit is 9, and in the test appeared: {}", maxRange);

但我找不到如何测试上下


共 (2) 个答案

  1. # 1 楼答案

    测试使用任意随机性的代码是很棘手的。您可以采取两种方法:

    1. 您的测试可以有足够的迭代次数,从而有很好的机会显示逻辑中的任何错误。在许多情况下,重复1000或1000000次并检查答案的一致性是合理的。如果您还希望检查某个范围内的某些必需分布,那么这是您唯一的选择

    这可能看起来像:

    for (int i = 0; i < 1000000; i++)
        assertTrue(isValid(new RandomVal()));
    

    如果要检查所有字符是否至少出现一次:

    assertEquals(26 * 2 + 9, IntStream.range(0, 1000000)
        .mapToObj(n -> stringBuilder(6))
        .flatMap(String::chars)
        .collect(Collectors.toSet())
        .size());
    

    这使用Java8,本质上是将每个字符(作为整数)添加到集合中,然后检查集合的大小

    1. 使用模拟框架(比如Mockito)来检查结果,这是您用来生成随机性的特定输出的预期结果。这是测试是否获得正确结果边界条件(即生成器在其范围的每一端返回结果)的最佳方法

    这可能看起来像:

    Random mockRandom = mock(Random.class);
    when(mockRandom.nextFloat()).thenReturn(0.0f);
    assertTrue(isValid(new RandomVal(mockRandom));
    when(mockRandom.nextFloat()).thenReturn(1.0f - Float.MIN_VALUE);
    assertTrue(isValid(new RandomVal(mockRandom));
    

    为了完整性,这两项都值得做

  2. # 2 楼答案

    如果我理解你的问题解决方法很简单

        int minRange =  999999; //improbable big value
        int maxRange = -999999; //improbable low value
    
        for (int i = 0; i < 100000; i++) {
            int result = item.randomDigits();
            minRange = Math.min(result, minRange);
            maxRange = Math.max(result, maxRange);
        }
    

    请试一试。 如果你不喜欢数学图书馆,你当然可以不用它

        for (int i = 0; i < 100000; i++) {
            int result = item.randomDigits();
            if (result < minRange) {
                minRange = result;
            }
            if (result > maxRange) {
                maxRange = result;
            }
        }