<PackageReference Include="NUnit" Version="4.3.2" />

Randomizer

public class Randomizer : Random
Randomizer returns a set of random values in a repeatable way, to allow re-running of tests if necessary. It extends the .NET Random class, providing random values for a much wider range of types. The class is used internally by the framework to generate test case data and is also exposed for use by users through the TestContext.Random property.
using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; namespace NUnit.Framework.Internal { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class Randomizer : Random { private static Random _seedGenerator; private static int _initialSeed; private static readonly Dictionary<MemberInfo, Randomizer> Randomizers; public const string DefaultStringChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789_"; private const int DefaultStringLength = 25; private const int MaxStackAllocSize = 256; public static int InitialSeed { get { return _initialSeed; } set { _initialSeed = value; _seedGenerator = new Random(_initialSeed); } } static Randomizer() { InitialSeed = new Random().Next(); Randomizers = new Dictionary<MemberInfo, Randomizer>(); } public static Randomizer GetRandomizer(MemberInfo member) { if (Randomizers.TryGetValue(member, out Randomizer value)) return value; Randomizer randomizer = CreateRandomizer(); Randomizers[member] = randomizer; return randomizer; } public static Randomizer GetRandomizer(ParameterInfo parameter) { return GetRandomizer(parameter.Member); } public static Randomizer CreateRandomizer() { return new Randomizer(_seedGenerator.Next()); } public Randomizer() { } public Randomizer(int seed) : base(seed) { } [CLSCompliant(false)] public uint NextUInt() { return NextUInt(0, uint.MaxValue); } [CLSCompliant(false)] public uint NextUInt(uint max) { return NextUInt(0, max); } [CLSCompliant(false)] public uint NextUInt(uint min, uint max) { Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max"); if (min == max) return min; uint num = max - min; uint num2 = (uint)(-1 - (int)(uint.MaxValue % num)); uint num3; do { num3 = RawUInt32(); } while (num3 > num2); return num3 % num + min; } public short NextShort() { return NextShort(0, short.MaxValue); } public short NextShort(short max) { return NextShort(0, max); } public short NextShort(short min, short max) { return (short)Next(min, max); } [CLSCompliant(false)] public ushort NextUShort() { return NextUShort(0, ushort.MaxValue); } [CLSCompliant(false)] public ushort NextUShort(ushort max) { return NextUShort(0, max); } [CLSCompliant(false)] public ushort NextUShort(ushort min, ushort max) { return (ushort)Next(min, max); } public long NextLong() { return NextLong(0, 9223372036854775807); } public long NextLong(long max) { return NextLong(0, max); } public long NextLong(long min, long max) { Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max"); if (min == max) return min; ulong num = (ulong)(max - min); ulong num2 = (ulong)(-1 - (long)(ulong.MaxValue % num)); ulong num3; do { num3 = RawUInt64(); } while (num3 > num2); return (long)(num3 % num) + min; } [CLSCompliant(false)] public ulong NextULong() { return NextULong(0, ulong.MaxValue); } [CLSCompliant(false)] public ulong NextULong(ulong max) { return NextULong(0, max); } [CLSCompliant(false)] public ulong NextULong(ulong min, ulong max) { Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max"); ulong num = max - min; if (num == 0) return min; ulong num2 = (ulong)(-1 - (long)(ulong.MaxValue % num)); ulong num3; do { num3 = RawUInt64(); } while (num3 > num2); return num3 % num + min; } public byte NextByte() { return NextByte(0, byte.MaxValue); } public byte NextByte(byte max) { return NextByte(0, max); } public byte NextByte(byte min, byte max) { return (byte)Next(min, max); } [CLSCompliant(false)] public sbyte NextSByte() { return NextSByte(0, sbyte.MaxValue); } [CLSCompliant(false)] public sbyte NextSByte(sbyte max) { return NextSByte(0, max); } [CLSCompliant(false)] public sbyte NextSByte(sbyte min, sbyte max) { return (sbyte)Next(min, max); } public bool NextBool() { return NextDouble() < 0.5; } public bool NextBool(double probability) { Guard.ArgumentInRange(probability >= 0 && probability <= 1, "Probability must be from 0.0 to 1.0", "probability"); return NextDouble() < probability; } public double NextDouble(double max) { return NextDouble() * max; } public double NextDouble(double min, double max) { Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max"); if (max == min) return min; double num = max - min; return NextDouble() * num + min; } public float NextFloat() { return (float)NextDouble(); } public float NextFloat(float max) { return (float)NextDouble((double)max); } public float NextFloat(float min, float max) { return (float)NextDouble((double)min, (double)max); } public object NextEnum(Type type) { Array values = Enum.GetValues(type); return values.GetValue(Next(0, values.Length)); } public T NextEnum<[System.Runtime.CompilerServices.Nullable(2)] T>() { return (T)NextEnum(typeof(T)); } public string GetString(int outputLength, string allowedChars) { if (outputLength < 0) throw new ArgumentOutOfRangeException("outputLength"); return string.Create(outputLength, allowedChars, delegate(Span<char> data, string allowedChars) { for (int i = 0; i < data.Length; i++) { data[i] = allowedChars[Next(0, allowedChars.Length)]; } }); } public string GetString(int outputLength) { return GetString(outputLength, "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789_"); } public string GetString() { return GetString(25, "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789_"); } public decimal NextDecimal() { return new decimal(RawInt32(), RawInt32(), RawInt32(), false, 0); } public decimal NextDecimal(decimal max) { if (max <= decimal.One) { Guard.ArgumentInRange(max > decimal.Zero, "Maximum must be greater than zero.", "max"); return decimal.Zero; } max = decimal.Floor(max); DecimalParts decimalParts = DecimalParts.FromValue(max); Guard.OperationValid(decimalParts.Scale == 0, "Decimal.Floor returned a value whose scale was not 0."); decimal num; do { int lo; int mid; int hi; if (decimalParts.High != 0) { uint maximum = decimalParts.High - 1; lo = RawInt32(); mid = RawInt32(); hi = (RawInt32() & (int)MaskToRemoveBitsGuaranteedToExceedMaximum(maximum)); } else if (decimalParts.Mid != 0) { uint maximum2 = decimalParts.Mid - 1; lo = RawInt32(); mid = (RawInt32() & (int)MaskToRemoveBitsGuaranteedToExceedMaximum(maximum2)); hi = 0; } else { uint maximum3 = decimalParts.Low - 1; lo = (RawInt32() & (int)MaskToRemoveBitsGuaranteedToExceedMaximum(maximum3)); mid = 0; hi = 0; } num = new decimal(lo, mid, hi, false, 0); } while (!(num < max)); return num; } public decimal NextDecimal(decimal min, decimal max) { Guard.ArgumentInRange(max >= min, "Maximum value must be greater than or equal to minimum.", "max"); Guard.ArgumentValid(max < decimal.Zero == min < decimal.Zero || min + decimal.MaxValue >= max, "Range too great for decimal data, use double range", "max"); if (min == max) return min; return NextDecimal(max - min) + min; } private static uint MaskToRemoveBitsGuaranteedToExceedMaximum(uint maximum) { uint num = maximum | (maximum >> 1); num |= num >> 2; num |= num >> 4; num |= num >> 8; return num | (num >> 16); } public Guid NextGuid() { byte[] array = new byte[16]; NextBytes(array); array[7] = (byte)((array[7] & 15) | 64); array[8] = (byte)((array[8] & 63) | 128); return new Guid(array); } private int RawInt32() { return (int)RawUInt32(); } private uint RawUInt32() { byte[] array = new byte[4]; NextBytes(array); return BitConverter.ToUInt32(array, 0); } private ulong RawUInt64() { byte[] array = new byte[8]; NextBytes(array); return BitConverter.ToUInt64(array, 0); } } }