简体   繁体   中英

Writing a JUnit test for a random number generator

I have a method which returns a random number between 0 and 10.

public int roll(){
    int pinsKnockedDown = (int) (Math.random() * 10);
    return pinsKnockedDown;
}

How would I write a JUnit test for this? So far I have put the call in a loop so it runs 1000 times and fails the test if - the number is less than 0 - the number is more than 10

How can I test that all the numbers aren't just the same, ie

迪尔伯特

Randomness tests are potentially complex. eg in the above do you simply want to ensure you get numbers between 1 and 10 ? Do you want to ensure a uniform distribution etc.? At some stage I would suggest you want to trust Math.random() and simply ensure you haven't screwed up the limits/range, which is essentially what you're doing.

My answer was already flawed, I needed to return a number from 0-10 but my original post only returned a range from 0-9! Here is how I found that out...

Loop 100k times and make sure that the range is correct, it should be 0-10 (although I've set 10 as a variable so that the code can be re-used).

Also I store the highest and lowest values that were found during the loop and they should be at the extreme ends of the scale.

If the highest and lowest values are the same then that's an indicator that someone has faked a random number return.

The only problem that I see is that it is possible to have a false negative from this test, but it is unlikely.

@Test
public void checkPinsKnockedDownIsWithinRange() {
    int pins;
    int lowestPin = 10000;
    int highestPin = -10000;

    for (int i = 0; i < 100000; i++) {
        pins = tester.roll();
        if (pins > tester.NUMBER_OF_PINS) {
            fail("More than 10 pins were knocked down");
        }
        if (pins < 0) {
            fail("Incorrect value of pins");
        }

        if (highestPin < pins) {
            highestPin = pins;
        }

        if (lowestPin > pins) {
            lowestPin = pins;
        }
    }

    if (lowestPin == highestPin) {
        fail("The highest pin count is the same as the lowest pin count. Check the method is returning a random number, and re-run the test.");
    }

    if (lowestPin != 0) {
        fail("The lowest pin is " + lowestPin + " and it should be zero.");
    }

    if (highestPin != tester.NUMBER_OF_PINS) {
        fail("The highest pin is " + highestPin + " and it should be " + tester.NUMBER_OF_PINS + ".");
    }

}

You want to test your code, not the quality of the Java supplied Math.random(). Assume the Java method is good. All tests are necessary but not sufficient conditions for correctness. So choose some tests that will uncover likely programming errors in use of the Java supplied method.

You might test the following: Eventually, after a succession of calls, the function returns each digit at least once, without returning any numbers out of the required range.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM