factory.fuzzy
Note
Now that FactoryBoy includes the factory.Faker
class, most of these built-in fuzzers are deprecated in favor of their Faker equivalents. Further discussion here: #271
Some tests may be interested in testing with fuzzy, random values.
This is handled by the factory.fuzzy
module, which provides a few random declarations.
Note
Use import factory.fuzzy
to load this module.
The FuzzyAttribute
uses an arbitrary callable as fuzzer. It is expected that successive calls of that function return various values.
fuzzer
The callable that generates random values
The FuzzyText
fuzzer yields random strings beginning with the given prefix
, followed by length
charactes chosen from the chars
character set, and ending with the given suffix
.
length
int, the length of the random part
prefix
text, an optional prefix to prepend to the random part
suffix
text, an optional suffix to append to the random part
chars
- char iterable, the chars to choose from; defaults to the list of ascii
letters and numbers.
The FuzzyChoice
fuzzer yields random choices from the given iterable.
Note
The passed in choices
will be converted into a list upon first use, not at declaration time.
This allows passing in, for instance, a Django queryset that will only hit the database during the database, not at import time.
choices
The list of choices to select randomly
The FuzzyInteger
fuzzer generates random integers within a given inclusive range.
The low
bound may be omitted, in which case it defaults to 0:
>>> fi = FuzzyInteger(0, 42)
>>> fi.low, fi.high
0, 42
>>> fi = FuzzyInteger(42)
>>> fi.low, fi.high
0, 42
low
int, the inclusive lower bound of generated integers
high
int, the inclusive higher bound of generated integers
step
int, the step between values in the range; for instance, a FuzzyInteger(0, 42, step=3)
might only yield values from [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42]
.
The FuzzyDecimal
fuzzer generates random decimals <decimal.Decimal>
within a given inclusive range.
The low
bound may be omitted, in which case it defaults to 0:
>>> FuzzyDecimal(0.5, 42.7)
>>> fi.low, fi.high
0.5, 42.7
>>> fi = FuzzyDecimal(42.7)
>>> fi.low, fi.high
0.0, 42.7
>>> fi = FuzzyDecimal(0.5, 42.7, 3)
>>> fi.low, fi.high, fi.precision
0.5, 42.7, 3
low
decimal, the inclusive lower bound of generated decimals
high
decimal, the inclusive higher bound of generated decimals
precision int, the number of digits to generate after the dot. The default is 2 digits.
The FuzzyFloat
fuzzer provides random float
objects within a given inclusive range.
>>> FuzzyFloat(0.5, 42.7)
>>> fi.low, fi.high
0.5, 42.7
>>> fi = FuzzyFloat(42.7)
>>> fi.low, fi.high
0.0, 42.7
low
decimal, the inclusive lower bound of generated floats
high
decimal, the inclusive higher bound of generated floats
The FuzzyDate
fuzzer generates random dates within a given inclusive range.
The end_date
bound may be omitted, in which case it defaults to the current date:
>>> fd = FuzzyDate(datetime.date(2008, 1, 1))
>>> fd.start_date, fd.end_date
datetime.date(2008, 1, 1), datetime.date(2013, 4, 16)
start_date
datetime.date
, the inclusive lower bound of generated dates
end_date
datetime.date
, the inclusive higher bound of generated dates
The FuzzyDateTime
fuzzer generates random timezone-aware datetime within a given inclusive range.
The end_dt
bound may be omitted, in which case it defaults to datetime.datetime.now()
localized into the UTC timezone.
>>> fdt = FuzzyDateTime(datetime.datetime(2008, 1, 1, tzinfo=UTC))
>>> fdt.start_dt, fdt.end_dt
datetime.datetime(2008, 1, 1, tzinfo=UTC), datetime.datetime(2013, 4, 21, 19, 13, 32, 458487, tzinfo=UTC)
The force_XXX
keyword arguments force the related value of generated datetimes:
>>> fdt = FuzzyDateTime(datetime.datetime(2008, 1, 1, tzinfo=UTC), datetime.datetime(2009, 1, 1, tzinfo=UTC),
... force_day=3, force_second=42)
>>> fdt.evaluate(2, None, False) # Actual code used by ``SomeFactory.build()``
datetime.datetime(2008, 5, 3, 12, 13, 42, 124848, tzinfo=UTC)
start_dt
datetime.datetime
, the inclusive lower bound of generated datetimes
end_dt
datetime.datetime
, the inclusive upper bound of generated datetimes
force_year
int or None; if set, forces the ~datetime.datetime.year
of generated datetime.
force_month
int or None; if set, forces the ~datetime.datetime.month
of generated datetime.
force_day
int or None; if set, forces the ~datetime.datetime.day
of generated datetime.
force_hour
int or None; if set, forces the ~datetime.datetime.hour
of generated datetime.
force_minute
int or None; if set, forces the ~datetime.datetime.minute
of generated datetime.
force_second
int or None; if set, forces the ~datetime.datetime.second
of generated datetime.
force_microsecond
int or None; if set, forces the ~datetime.datetime.microsecond
of generated datetime.
The FuzzyNaiveDateTime
fuzzer generates random naive datetime within a given inclusive range.
The end_dt
bound may be omitted, in which case it defaults to datetime.datetime.now()
:
>>> fdt = FuzzyNaiveDateTime(datetime.datetime(2008, 1, 1))
>>> fdt.start_dt, fdt.end_dt
datetime.datetime(2008, 1, 1), datetime.datetime(2013, 4, 21, 19, 13, 32, 458487)
The force_XXX
keyword arguments force the related value of generated datetimes:
>>> fdt = FuzzyNaiveDateTime(datetime.datetime(2008, 1, 1), datetime.datetime(2009, 1, 1),
... force_day=3, force_second=42)
>>> fdt.evaluate(2, None, False) # Actual code used by ``SomeFactory.build()``
datetime.datetime(2008, 5, 3, 12, 13, 42, 124848)
start_dt
datetime.datetime
, the inclusive lower bound of generated datetimes
end_dt
datetime.datetime
, the inclusive upper bound of generated datetimes
force_year
int or None; if set, forces the ~datetime.datetime.year
of generated datetime.
force_month
int or None; if set, forces the ~datetime.datetime.month
of generated datetime.
force_day
int or None; if set, forces the ~datetime.datetime.day
of generated datetime.
force_hour
int or None; if set, forces the ~datetime.datetime.hour
of generated datetime.
force_minute
int or None; if set, forces the ~datetime.datetime.minute
of generated datetime.
force_second
int or None; if set, forces the ~datetime.datetime.second
of generated datetime.
force_microsecond
int or None; if set, forces the ~datetime.datetime.microsecond
of generated datetime.
Alternate fuzzy fields may be defined. They should inherit from the BaseFuzzyAttribute
class, and override its ~BaseFuzzyAttribute.fuzz
method.
Base class for all fuzzy attributes.
fuzz(self)
The method responsible for generating random values. Must be overridden in subclasses.
Using random
in factories allows to "fuzz" a program efficiently. However, it's sometimes required to reproduce a failing test.
factory.fuzzy
uses a separate instance of random.Random
, and provides a few helpers for this:
get_random_state()
Call get_random_state
to retrieve the random generator's current state.
set_random_state(state)
Use set_random_state
to set a custom state into the random generator (fetched from get_random_state
in a previous run, for instance)
reseed_random(seed)
The reseed_random
function allows to load a chosen seed into the random generator.
Custom BaseFuzzyAttribute
subclasses SHOULD use factory.fuzzy._random
as a randomness source; this ensures that data they generate can be regenerated using the simple state from get_random_state
.