Are integer numbers generated with AutoFixture 3 unique?
Asked Answered
B

2

13

Are integer numbers generated with IFixture.Create<int>() unique?

The Wiki says that numbers are random, but it also tells us this

The first numbers are generated within the range of [1, 255], as this is a set of values that are valid for all numeric data types. The smallest numeric data type in .NET is System.Byte, which fits in this range.

When the first 255 integers have been used, numbers are subsequently picked from the range [256, 32767], which corresponds to the remaining positive numbers available for System.Int16.

Two related things at GitHub:

https://github.com/AutoFixture/AutoFixture/issues/2

https://github.com/AutoFixture/AutoFixture/pull/7

And what about those unit tests?

https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixtureUnitTest/GeneratorTest.cs#L33

[Theory, ClassData(typeof(CountTestCases))]
public void StronglyTypedEnumerationYieldsUniqueValues(int count)
{
    // Fixture setup
    var sut = new Generator<T>(new Fixture());
    // Exercise system
    var actual = sut.Take(count);
    // Verify outcome
    Assert.Equal(count, actual.Distinct().Count());
    // Teardown
}

https://github.com/AutoFixture/AutoFixture/blob/master/Src/AutoFixtureUnitTest/GeneratorTest.cs#L57

[Theory, ClassData(typeof(CountTestCases))]
public void WeaklyTypedEnumerationYieldsUniqueValues(int count)
{
    // Fixture setup
    IEnumerable sut = new Generator<T>(new Fixture());
    // Exercise system
    var actual = sut.OfType<T>().Take(count);
    // Verify outcome
    Assert.Equal(count, actual.Distinct().Count());
    // Teardown
}

I have not found a statement that says the generated numbers are unique, only those bits of information that would suggest it, but I may be wrong.

Bellbird answered 3/2, 2016 at 8:45 Comment(0)
T
17

Currently, AutoFixture endeavours to create unique numbers, but it doesn't guarantee it. For instance, you can exhaust the range, which is most likely to happen for byte values. If, for instance, you request 300 byte values, you will get duplicates, because there's only 256 values to choose from.

AutoFixture will happily reuse values once the initial set has been depleted; the alternative would be to throw an exception.

If it's important for a test case that numbers are unique, I would recommend making this explicit in the test case itself. You can combine Generator<T> with Distinct for this:

var uniqueIntegers = new Generator<int>(new Fixture()).Distinct().Take(10);

If you're using AutoFixture.Xunit2, you can request a Generator<T> via a test method argument:

[Theory, AutoData]
public void MyTest(Generator<int> g, string foo)
{
    var uniqueIntegers = g.Distinct().Take(10);
    // more test code goes here...
}
Taliped answered 3/2, 2016 at 10:28 Comment(0)
A
8

The first numbers are generated within the range of [1, 255] and there are no duplicates present. Above that range, it is currently possible to get duplicates.

This issue contains useful information on how the built-in algorithm can be improved.

Abiotic answered 3/2, 2016 at 9:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.