# Friday, April 03, 2009

Previously, we saw how AutoFixture creates strings. In this post, I’ll explain how it creates numbers. Once again, the algorithm that I’ll explain here is the default algorithm, but if you don’t like it, you can replace it with something else.

It’s very simple: Numbers are returned in the ordered sequence of natural numbers (1, 2, 3, 4, 5, …). The first time you call

fixture.CreateAnonymous<int>();

the returned number will be 1, the second time 2, etc.

The reason I chose that particular algorithm is because it creates numbers that we, as humans, find… well… natural!

A lot of the domains we model work with natural numbers, and even if you write an API where negative numbers are allowed, it’s fairly unlikely that positive numbers will not be allowed. Thus, in most cases, small positive integers tend to be ‘nice’ values in most APIs – and recall that when we do TDD, we focus on the Happy Path, so it’s important to pick values that take us down that path.

Using the overload that takes a seed, like this:

fixture.CreateAnonymous(42);

has no effect – the seed (in this case 42) is simply ignored, so if you call this after first calling the parameterless overload twice, the return number is going to be 3.

Each number type, however, has its own sequence, so even if you’ve been creating a few Int32 instances like above,

fixture.CreateAnonymous<decimal>();

will return 1.

The following number types all work that way:

  • Byte
  • Decimal
  • Double
  • Int16
  • Int32
  • Int64
  • SByte
  • Single
  • UInt16
  • UInt32
  • UInt64
Friday, May 21, 2010 12:29:25 PM (Romance Daylight Time, UTC+02:00)
Having them sequence ordered sounds like there will not be so "non-deterministic". Wouldn't a random number be more appropriate as it would allow testing of different cases each time. Sure it would not be reproducible but at least you will get to know that there might be something wrong with the code under test.
florin
Friday, May 21, 2010 2:33:43 PM (Romance Daylight Time, UTC+02:00)
The idea about constrained non-determinism is that although test values are essentially unknown, two consecutive test runs must traverse the same branch of source code each time. In some SUTs different integer values may cause different branches to be exectured for each test run, so I found it safer to use a deterministic sequence.

For complex objects (say: a class with two writable properties of the same number type) the ordering of assignment is undefined even though the sequence of numbers is deterministic. In other words, if you have the properties Number1 and Number2, you know one gets the value 1 and the other gets the value 2, but you don't know which one gets what (it's probably deterministic anyway because Reflection is likely to always return properties in the same order, but AutoFixture does nothing to explicitly order properties and fields).

Another similar strategy could be to use random numbers from a constant seed. This would give you another stable sequence of numbers.

If none of the above is a concern (numbers do not influence the execution path) you can also choose to use pure random numbers.

In any case you can use the Register method to override the default behavior for a given type, so it's entirely possible to set it up with random numbers instead of a rising sequence.
Sunday, March 06, 2011 12:16:44 AM (Romance Standard Time, UTC+01:00)
If you offer an overload for the constructor that takes a seed, when/how is it used? As you say, it does not work in this case.
Sunday, March 06, 2011 5:24:43 AM (Romance Standard Time, UTC+01:00)
Let's say that you want to change the integer algorithm to return the seed. This can be done like this:

fixture.Customize<int>(c => c.FromSeed(i => i));
All comments require the approval of the site owner before being displayed.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, b, em, i, strike, strong) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview