Harry Stevens
Harry Stevens

Reputation: 1423

Testing a random number function in JavaScript with Mocha and Chai

Suppose I have a function that returns a number multiplied by two.

function double(number){
  return number * 2;
}

To test it with Mocha and Chai is easy.

var expect = require("chai").expect;

describe("#double", function(){
  it("should double a number", function(){
    expect(double(2)).to.equal(4);
    expect(double(4.5)).to.equal(9);
    expect(double(-3)).to.equal(-6);
  });
});

But now suppose I have a function that returns a random integer between two specified integers, call them min and max.

function randBetween(min, max){
  return Math.floor(Math.random() * (max - min + 1) + min);
}

I won't be able to predict what the returned value will be equal to. I could write a test that makes sure the returned value is both greater than or equal to min and less than or equal to max, but that doesn't actually test whether the returned value is random. Is there a statistically valid way for me to test whether my randBetween function is working?

P.S. I know the function does not handle invalid arguments, e.g. if max is less than min. Please leave that aside for now.

Upvotes: 3

Views: 2603

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075209

You can't test it with a single call; you'll need a large number of calls to prove randomness (within a reasonable definition of randomness).

In the large number of calls, you'll want to:

  1. Make sure it doesn't return values out of range
  2. Make sure it does provide random values within a reasonable definition of randomness (given it's a deterministic PRNG)

This question and its answers go into how to do the latter, although sadly the links in the accepted answer are mostly dead now.

The National Institute of Standards and Technology has a whole section dedicated to PRNGs, including this page describing several tests you could use to ensure the randomness of what you get back.

Of course, provided your function is implemented correctly (and it appears to be, if it's meant to return min <= value < max as is usually the case), ultimately you're testing the randomness of the underlying Math.random implementation.

Upvotes: 3

Related Questions