Fuzzy attributes

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: https://github.com/FactoryBoy/factory_boy/issues/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.

FuzzyAttribute

class factory.fuzzy.FuzzyAttribute[source]

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

FuzzyText

class factory.fuzzy.FuzzyText(length=12, chars=string.ascii_letters, prefix='')[source]

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.

FuzzyChoice

class factory.fuzzy.FuzzyChoice(choices)[source]

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.

Warning

When using Python2 and list comprehension, use private variable names as in:

[_x.name for _x in items]

instead of:

[x.name for x in items]

choices

The list of choices to select randomly

FuzzyInteger

class factory.fuzzy.FuzzyInteger(low[, high[, step]])[source]

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].

FuzzyDecimal

class factory.fuzzy.FuzzyDecimal(low[, high[, precision=2]])[source]

The FuzzyDecimal fuzzer generates random decimals 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.

FuzzyFloat

class factory.fuzzy.FuzzyFloat(low[, high])[source]

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

FuzzyDate

class factory.fuzzy.FuzzyDate(start_date[, end_date])[source]

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

FuzzyDateTime

class factory.fuzzy.FuzzyDateTime(start_dt, [end_dt, ]force_year=None, force_month=None, force_day=None, force_hour=None, force_minute=None, force_second=None, force_microsecond=None)[source]

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 year of generated datetime.

force_month

int or None; if set, forces the month of generated datetime.

force_day

int or None; if set, forces the day of generated datetime.

force_hour

int or None; if set, forces the hour of generated datetime.

force_minute

int or None; if set, forces the minute of generated datetime.

force_second

int or None; if set, forces the second of generated datetime.

force_microsecond

int or None; if set, forces the microsecond of generated datetime.

FuzzyNaiveDateTime

class factory.fuzzy.FuzzyNaiveDateTime(start_dt, [end_dt, ]force_year=None, force_month=None, force_day=None, force_hour=None, force_minute=None, force_second=None, force_microsecond=None)[source]

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 year of generated datetime.

force_month

int or None; if set, forces the month of generated datetime.

force_day

int or None; if set, forces the day of generated datetime.

force_hour

int or None; if set, forces the hour of generated datetime.

force_minute

int or None; if set, forces the minute of generated datetime.

force_second

int or None; if set, forces the second of generated datetime.

force_microsecond

int or None; if set, forces the microsecond of generated datetime.

Custom fuzzy fields

Alternate fuzzy fields may be defined. They should inherit from the BaseFuzzyAttribute class, and override its fuzz() method.

class factory.fuzzy.BaseFuzzyAttribute[source]

Base class for all fuzzy attributes.

fuzz(self)[source]

The method responsible for generating random values. Must be overridden in subclasses.

Managing randomness

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:

factory.fuzzy.get_random_state()[source]

Call get_random_state() to retrieve the random generator’s current state.

factory.fuzzy.set_random_state(state)[source]

Use set_random_state() to set a custom state into the random generator (fetched from get_random_state() in a previous run, for instance)

factory.fuzzy.reseed_random(seed)[source]

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().