hits counter

Using Random Values For Unit Testing

When writing my unit tests I don’t like to use hard coded fixed values because I either end up using the same values or, because of that, tests may succeed by coincidence.

Over time, I have developed an helper class to generate random values for testing.

namespace PauloMorgado.VisualStudio.TestTools.UnitTesting
{
    public static class RandomGenerator
    {
        public static bool Boolean();
        public static string String();
        public static string String(string prefix);
        public static short Int8();
        public static short Int8(short maxValue);
        public static short Int8(short minValue, short maxValue);
        public static short Int16();
        public static short Int16(short maxValue);
        public static short Int16(short minValue, short maxValue);
        public static int Int32();
        public static int Int32(int maxValue);
        public static int Int32(int minValue, int maxValue);
        public static TEnum Enum<TEnum>();
        public static TEnum EnumFlagsWith<TEnum>(TEnum flagsToAdd);
        public static TEnum EnumFlagsWithout<TEnum>(TEnum flagsToRemove);
        public static TEnum Enum<TEnum>(int maxValue);
        public static TEnum Enum<TEnum>(int minValue, int maxValue);
        public static System.Guid Guid();
    }
}

This is something that I would like to find on mock frameworks (like Typemock Isolator, Rhino.Mocks or MoQ).

It’s still a work in progress, but if you want to try it, it’s on my MSDN Code Gallery: Random Generator For Unit Testing

8 Comments

  • It's cool, i will try it!

  • Thanks Anders. Let me know what you think of it after using it.

  • Nice suggestions, Petar.

    I'll add them as soon as I can.

  • Hi,

    I agree with randomised unit tests to get theoretically better coverage of values but I always ensure the tests publish the random seed when they fail so I can rerun the test with the same seed and get it to fail the same way in debug.

    Regards,

    --
    Jason

  • Don't you just need the actual used values? Aren't those that make the test pass or fail?

    You can always add a System.Diagnostics.Trace.WriteLine call to record the values. Even for non random ones like when using a data set.

  • @Paulo: Wouldn't you then you have to manually sprinkle TraceLine()'s throughout your test code?

    Printing the random seed just once seems much easier way to investigate a failed test.

  • The reason there is no such feature in testing frameworks is that they do not want it. Random values in tests mean that the tests are never the same whenever they run which again violates the rule that unit tests should always be repeatable. Technically, you never run the same test this way.
    It is much cleaner, more controlled and predictable to just use hard coded real values that are the same in each test run.

  • I agree with you.

    But if I have some code that concatenates two strings (any strings) I like o do this because I don't risk making a test that only pass for a particular set of values. Over time, it might come up a set of values that makes the test fail and that means I might need to fix the code or the test.

    Another reason is that tests are written by humans. At least, this way, I don't risk writng test data.

    If I'm using an enum flags, and I'm testing just for one of the bits, it doesn't matter what the other bits are.

Comments have been disabled for this content.