TestingUtils: Randomization
$ dotnet add package Jds.TestingUtils.RandomizationThis collection of randomization test utilities supports creating test arrangements.
All examples below use the thread-safe, static
Jds.TestingUtils.Randomization.Randomizer.Sharedinstance ofIRandomizationSource, which generates random values usingSystem.Random.Shared. ThisIRandomizationSourceis advised for most tests.If a different algorithm is needed, e.g., a cryptographically strong random number generator is required, consider creating a
Jds.TestingUtils.Randomization.ArrangedRandomizationSource. It uses provided delegates to supply values when requested.
Func<IEnumerable<>>If a specific set of random-seeming data is needed, consider creating a Jds.TestingUtils.Randomization.DeterministicRandomizationSource. It uses provided IEnumerable<> sources to supply values when requested.
Jds.TestingUtils.Randomization NuGet Package and Add usingAdd Jds.TestingUtils.Randomization NuGet package to the test project.
Add the extensions to your test files with the following using statement:
using Jds.TestingUtils.Randomization;All examples below assume the following additional using statements:
using System;
using System.Collections.Generic;
using System.Linq;IRandomizationSource.Boolean()
bool.IRandomizationSource.Byte()
byte, greater than or equal to byte.MinValue, and less than byte.MaxValue.IRandomizationSource.ByteInRange(byte minInclusive, byte maxExclusive)
byte, greater than or equal to minInclusive, and less than maxExclusive.IRandomizationSource.Double()
double, using IRandomizationSource.NextDouble. The value should be greater than or equal to 0.0, and less than 1.0.IRandomizationSource.Float()
float, using IRandomizationSource.NextFloat. The value should be greater than or equal to 0.0, and less than 1.0.IRandomizationSource.Int()
int, using IRandomizationSource.NextIntInRange. The value should be greater than or equal to int.MinValue, and less than int.MaxValue.IRandomizationSource.IntInRange(int minInclusive, int maxExclusive)
int, using IRandomizationSource.NextIntInRange. The value should be greater than or equal to minInclusive, and less than maxExclusive.IRandomizationSource.IntNegative()
int, using IRandomizationSource.NextIntInRange. The value should be greater than or equal to int.MinValue, and less than 0.IRandomizationSource.IntPositive()
int, using IRandomizationSource.NextIntInRange. The value should be greater than or equal to 0, and less than int.MaxValue.IRandomizationSource.Long()
long, using IRandomizationSource.NextLongInRange. The value should be greater than or equal to long.MinValue, and less than long.MaxValue.IRandomizationSource.LongInRange(long minInclusive, long maxExclusive)
long, using IRandomizationSource.NextLongInRange. The value should be greater than or equal to minInclusive, and less than maxExclusive.IRandomizationSource.LongNegative()
long, using IRandomizationSource.NextLongInRange. The value should be greater than or equal to long.MinValue, and less than 0.IRandomizationSource.LongPositive()
long, using IRandomizationSource.NextLongInRange. The value should be greater than or equal to 0, and less than long.MaxValue.IRandomizationSource.RandomEnumValue<TEnum>()
enum of type specified (TEnum).Randomizer.Shared.RandomEnumValue<System.Net.HttpStatusCode>()IRandomizationSource.RandomListItem<T>(IReadOnlyList<T> items)IReadOnlyList<T>.GetRandomItem<T>()
items.Randomizer.Shared.RandomListItem(System.Linq.Enumerable.Range(1, 20).ToArray())IRandomizationSource.RandomListItem<T>(IReadOnlyList<(T Item, double Weight)> weightedItems)IRandomizationSource.RandomListItem<T>(IReadOnlyList<(T Item, int Weight)> weightedItems)IReadOnlyList<(T Key, double Weight)>.GetWeightedRandomItem<T>()IReadOnlyList<(T Key, int Weight)>.GetWeightedRandomItem<T>()
.Item from provided weightedItems; item selection is weighted based upon relative .Weight.Randomizer.Shared.WeightedRandomListItem(
new[] { ("Sure", 1000), ("Likely", 500), ("Possible", 200), ("Unlikely", 50), ("Rare", 5), ("Apocryphal", 1) }
);IRandomizationSource.GetWeightedRandomKey<T>(IReadOnlyDictionary<T, double> weightedKeys)IRandomizationSource.GetWeightedRandomKey<T>(IReadOnlyDictionary<T, int> weightedKeys)IReadOnlyDictionary<T, double>.GetWeightedRandomKey<T>()IReadOnlyDictionary<T, int>.GetWeightedRandomKey<T>()
.Key from provided weightedItems; item selection is weighted based upon relative .Value.Randomizer.Shared.WeightedRandomKey(new Dictionary<string, double>
{
{ "North", 0.4 }, { "East", 0.1 }, { "West", 0.1 }, { "South", 0.4 }
});IRandomizationSource.RandomString(int length, IReadOnlyList<char> chars)
string of length characters, using provided chars. Random selections from chars are concatenated until reaching length characters.IRandomizationSource.RandomString(int length, IReadOnlyList<string> strings)
string of length characters, using provided strings. Random selections from strings are concatenated until reaching length characters. The result is truncated to length characters.IRandomizationSource.RandomStringLatin(int length, bool uppercase = false, bool alphanumeric = false)
string of length characters using ASCII Latin characters. Uses a - z by default. If uppercase, uses A - Z. If alphanumeric, also includes 0 - 9 with either casing.IRandomizationSource.MailAddress()IRandomizationSource.MailAddress(int length)
System.Net.Mail.MailAddress. The generated System.Net.Mail.MailAddress.User will be a dot-atom form of local-part (see RFC-2822 section 3.4.1). The generated System.Net.Mail.MailAddress.Host will be a domain (see RFC-1035 section 2.3.1).IRandomizationSource.MailAddressAddrSpec(int length)IRandomizationSource.MailAddressAddrSpec((int LocalPartLength, int DomainLength) componentLengths)
string according to addr-spec (see RFC-2822 section 3.4.1). The generated local-part will be of dot-atom form (see RFC-2822 section 3.4.1). The generated domain will be of dot-atom form (see RFC-2822 section 3.4.1), and its value will be generated as a RFC-1035 section 2.3.1 domain.IRandomizationSource.DomainName(int length)IRandomizationSource.DomainName(IReadOnlyList<int> domainLabelLengths)
string according to domain (see RFC-1035 section 2.3.1).IRandomizationSource.RandomUrl(int hostLength, int pathLength = 0, int queryLength = 0, int fragmentLength = 0, string scheme = "https", int? port = null)
string URL according to RFC-3986 URI syntax. The host segment is generated using IRandomizationSource.DomainName(int length).IRandomizationSource.CreateMarkovGenerator(IReadOnlyCollection<IReadOnlyList<T>> sources, int chainLength = 1) where T : notnull, IEquatable<T>
Func<int, IReadOnlyList<T>> which accepts an int maxLength and uses a Markov Chain model, derived from sources, to generate sequences of T of up to length maxLength.
chainLength determines how many T are grouped to determine Markov Chain probability.IRandomizationSource.CreateMarkovGenerator(IEnumerable<string> sources, int chainLength = 1)
Func<int, string> which accepts an int maxLength and uses a Markov Chain model, derived from sources, to generate strings of up to length maxLength.
chainLength determines how many characters in each input string are grouped to determine Markov Chain probability.var exampleFruitNames = new[]
{
"apple", "apricot", "avocado", "banana", "blackberry", "blackcurrant", "blueberry", "boysenberry", "cantaloupe",
"caper", "cherry", "cranberry", "elderberry", "fig", "gooseberry", "grape", "grapefruit", "guava", "jujube",
"kiwi", "kumquat", "lemon", "lime", "lychee", "mango", "mulberry", "olive", "orange", "papaya", "pear",
"persimmon", "pineapple", "plantain", "plum", "pomegranate", "raspberry", "starfruit", "strawberry", "tangerine",
"watermelon"
};
Func<int, string> fruitGenerator = Randomizer.Shared.CreateMarkovGenerator(sources: exampleFruitNames, chainLength: 2);
string generatedFruit = fruitGenerator(maxLength: 12);
string possiblyLongerGeneratedFruit = fruitGenerator(maxLength: 20);
string likelyShorterGeneratedFruit = fruitGenerator(maxLength: 6);IRandomizationSource.GenerateRandomMarkov<T>(IReadOnlyCollection<IReadOnlyList<T>> sources, int? maxLength = null, int chainLength = 1)
IReadOnlyList<T> based upon a Markov Chain model, derived from sources.
chainLength determines how many items in each input IReadOnlyList<T> are grouped to determine Markov Chain probability.IRandomizationSource.CreateMarkovGenerator() (above), instead of this function, unless only a single value is needed.
IRandomizationSource.GenerateRandomMarkov(IEnumerable<string> sources, int? maxLength = null, int chainLength = 1)
string based upon a Markov Chain model, derived from sources..
chainLength determines how many characters in each input string are grouped to determine Markov Chain probability.IRandomizationSource.CreateMarkovGenerator() (above), instead of this function, unless only a single value is needed.
var exampleFruitNames = new[]
{
"apple", "apricot", "avocado", "banana", "blackberry", "blackcurrant", "blueberry", "boysenberry", "cantaloupe",
"caper", "cherry", "cranberry", "elderberry", "fig", "gooseberry", "grape", "grapefruit", "guava", "jujube",
"kiwi", "kumquat", "lemon", "lime", "lychee", "mango", "mulberry", "olive", "orange", "papaya", "pear",
"persimmon", "pineapple", "plantain", "plum", "pomegranate", "raspberry", "starfruit", "strawberry", "tangerine",
"watermelon"
};
string similarGeneratedFruit = Randomizer.Shared.GenerateRandomMarkov(sources: exampleFruitNames, maxLength: 12, chainLength: 2);
string slightlySimilarGeneratedFruit = Randomizer.Shared.GenerateRandomMarkov(sources: exampleFruitNames, maxLength: 20, chainLength: 1);
string verySimilarGeneratedFruit = Randomizer.Shared.GenerateRandomMarkov(sources: exampleFruitNames, maxLength: 15, chainLength: 3);The Lorem Ipsum random generators create Latin-like words, sentences, and paragraphs. They use Markov Chain models trained on multiple Latin sources: the traditional Lorem Ipsum excerpts of Cicero's De Finibus Bonorum et Malorum, and excerpts of René Descartes's Meditationes de Prima Philosophia.
IRandomizationSource.LoremIpsumParagraph((int WordCount, int MaxWordLength) paragraphParameters)
string of paragraphParameters.WordCount words, broken into a random number of sentences. Each word in the paragraph is no more than paragraphParameters.MaxWordLength characters.IRandomizationSource.LoremIpsumSentence((int WordCount, int MaxWordLength) sentenceParameters)
string of sentenceParameters.WordCount words, each word no more than sentenceParameters.MaxWordLength characters. Sentences always begin with a capital letter and end with a period (.).IRandomizationSource.LoremIpsumWord(int maxLength)
string of no more than maxLength characters.The name generators use Markov Chain models trained on public census and government data.
IRandomizationSource.DemographicsBirthDateTime(DateTime? relativeTo = null)IRandomizationSource.DemographicsBirthDateTime((int MinAgeInYears, int MaxAgeInYearsExclusive) ageRange, DateTime? relativeTo = null)
DateTime within the ageRange specified, relative to relativeTo. If not provided, ageRange defaults to (MinAgeInYears: 18, MaxAgeInYearsExclusive: 96). If not provided, relativeTo defaults to DateTime.UtcNow.IRandomizationSource.DemographicsForenameUsa(int maxLength)
string of no more than maxLength characters. Generated names have an initial capital letter and all subsequent characters are lowercase.IRandomizationSource.DemographicsSurnameUsa(int maxLength)
string of no more than maxLength characters. Generated names have an initial capital letter and all subsequent characters are lowercase.