1

I have a short function which gets an array and shuffles the values "around".

array_name.sort(function() { return 0.5 - Math.random() });

How can I test that I get a different array then I had before?

Of course I can mock the array, and then test if

array_name[2] != array_after[2];

But, as its random, it could happen that sometimes this position is equal and sometimes not.

What is a good approach to this?


So, its about testing the randomness

I have an approach, and of course my problem:

it('different option order when randomization is true', function() {
  var array = // getting from json.file here
  var array_after = question.shuffle(array);

  expect(array[4].text.localeCompare(array_after[1].text)).toBe(0);

});

Of course, i cannot say now that this is always different. Because i run my tests several times, and sometimes they are the same, and sometimes not...

10
  • Compare all occurrences in the array for equality. This "random" sorting algorithm of yours isn't a true random sort, though. If you have an array like this: [0,1,2,3,4,5,6,7,8,9], 9 is very unlikely to be moved to index 0 Commented Apr 30, 2014 at 8:25
  • possible duplicate of How to randomize (shuffle) a javascript array? Clarification: You seem to be looking for a proper algorithm to randomize the array. Commented Apr 30, 2014 at 8:31
  • I just have an array of objects, like 4 to 10. An object contains of a text and a value. So i just want to shuffle these few things. A complex shuffle algorithm seems overweighted for me... Commented Apr 30, 2014 at 8:37
  • comparing-two-arrays-in-javascript Commented Apr 30, 2014 at 8:41
  • 1
    Ehm, re-shuffle before the expect, if they're equal. The chances of the array still being the same are very slim then, but theoretically still possible. Commented Apr 30, 2014 at 9:23

2 Answers 2

3

What you're after is a seeded random number generator. In your tests you can control the seed and verify that different seeds consistently generates different numbers.

See http://indiegamr.com/generate-repeatable-random-numbers-in-js/ for more information.

Related questions:

Sign up to request clarification or add additional context in comments.

2 Comments

This would allow him to ensure the "randomisation" happens the same each time, and therefore he can guarantee that the array will be different after it is sorted.
As I understood it, he needs to make sure his tests don't fail in the event the random shuffling happens to generate the same array. Your unit tests should be repeatable.
-1

If you need to compare if the before / after arrays are indeed different, do something like this:

function arraysAreEqual(before, after){
    if(before.length !== after.length){
        return false;
    }
    for(var i = 0; i < before.length; i++){
        if(before[i] !== after[i]){
            return false;
        }
    }
    return true;
}

Depending on the contents of the arrays, you may need to modify the equality check in the for loop to account for nested arrays / objects.

Assuming:

var myArray = [
    {text: 'foo', value: 1},
    {text: 'bar', value: 2}
]

You can use this, for example:

if(before[i].text !== after[i].text ||
   before[i].value !== after[i].value){
    return false;
}

With this function, you should be able to use:

expect(arraysAreEqual(array, array_after)).toBe(false);

However, the test case will fail in the (improbable, but possible) case the randomizer returns the same array as the input.

6 Comments

This effectively compares the arrays, but it doesn't solve the case when the shuffle function generates the same array order.
@flitig: Is that a case that should pass, then? It's unlikely that the in / out arrays are the same. I don't see how one can test if the randomizer "works" in cases where it returns a unchanged array. Maybe a small failure rate (As in "in 2% of the test cases, the output can be the same as the input"), should be tolerated.
Sure, I see your point. I could accept that in production there's the off chance that the randomizer outputs the same array. However, I would not accept that my test suite will fail in 2% of the test runs. That's a fragile test and I would sooner remove it completely. A seeded randomizer will repeatedly work and test the functionality, why not use that?
@flitig: Hm, I see now, a seeded randomizer should consistently provide the same results for the same input (array / seed value combination) But is it productive to change the randomization just for the sake of passing test? I guess that's up to the OP.
I think that comparing two arrays is pretty much a trivial task. I would personally rely on a library to do it in a cross-browser way.The non-trivial task is to test if the "random sort" or shuffling algorithm produces sequences drawn from a target probability distribution (uniform, normal). That could take a few iterations of reshuffling.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.