Like for the generation of sequential numbers, the generation of pseudo-random numbers is accessible in MbUnit through a dedicated attribute. You need to attach that attribute to one or several parameters of a test method. Please consider the following simple example.
public class Foo
{
private readonly value;
public int Value
{
get
{
return value;
}
}
public Foo(int value)
{
if (value < 0)
throw new ArgumentOutOfRangeException("value", "Must be greater than or equal to zero.");
if (value % 3 != 0)
throw new ArgumentException("value", "Must be divisible by 3.");
this.value = value;
}
}
Foo
instance with a negative value really throws an exception.[TestFixture]
public class FooTest
{
[Test]
[ExpectedArgumentOutOfRangeException]
public void Constructs_with_negative_value_should_throw_exception(
[RandomNumbers(Minimum = Int32.MinValue, Maximum = -1, Count = 50] int negativeValue)
{
new Foo(negativeValue);
}
}
Int32.MinValue
and -1.It is possible to intercept the generation of the numbers to filter them before they reach your test method. Let's use that feature to pass to the constructor, only values that are divisible by 3.
[TestFixture]
public class FooTest
{
[Test]
public void Constructs_with_value_divisible_by_3_ok(
[RandomNumbers(Minimum = 0, Maximum = Int32.MaxValue, Count = 50, Filter = "FilterDivisibleByThree"] int value)
{
var foo = new Foo(value);
Assert.AreEqual(value, foo.Value);
}
public static bool FilterDivisibleByThree(int value)
{
return value % 3 == 0;
}
}
Like for
SequenceNumbersAttribute
, the data generation framework works internally with System.Decimal
numbers, which are converted later by the Gallio type conversion engine when they are bound to the parameters of your test method. It means that you can use RandomNumbersAttribute
against any numeric primitive (double
, short
, byte
, etc.) and not only System.Int32
like in the previous examples.Remember that you can combine together several attributes related to data driven testing to create combinatorial tests.
[TestFixture]
public class CrazyTest
{
[Test]
public void SomeCrazyCombinatorialTest(
[EnumData(typeof(MyEnum))] MyEnum arg1,
[Column("Hello", "World")] string arg2,
[RandomNumbers(Minimum = 0.25, Maximum = 5.75, Count = 7)] double arg2,
[SequentialNumbers(Start = 0, End = 100, Count = 10)] ushort arg3)
{
// Assuming that MyEnum has 4 members,
// this test will run 4 * 2 * 7 * 10 = 560 times!
}
}