1FACTORYBOY(1) Factory Boy FACTORYBOY(1)
2
3
4
6 factoryboy - Factory Boy Documentation Latest VersionSupported Python
7 versionsWheel statusLicense
8
9 factory_boy is a fixtures replacement based on thoughtbot’s
10 factory_bot.
11
12 As a fixtures replacement tool, it aims to replace static, hard to
13 maintain fixtures with easy-to-use factories for complex object.
14
15 Instead of building an exhaustive test setup with every possible combi‐
16 nation of corner cases, factory_boy allows you to use objects custom‐
17 ized for the current test, while only declaring the test-specific
18 fields:
19
20 class FooTests(unittest.TestCase):
21
22 def test_with_factory_boy(self):
23 # We need a 200€, paid order, shipping to australia, for a VIP customer
24 order = OrderFactory(
25 amount=200,
26 status='PAID',
27 customer__is_vip=True,
28 address__country='AU',
29 )
30 # Run the tests here
31
32 def test_without_factory_boy(self):
33 address = Address(
34 street="42 fubar street",
35 zipcode="42Z42",
36 city="Sydney",
37 country="AU",
38 )
39 customer = Customer(
40 first_name="John",
41 last_name="Doe",
42 phone="+1234",
43 email="john.doe@example.org",
44 active=True,
45 is_vip=True,
46 address=address,
47 )
48 # etc.
49
50 factory_boy is designed to work well with various ORMs (Django, Mongo,
51 SQLAlchemy), and can easily be extended for other libraries.
52
53 Its main features include:
54
55 · Straightforward declarative syntax
56
57 · Chaining factory calls while retaining the global context
58
59 · Support for multiple build strategies (saved/unsaved instances,
60 stubbed objects)
61
62 · Multiple factories per class support, including inheritance
63
65 · Documentation: https://factoryboy.readthedocs.io/
66
67 · Repository: https://github.com/FactoryBoy/factory_boy
68
69 · Package: https://pypi.org/project/factory_boy/
70
71 · Mailing-list: factoryboy@googlegroups.com |
72 https://groups.google.com/forum/#!forum/factoryboy
73
74 factory_boy supports Python 2.7, 3.4 to 3.7, as well as PyPy 2.7 and
75 5.8.
76
78 PyPI: https://pypi.org/project/factory_boy/
79
80 $ pip install factory_boy
81
82 Source: https://github.com/FactoryBoy/factory_boy/
83
84 $ git clone git://github.com/FactoryBoy/factory_boy/
85 $ python setup.py install
86
88 NOTE:
89 This section provides a quick summary of factory_boy features. A
90 more detailed listing is available in the full documentation.
91
92 Defining factories
93 Factories declare a set of attributes used to instantiate an object.
94 The class of the object must be defined in the model field of a class
95 Meta: attribute:
96
97 import factory
98 from . import models
99
100 class UserFactory(factory.Factory):
101 class Meta:
102 model = models.User
103
104 first_name = 'John'
105 last_name = 'Doe'
106 admin = False
107
108 # Another, different, factory for the same object
109 class AdminFactory(factory.Factory):
110 class Meta:
111 model = models.User
112
113 first_name = 'Admin'
114 last_name = 'User'
115 admin = True
116
117 Using factories
118 factory_boy supports several different build strategies: build, create,
119 and stub:
120
121 # Returns a User instance that's not saved
122 user = UserFactory.build()
123
124 # Returns a saved User instance
125 user = UserFactory.create()
126
127 # Returns a stub object (just a bunch of attributes)
128 obj = UserFactory.stub()
129
130 You can use the Factory class as a shortcut for the default build
131 strategy:
132
133 # Same as UserFactory.create()
134 user = UserFactory()
135
136 No matter which strategy is used, it’s possible to override the defined
137 attributes by passing keyword arguments:
138
139 # Build a User instance and override first_name
140 >>> user = UserFactory.build(first_name='Joe')
141 >>> user.first_name
142 "Joe"
143
144 It is also possible to create a bunch of objects in a single call:
145
146 >>> users = UserFactory.build_batch(10, first_name="Joe")
147 >>> len(users)
148 10
149 >>> [user.first_name for user in users]
150 ["Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe", "Joe"]
151
152 Realistic, random values
153 Demos look better with random yet realistic values; and those realistic
154 values can also help discover bugs. For this, factory_boy relies on
155 the excellent faker library:
156
157 class RandomUserFactory(factory.Factory):
158 class Meta:
159 model = models.User
160
161 first_name = factory.Faker('first_name')
162 last_name = factory.Faker('last_name')
163
164 >>> UserFactory()
165 <User: Lucy Murray>
166
167 Reproducible random values
168 The use of fully randomized data in tests is quickly a problem for
169 reproducing broken builds. To that purpose, factory_boy provides
170 helpers to handle the random seeds it uses, located in the factory.ran‐
171 dom module:
172
173 import factory.random
174
175 def setup_test_environment():
176 factory.random.reseed_random('my_awesome_project')
177 # Other setup here
178
179 Lazy Attributes
180 Most factory attributes can be added using static values that are eval‐
181 uated when the factory is defined, but some attributes (such as fields
182 whose value is computed from other elements) will need values assigned
183 each time an instance is generated.
184
185 These “lazy” attributes can be added as follows:
186
187 class UserFactory(factory.Factory):
188 class Meta:
189 model = models.User
190
191 first_name = 'Joe'
192 last_name = 'Blow'
193 email = factory.LazyAttribute(lambda a: '{0}.{1}@example.com'.format(a.first_name, a.last_name).lower())
194 date_joined = factory.LazyFunction(datetime.now)
195
196 >>> UserFactory().email
197 "joe.blow@example.com"
198
199 NOTE:
200 LazyAttribute calls the function with the object being constructed
201 as an argument, when LazyFunction does not send any argument.
202
203 Sequences
204 Unique values in a specific format (for example, e-mail addresses) can
205 be generated using sequences. Sequences are defined by using Sequence
206 or the decorator sequence:
207
208 class UserFactory(factory.Factory):
209 class Meta:
210 model = models.User
211
212 email = factory.Sequence(lambda n: 'person{0}@example.com'.format(n))
213
214 >>> UserFactory().email
215 'person0@example.com'
216 >>> UserFactory().email
217 'person1@example.com'
218
219 Associations
220 Some objects have a complex field, that should itself be defined from a
221 dedicated factories. This is handled by the SubFactory helper:
222
223 class PostFactory(factory.Factory):
224 class Meta:
225 model = models.Post
226
227 author = factory.SubFactory(UserFactory)
228
229 The associated object’s strategy will be used:
230
231 # Builds and saves a User and a Post
232 >>> post = PostFactory()
233 >>> post.id is None # Post has been 'saved'
234 False
235 >>> post.author.id is None # post.author has been saved
236 False
237
238 # Builds but does not save a User, and then builds but does not save a Post
239 >>> post = PostFactory.build()
240 >>> post.id is None
241 True
242 >>> post.author.id is None
243 True
244
245 ORM Support
246 factory_boy has specific support for a few ORMs, through specific fac‐
247 tory.Factory subclasses:
248
249 · Django, with factory.django.DjangoModelFactory
250
251 · Mogo, with factory.mogo.MogoFactory
252
253 · MongoEngine, with factory.mongoengine.MongoEngineFactory
254
255 · SQLAlchemy, with factory.alchemy.SQLAlchemyModelFactory
256
257 Debugging factory_boy
258 Debugging factory_boy can be rather complex due to the long chains of
259 calls. Detailed logging is available through the factory logger.
260
261 A helper, factory.debug(), is available to ease debugging:
262
263 with factory.debug():
264 obj = TestModel2Factory()
265
266
267 import logging
268 logger = logging.getLogger('factory')
269 logger.addHandler(logging.StreamHandler())
270 logger.setLevel(logging.DEBUG)
271
272 This will yield messages similar to those (artificial indentation):
273
274 BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={})
275 LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>)
276 SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True
277 BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4})
278 LazyStub: Computing values for tests.test_using.TestModelFactory(one=4)
279 LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4)
280 BaseFactory: Generating tests.test_using.TestModelFactory(one=4)
281 LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
282 BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
283
285 factory_boy is distributed under the MIT License.
286
287 Issues should be opened through GitHub Issues; whenever possible, a
288 pull request should be included. Questions and suggestions are welcome
289 on the mailing-list.
290
291 All pull request should pass the test suite, which can be launched sim‐
292 ply with:
293
294 $ make test
295
296 In order to test coverage, please use:
297
298 $ make coverage
299
300 To test with a specific framework version, you may use a tox target:
301
302 # list all tox environments
303 $ tox --listenvs
304
305 # run tests inside a specific environment
306 $ tox -e py36-django20-alchemy13-mongoengine017
307
308 Valid options are:
309
310 · DJANGO for Django
311
312 · MONGOENGINE for mongoengine
313
314 · ALCHEMY for SQLAlchemy
315
316 To avoid running mongoengine tests (e.g no mongo server installed),
317 run:
318
319 $ make SKIP_MONGOENGINE=1 test
320
322 Introduction
323 The purpose of factory_boy is to provide a default way of getting a new
324 instance, while still being able to override some fields on a per-call
325 basis.
326
327 NOTE:
328 This section will drive you through an overview of factory_boy’s
329 feature. New users are advised to spend a few minutes browsing
330 through this list of useful helpers.
331
332 Users looking for quick helpers may take a look at recipes, while
333 those needing detailed documentation will be interested in the ref‐
334 erence section.
335
336 Basic usage
337 Factories declare a set of attributes used to instantiate an object,
338 whose class is defined in the class Meta’s model attribute:
339
340 · Subclass factory.Factory (or a more suitable subclass)
341
342 · Add a class Meta: block
343
344 · Set its model attribute to the target class
345
346 · Add defaults for keyword args to pass to the associated class’
347 __init__ method
348
349 import factory
350 from . import base
351
352 class UserFactory(factory.Factory):
353 class Meta:
354 model = base.User
355
356 firstname = "John"
357 lastname = "Doe"
358
359 You may now get base.User instances trivially:
360
361 >>> john = UserFactory()
362 <User: John Doe>
363
364 It is also possible to override the defined attributes by passing key‐
365 word arguments to the factory:
366
367 >>> jack = UserFactory(firstname="Jack")
368 <User: Jack Doe>
369
370 A given class may be associated to many Factory subclasses:
371
372 class EnglishUserFactory(factory.Factory):
373 class Meta:
374 model = base.User
375
376 firstname = "John"
377 lastname = "Doe"
378 lang = 'en'
379
380
381 class FrenchUserFactory(factory.Factory):
382 class Meta:
383 model = base.User
384
385 firstname = "Jean"
386 lastname = "Dupont"
387 lang = 'fr'
388
389 >>> EnglishUserFactory()
390 <User: John Doe (en)>
391 >>> FrenchUserFactory()
392 <User: Jean Dupont (fr)>
393
394 Sequences
395 When a field has a unique key, each object generated by the factory
396 should have a different value for that field. This is achieved with
397 the Sequence declaration:
398
399 class UserFactory(factory.Factory):
400 class Meta:
401 model = models.User
402
403 username = factory.Sequence(lambda n: 'user%d' % n)
404
405 >>> UserFactory()
406 <User: user0>
407 >>> UserFactory()
408 <User: user1>
409
410 NOTE:
411 For more complex situations, you may also use the @sequence() deco‐
412 rator (note that self is not added as first parameter):
413
414 class UserFactory(factory.Factory):
415 class Meta:
416 model = models.User
417
418 @factory.sequence
419 def username(n):
420 return 'user%d' % n
421
422 LazyFunction
423 In simple cases, calling a function is enough to compute the value. If
424 that function doesn’t depend on the object being built, use LazyFunc‐
425 tion to call that function; it should receive a function taking no
426 argument and returning the value for the field:
427
428 class LogFactory(factory.Factory):
429 class Meta:
430 model = models.Log
431
432 timestamp = factory.LazyFunction(datetime.now)
433
434 >>> LogFactory()
435 <Log: log at 2016-02-12 17:02:34>
436
437 >>> # The LazyFunction can be overriden
438 >>> LogFactory(timestamp=now - timedelta(days=1))
439 <Log: log at 2016-02-11 17:02:34>
440
441 NOTE:
442 For complex cases when you happen to write a specific function, the
443 @lazy_attribute() decorator should be more appropriate.
444
445 LazyAttribute
446 Some fields may be deduced from others, for instance the email based on
447 the username. The LazyAttribute handles such cases: it should receive
448 a function taking the object being built and returning the value for
449 the field:
450
451 class UserFactory(factory.Factory):
452 class Meta:
453 model = models.User
454
455 username = factory.Sequence(lambda n: 'user%d' % n)
456 email = factory.LazyAttribute(lambda obj: '%s@example.com' % obj.username)
457
458 >>> UserFactory()
459 <User: user1 (user1@example.com)>
460
461 >>> # The LazyAttribute handles overridden fields
462 >>> UserFactory(username='john')
463 <User: john (john@example.com)>
464
465 >>> # They can be directly overridden as well
466 >>> UserFactory(email='doe@example.com')
467 <User: user3 (doe@example.com)>
468
469 NOTE:
470 As for Sequence, a @lazy_attribute() decorator is available:
471
472 class UserFactory(factory.Factory):
473 class Meta:
474 model = models.User
475
476 username = factory.Sequence(lambda n: 'user%d' % n)
477
478 @factory.lazy_attribute
479 def email(self):
480 return '%s@example.com' % self.username
481
482 Inheritance
483 Once a “base” factory has been defined for a given class, alternate
484 versions can be easily defined through subclassing.
485
486 The subclassed Factory will inherit all declarations from its parent,
487 and update them with its own declarations:
488
489 class UserFactory(factory.Factory):
490 class Meta:
491 model = base.User
492
493 firstname = "John"
494 lastname = "Doe"
495 group = 'users'
496
497 class AdminFactory(UserFactory):
498 admin = True
499 group = 'admins'
500
501 >>> user = UserFactory()
502 >>> user
503 <User: John Doe>
504 >>> user.group
505 'users'
506
507 >>> admin = AdminFactory()
508 >>> admin
509 <User: John Doe (admin)>
510 >>> admin.group # The AdminFactory field has overridden the base field
511 'admins'
512
513 Any argument of all factories in the chain can easily be overridden:
514
515 >>> super_admin = AdminFactory(group='superadmins', lastname="Lennon")
516 >>> super_admin
517 <User: John Lennon (admin)>
518 >>> super_admin.group # Overridden at call time
519 'superadmins'
520
521 Non-kwarg arguments
522 Some classes take a few, non-kwarg arguments first.
523
524 This is handled by the inline_args attribute:
525
526 class MyFactory(factory.Factory):
527 class Meta:
528 model = MyClass
529 inline_args = ('x', 'y')
530
531 x = 1
532 y = 2
533 z = 3
534
535 >>> MyFactory(y=4)
536 <MyClass(1, 4, z=3)>
537
538 Altering a factory’s behaviour: parameters and traits
539 Some classes are better described with a few, simple parameters, that
540 aren’t fields on the actual model. In that case, use a Params declara‐
541 tion:
542
543 class RentalFactory(factory.Factory):
544 class Meta:
545 model = Rental
546
547 begin = factory.fuzzy.FuzzyDate(start_date=datetime.date(2000, 1, 1))
548 end = factory.LazyAttribute(lambda o: o.begin + o.duration)
549
550 class Params:
551 duration = 12
552
553 >>> RentalFactory(duration=0)
554 <Rental: 2012-03-03 -> 2012-03-03>
555 >>> RentalFactory(duration=10)
556 <Rental: 2008-12-16 -> 2012-12-26>
557
558 When many fields should be updated based on a flag, use Traits instead:
559
560 class OrderFactory(factory.Factory):
561 status = 'pending'
562 shipped_by = None
563 shipped_on = None
564
565 class Meta:
566 model = Order
567
568 class Params:
569 shipped = factory.Trait(
570 status='shipped',
571 shipped_by=factory.SubFactory(EmployeeFactory),
572 shipped_on=factory.LazyFunction(datetime.date.today),
573 )
574
575 A trait is toggled by a single boolean value:
576
577 >>> OrderFactory()
578 <Order: pending>
579 >>> OrderFactory(shipped=True)
580 <Order: shipped by John Doe on 2016-04-02>
581
582 Strategies
583 All factories support two built-in strategies:
584
585 · build provides a local object
586
587 · create instantiates a local object, and saves it to the database.
588
589 NOTE:
590 For 1.X versions, the create will actually call Associated‐
591 Class.objects.create, as for a Django model.
592
593 Starting from 2.0, factory.Factory.create() simply calls Associated‐
594 Class(**kwargs). You should use DjangoModelFactory for Django mod‐
595 els.
596
597 When a Factory includes related fields (SubFactory, RelatedFactory),
598 the parent’s strategy will be pushed onto related factories.
599
600 Calling a Factory subclass will provide an object through the default
601 strategy:
602
603 class MyFactory(factory.Factory):
604 class Meta:
605 model = MyClass
606
607 >>> MyFactory.create()
608 <MyFactory: X (saved)>
609
610 >>> MyFactory.build()
611 <MyFactory: X (unsaved)>
612
613 >>> MyFactory() # equivalent to MyFactory.create()
614 <MyClass: X (saved)>
615
616 The default strategy can be changed by setting the class Meta strategy
617 attribute.
618
619 Reference
620 This section offers an in-depth description of factory_boy features.
621
622 For internals and customization points, please refer to the internals
623 section.
624
625 The Factory class
626 Meta options
627 class factory.FactoryOptions
628 New in version 2.4.0.
629
630
631 A Factory’s behaviour can be tuned through a few settings.
632
633 For convenience, they are declared in a single class Meta
634 attribute:
635
636 class MyFactory(factory.Factory):
637 class Meta:
638 model = MyObject
639 abstract = False
640
641 model This optional attribute describes the class of objects to
642 generate.
643
644 If unset, it will be inherited from parent Factory sub‐
645 classes.
646
647 New in version 2.4.0.
648
649
650 get_model_class()
651 Returns the actual model class (FactoryOptions.model
652 might be the path to the class; this function will always
653 return a proper class).
654
655 abstract
656 This attribute indicates that the Factory subclass should
657 not be used to generate objects, but instead provides
658 some extra defaults.
659
660 It will be automatically set to True if neither the
661 Factory subclass nor its parents define the model
662 attribute.
663
664 WARNING:
665 This flag is reset to False when a Factory subclasses
666 another one if a model is set.
667
668 New in version 2.4.0.
669
670
671 inline_args
672 Some factories require non-keyword arguments to their
673 __init__(). They should be listed, in order, in the
674 inline_args attribute:
675
676 class UserFactory(factory.Factory):
677 class Meta:
678 model = User
679 inline_args = ('login', 'email')
680
681 login = 'john'
682 email = factory.LazyAttribute(lambda o: '%s@example.com' % o.login)
683 firstname = "John"
684
685 >>> UserFactory()
686 <User: john>
687 >>> User('john', 'john@example.com', firstname="John") # actual call
688
689 New in version 2.4.0.
690
691
692 exclude
693 While writing a Factory for some object, it may be useful
694 to have general fields helping defining others, but that
695 should not be passed to the model class; for instance, a
696 field named ‘now’ that would hold a reference time used
697 by other objects.
698
699 Factory fields whose name are listed in exclude will be
700 removed from the set of args/kwargs passed to the under‐
701 lying class; they can be any valid factory_boy declara‐
702 tion:
703
704 class OrderFactory(factory.Factory):
705 class Meta:
706 model = Order
707 exclude = ('now',)
708
709 now = factory.LazyFunction(datetime.datetime.utcnow)
710 started_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(hours=1))
711 paid_at = factory.LazyAttribute(lambda o: o.now - datetime.timedelta(minutes=50))
712
713 >>> OrderFactory() # The value of 'now' isn't passed to Order()
714 <Order: started 2013-04-01 12:00:00, paid 2013-04-01 12:10:00>
715
716 >>> # An alternate value may be passed for 'now'
717 >>> OrderFactory(now=datetime.datetime(2013, 4, 1, 10))
718 <Order: started 2013-04-01 09:00:00, paid 2013-04-01 09:10:00>
719
720 New in version 2.4.0.
721
722
723 rename Sometimes, a model expects a field with a name already
724 used by one of Factory’s methods.
725
726 In this case, the rename attributes allows to define
727 renaming rules: the keys of the rename dict are those
728 used in the Factory declarations, and their values the
729 new name:
730
731 class ImageFactory(factory.Factory):
732 # The model expects "attributes"
733 form_attributes = ['thumbnail', 'black-and-white']
734
735 class Meta:
736 model = Image
737 rename = {'form_attributes': 'attributes'}
738
739 strategy
740 Use this attribute to change the strategy used by a
741 Factory. The default is CREATE_STRATEGY.
742
743 Attributes and methods
744 class factory.Factory
745 Class-level attributes:
746
747 Meta
748
749 _meta New in version 2.4.0.
750
751
752 The FactoryOptions instance attached to a Factory class
753 is available as a _meta attribute.
754
755 Params New in version 2.7.0.
756
757
758 The extra parameters attached to a Factory are declared
759 through a Params class. See the “Parameters” section for
760 more information.
761
762 _options_class
763 New in version 2.4.0.
764
765
766 If a Factory subclass needs to define additional, extra
767 options, it has to provide a custom FactoryOptions sub‐
768 class.
769
770 A pointer to that custom class should be provided as
771 _options_class so that the Factory-building metaclass can
772 use it instead.
773
774 Base functions:
775
776 The Factory class provides a few methods for getting objects;
777 the usual way being to simply call the class:
778
779 >>> UserFactory() # Calls UserFactory.create()
780 >>> UserFactory(login='john') # Calls UserFactory.create(login='john')
781
782 Under the hood, factory_boy will define the Factory __new__()
783 method to call the default strategy of the Factory.
784
785 A specific strategy for getting instance can be selected by
786 calling the adequate method:
787
788 classmethod build(cls, **kwargs)
789 Provides a new object, using the ‘build’ strategy.
790
791 classmethod build_batch(cls, size, **kwargs)
792 Provides a list of size instances from the Factory,
793 through the ‘build’ strategy.
794
795 classmethod create(cls, **kwargs)
796 Provides a new object, using the ‘create’ strategy.
797
798 classmethod create_batch(cls, size, **kwargs)
799 Provides a list of size instances from the Factory,
800 through the ‘create’ strategy.
801
802 classmethod stub(cls, **kwargs)
803 Provides a new stub
804
805 classmethod stub_batch(cls, size, **kwargs)
806 Provides a list of size stubs from the Factory.
807
808 classmethod generate(cls, strategy, **kwargs)
809 Provide a new instance, with the provided strategy.
810
811 classmethod generate_batch(cls, strategy, size, **kwargs)
812 Provides a list of size instances using the specified
813 strategy.
814
815 classmethod simple_generate(cls, create, **kwargs)
816 Provide a new instance, either built (create=False) or
817 created (create=True).
818
819 classmethod simple_generate_batch(cls, create, size, **kwargs)
820 Provides a list of size instances, either built or cre‐
821 ated according to create.
822
823 Extension points:
824
825 A Factory subclass may override a couple of class methods to
826 adapt its behaviour:
827
828 classmethod _adjust_kwargs(cls, **kwargs)
829 The _adjust_kwargs() extension point allows for late
830 fields tuning.
831
832 It is called once keyword arguments have been resolved
833 and post-generation items removed, but before the
834 inline_args extraction phase.
835
836 class UserFactory(factory.Factory):
837
838 @classmethod
839 def _adjust_kwargs(cls, **kwargs):
840 # Ensure ``lastname`` is upper-case.
841 kwargs['lastname'] = kwargs['lastname'].upper()
842 return kwargs
843
844 classmethod _setup_next_sequence(cls)
845 This method will compute the first value to use for the
846 sequence counter of this factory.
847
848 It is called when the first instance of the factory (or
849 one of its subclasses) is created.
850
851 Subclasses may fetch the next free ID from the database,
852 for instance.
853
854 classmethod _build(cls, model_class, *args, **kwargs)
855 This class method is called whenever a new instance needs
856 to be built. It receives the model class (provided to
857 model), and the positional and keyword arguments to use
858 for the class once all has been computed.
859
860 Subclasses may override this for custom APIs.
861
862 classmethod _create(cls, model_class, *args, **kwargs)
863 The _create() method is called whenever an instance needs
864 to be created. It receives the same arguments as
865 _build().
866
867 Subclasses may override this for specific persistence
868 backends:
869
870 class BaseBackendFactory(factory.Factory):
871 class Meta:
872 abstract = True # Optional
873
874 @classmethod
875 def _create(cls, model_class, *args, **kwargs):
876 obj = model_class(*args, **kwargs)
877 obj.save()
878 return obj
879
880 classmethod _after_postgeneration(cls, obj, create,
881 results=None)
882
883 Parameters
884
885 · obj (object) – The object just generated
886
887 · create (bool) – Whether the object was ‘built’
888 or ‘created’
889
890 · results (dict) – Map of post-generation declara‐
891 tion name to call result
892
893 The _after_postgeneration() is called once post-genera‐
894 tion declarations have been handled.
895
896 Its arguments allow to handle specifically some post-gen‐
897 eration return values, for instance.
898
899 Advanced functions:
900
901 classmethod reset_sequence(cls, value=None, force=False)
902
903 Parameters
904
905 · value (int) – The value to reset the sequence to
906
907 · force (bool) – Whether to force-reset the
908 sequence
909
910 Allows to reset the sequence counter for a Factory. The
911 new value can be passed in as the value argument:
912
913 >>> SomeFactory.build().sequenced_attribute
914 0
915 >>> SomeFactory.reset_sequence(4)
916 >>> SomeFactory.build().sequenced_attribute
917 4
918
919 Since subclasses of a non-abstract Factory share the same
920 sequence counter, special care needs to be taken when
921 resetting the counter of such a subclass.
922
923 By default, reset_sequence() will raise a ValueError when
924 called on a subclassed Factory subclass. This can be
925 avoided by passing in the force=True flag:
926
927 >>> InheritedFactory.reset_sequence()
928 Traceback (most recent call last):
929 File "factory_boy/tests/test_base.py", line 179, in test_reset_sequence_subclass_parent
930 SubTestObjectFactory.reset_sequence()
931 File "factory_boy/factory/base.py", line 250, in reset_sequence
932 "Cannot reset the sequence of a factory subclass. "
933 ValueError: Cannot reset the sequence of a factory subclass. Please call reset_sequence() on the root factory, or call reset_sequence(forward=True).
934
935 >>> InheritedFactory.reset_sequence(force=True)
936 >>>
937
938 This is equivalent to calling reset_sequence() on the
939 base factory in the chain.
940
941 Parameters
942 New in version 2.7.0.
943
944
945 Some models have many fields that can be summarized by a few parame‐
946 ters; for instance, a train with many cars — each complete with serial
947 number, manufacturer, …; or an order that can be pend‐
948 ing/shipped/received, with a few fields to describe each step.
949
950 When building instances of such models, a couple of parameters can be
951 enough to determine all other fields; this is handled by the Params
952 section of a Factory declaration.
953
954 Simple parameters
955 Some factories only need little data:
956
957 class ConferenceFactory(factory.Factory):
958 class Meta:
959 model = Conference
960
961 class Params:
962 duration = 'short' # Or 'long'
963
964 start_date = factory.fuzzy.FuzzyDate()
965 end_date = factory.LazyAttribute(
966 lambda o: o.start_date + datetime.timedelta(days=2 if o.duration == 'short' else 7)
967 )
968 sprints_start = factory.LazyAttribute(
969 lambda o: o.end_date - datetime.timedelta(days=0 if o.duration == 'short' else 1)
970 )
971
972 >>> ConferenceFactory(duration='short')
973 <Conference: DUTH 2015 (2015-11-05 - 2015-11-08, sprints 2015-11-08)>
974 >>> ConferenceFactory(duration='long')
975 <Conference: DjangoConEU 2016 (2016-03-30 - 2016-04-03, sprints 2016-04-02)>
976
977 Any simple parameter provided to the Factory.Params section is avail‐
978 able to the whole factory, but not passed to the final class (similar
979 to the exclude behavior).
980
981 Traits
982 class factory.Trait(**kwargs)
983 New in version 2.7.0.
984
985
986 A trait’s parameters are the fields it should alter when
987 enabled.
988
989 For more complex situations, it is helpful to override a few fields at
990 once:
991
992 class OrderFactory(factory.Factory):
993 class Meta:
994 model = Order
995
996 state = 'pending'
997 shipped_on = None
998 shipped_by = None
999
1000 class Params:
1001 shipped = factory.Trait(
1002 state='shipped',
1003 shipped_on=datetime.date.today(),
1004 shipped_by=factory.SubFactory(EmployeeFactory),
1005 )
1006
1007 Such a Trait is activated or disabled by a single boolean field:
1008
1009 >>> OrderFactory()
1010 <Order: pending>
1011 Order(state='pending')
1012 >>> OrderFactory(shipped=True)
1013 <Order: shipped by John Doe on 2016-04-02>
1014
1015 A Trait can be enabled/disabled by a Factory subclass:
1016
1017 class ShippedOrderFactory(OrderFactory):
1018 shipped = True
1019
1020 Values set in a Trait can be overridden by call-time values:
1021
1022 >>> OrderFactory(shipped=True, shipped_on=last_year)
1023 <Order: shipped by John Doe on 2015-04-20>
1024
1025 Traits can be chained:
1026
1027 class OrderFactory(factory.Factory):
1028 class Meta:
1029 model = Order
1030
1031 # Can be pending/shipping/received
1032 state = 'pending'
1033 shipped_on = None
1034 shipped_by = None
1035 received_on = None
1036 received_by = None
1037
1038 class Params:
1039 shipped = factory.Trait(
1040 state='shipped',
1041 shipped_on=datetime.date.today,
1042 shipped_by=factory.SubFactory(EmployeeFactory),
1043 )
1044 received = factory.Trait(
1045 shipped=True,
1046 state='received',
1047 shipped_on=datetime.date.today - datetime.timedelta(days=4),
1048 received_on=datetime.date.today,
1049 received_by=factory.SubFactory(CustomerFactory),
1050 )
1051
1052 >>> OrderFactory(received=True)
1053 <Order: shipped by John Doe on 2016-03-20, received by Joan Smith on 2016-04-02>
1054
1055 A Trait might be overridden in Factory subclasses:
1056
1057 class LocalOrderFactory(OrderFactory):
1058
1059 class Params:
1060 received = factory.Trait(
1061 shipped=True,
1062 state='received',
1063 shipped_on=datetime.date.today - datetime.timedelta(days=1),
1064 received_on=datetime.date.today,
1065 received_by=factory.SubFactory(CustomerFactory),
1066 )
1067
1068 >>> LocalOrderFactory(received=True)
1069 <Order: shipped by John Doe on 2016-04-01, received by Joan Smith on 2016-04-02>
1070
1071 NOTE:
1072 When overriding a Trait, the whole declaration MUST be replaced.
1073
1074 Strategies
1075 factory_boy supports two main strategies for generating instances, plus
1076 stubs.
1077
1078 factory.BUILD_STRATEGY
1079 The ‘build’ strategy is used when an instance should be created,
1080 but not persisted to any datastore.
1081
1082 It is usually a simple call to the __init__() method of the
1083 model class.
1084
1085 factory.CREATE_STRATEGY
1086 The ‘create’ strategy builds and saves an instance into its
1087 appropriate datastore.
1088
1089 This is the default strategy of factory_boy; it would typically
1090 instantiate an object, then save it:
1091
1092 >>> obj = self._associated_class(*args, **kwargs)
1093 >>> obj.save()
1094 >>> return obj
1095
1096 WARNING:
1097 For backward compatibility reasons, the default behaviour of
1098 factory_boy is to call MyClass.objects.create(*args,
1099 **kwargs) when using the create strategy.
1100
1101 That policy will be used if the associated class has an
1102 objects attribute and the _create() classmethod of the
1103 Factory wasn’t overridden.
1104
1105 factory.use_strategy(strategy)
1106 Decorator
1107
1108 Change the default strategy of the decorated Factory to the cho‐
1109 sen strategy:
1110
1111 @use_strategy(factory.BUILD_STRATEGY)
1112 class UserBuildingFactory(UserFactory):
1113 pass
1114
1115 factory.STUB_STRATEGY
1116 The ‘stub’ strategy is an exception in the factory_boy world: it
1117 doesn’t return an instance of the model class, and actually
1118 doesn’t require one to be present.
1119
1120 Instead, it returns an instance of StubObject whose attributes
1121 have been set according to the declarations.
1122
1123 class factory.StubObject(object)
1124 A plain, stupid object. No method, no helpers, simply a bunch of
1125 attributes.
1126
1127 It is typically instantiated, then has its attributes set:
1128
1129 >>> obj = StubObject()
1130 >>> obj.x = 1
1131 >>> obj.y = 2
1132
1133 class factory.StubFactory(Factory)
1134 An abstract Factory, with a default strategy set to
1135 STUB_STRATEGY.
1136
1137 factory.debug(logger='factory', stream=None)
1138
1139 Parameters
1140
1141 · logger (str) – The name of the logger to enable debug
1142 for
1143
1144 · stream (file) – The stream to send debug output to,
1145 defaults to sys.stderr
1146
1147 Context manager to help debugging factory_boy behavior. It will
1148 temporarily put the target logger (e.g 'factory') in debug mode,
1149 sending all output to :obj`~sys.stderr`; upon leaving the con‐
1150 text, the logging levels are reset.
1151
1152 A typical use case is to understand what happens during a single
1153 factory call:
1154
1155 with factory.debug():
1156 obj = TestModel2Factory()
1157
1158 This will yield messages similar to those (artificial indenta‐
1159 tion):
1160
1161 BaseFactory: Preparing tests.test_using.TestModel2Factory(extra={})
1162 LazyStub: Computing values for tests.test_using.TestModel2Factory(two=<OrderedDeclarationWrapper for <factory.declarations.SubFactory object at 0x1e15610>>)
1163 SubFactory: Instantiating tests.test_using.TestModelFactory(__containers=(<LazyStub for tests.test_using.TestModel2Factory>,), one=4), create=True
1164 BaseFactory: Preparing tests.test_using.TestModelFactory(extra={'__containers': (<LazyStub for tests.test_using.TestModel2Factory>,), 'one': 4})
1165 LazyStub: Computing values for tests.test_using.TestModelFactory(one=4)
1166 LazyStub: Computed values, got tests.test_using.TestModelFactory(one=4)
1167 BaseFactory: Generating tests.test_using.TestModelFactory(one=4)
1168 LazyStub: Computed values, got tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
1169 BaseFactory: Generating tests.test_using.TestModel2Factory(two=<tests.test_using.TestModel object at 0x1e15410>)
1170
1171 Declarations
1172 Faker
1173 class factory.Faker(provider, locale=None, **kwargs)
1174 In order to easily define realistic-looking factories, use the
1175 Faker attribute declaration.
1176
1177 This is a wrapper around faker; its argument is the name of a
1178 faker provider:
1179
1180 class UserFactory(factory.Factory):
1181 class Meta:
1182 model = User
1183
1184 name = factory.Faker('name')
1185
1186 >>> user = UserFactory()
1187 >>> user.name
1188 'Lucy Cechtelar'
1189
1190 locale If a custom locale is required for one specific field,
1191 use the locale parameter:
1192
1193 class UserFactory(factory.Factory):
1194 class Meta:
1195 model = User
1196
1197 name = factory.Faker('name', locale='fr_FR')
1198
1199 >>> user = UserFactory()
1200 >>> user.name
1201 'Jean Valjean'
1202
1203 classmethod override_default_locale(cls, locale)
1204 If the locale needs to be overridden for a whole test,
1205 use override_default_locale():
1206
1207 >>> with factory.Faker.override_default_locale('de_DE'):
1208 ... UserFactory()
1209 <User: Johannes Brahms>
1210
1211 classmethod add_provider(cls, locale=None)
1212 Some projects may need to fake fields beyond those pro‐
1213 vided by faker; in such cases, use
1214 factory.Faker.add_provider() to declare additional
1215 providers for those fields:
1216
1217 factory.Faker.add_provider(SmileyProvider)
1218
1219 class FaceFactory(factory.Factory):
1220 class Meta:
1221 model = Face
1222
1223 smiley = factory.Faker('smiley')
1224
1225 LazyFunction
1226 class factory.LazyFunction(method_to_call)
1227
1228 The LazyFunction is the simplest case where the value of an attribute
1229 does not depend on the object being built.
1230
1231 It takes as argument a method to call (function, lambda…); that method
1232 should not take any argument, though keyword arguments are safe but
1233 unused, and return a value.
1234
1235 class LogFactory(factory.Factory):
1236 class Meta:
1237 model = models.Log
1238
1239 timestamp = factory.LazyFunction(datetime.now)
1240
1241 >>> LogFactory()
1242 <Log: log at 2016-02-12 17:02:34>
1243
1244 >>> # The LazyFunction can be overriden
1245 >>> LogFactory(timestamp=now - timedelta(days=1))
1246 <Log: log at 2016-02-11 17:02:34>
1247
1248 LazyFunction is also useful for assigning copies of mutable objects
1249 (like lists) to an object’s property. Example:
1250
1251 DEFAULT_TEAM = ['Player1', 'Player2']
1252
1253 class TeamFactory(factory.Factory):
1254 class Meta:
1255 model = models.Team
1256
1257 teammates = factory.LazyFunction(lambda: list(DEFAULT_TEAM))
1258
1259 Decorator
1260 The class LazyFunction does not provide a decorator.
1261
1262 For complex cases, use LazyAttribute.lazy_attribute() directly.
1263
1264 LazyAttribute
1265 class factory.LazyAttribute(method_to_call)
1266
1267 The LazyAttribute is a simple yet extremely powerful building brick for
1268 extending a Factory.
1269
1270 It takes as argument a method to call (usually a lambda); that method
1271 should accept the object being built as sole argument, and return a
1272 value.
1273
1274 class UserFactory(factory.Factory):
1275 class Meta:
1276 model = User
1277
1278 username = 'john'
1279 email = factory.LazyAttribute(lambda o: '%s@example.com' % o.username)
1280
1281 >>> u = UserFactory()
1282 >>> u.email
1283 'john@example.com'
1284
1285 >>> u = UserFactory(username='leo')
1286 >>> u.email
1287 'leo@example.com'
1288
1289 The object passed to LazyAttribute is not an instance of the target
1290 class, but instead a Resolver: a temporary container that computes the
1291 value of all declared fields.
1292
1293 Decorator
1294 factory.lazy_attribute()
1295
1296 If a simple lambda isn’t enough, you may use the lazy_attribute() deco‐
1297 rator instead.
1298
1299 This decorates an instance method that should take a single argument,
1300 self; the name of the method will be used as the name of the attribute
1301 to fill with the return value of the method:
1302
1303 class UserFactory(factory.Factory)
1304 class Meta:
1305 model = User
1306
1307 name = u"Jean"
1308
1309 @factory.lazy_attribute
1310 def email(self):
1311 # Convert to plain ascii text
1312 clean_name = (unicodedata.normalize('NFKD', self.name)
1313 .encode('ascii', 'ignore')
1314 .decode('utf8'))
1315 return u'%s@example.com' % clean_name
1316
1317 >>> joel = UserFactory(name=u"Joël")
1318 >>> joel.email
1319 u'joel@example.com'
1320
1321 Sequence
1322 class factory.Sequence(lambda)
1323
1324 If a field should be unique, and thus different for all built
1325 instances, use a Sequence.
1326
1327 This declaration takes a single argument, a function accepting a single
1328 parameter - the current sequence counter - and returning the related
1329 value.
1330
1331 class UserFactory(factory.Factory)
1332 class Meta:
1333 model = User
1334
1335 phone = factory.Sequence(lambda n: '123-555-%04d' % n)
1336
1337 >>> UserFactory().phone
1338 '123-555-0001'
1339 >>> UserFactory().phone
1340 '123-555-0002'
1341
1342 Decorator
1343 factory.sequence()
1344
1345 As with lazy_attribute(), a decorator is available for complex situa‐
1346 tions.
1347
1348 sequence() decorates an instance method, whose self method will actu‐
1349 ally be the sequence counter - this might be confusing:
1350
1351 class UserFactory(factory.Factory)
1352 class Meta:
1353 model = User
1354
1355 @factory.sequence
1356 def phone(n):
1357 a = n // 10000
1358 b = n % 10000
1359 return '%03d-555-%04d' % (a, b)
1360
1361 >>> UserFactory().phone
1362 '000-555-9999'
1363 >>> UserFactory().phone
1364 '001-555-0000'
1365
1366 Sharing
1367 The sequence counter is shared across all Sequence attributes of the
1368 Factory:
1369
1370 class UserFactory(factory.Factory):
1371 class Meta:
1372 model = User
1373
1374 phone = factory.Sequence(lambda n: '%04d' % n)
1375 office = factory.Sequence(lambda n: 'A23-B%03d' % n)
1376
1377 >>> u = UserFactory()
1378 >>> u.phone, u.office
1379 '0041', 'A23-B041'
1380 >>> u2 = UserFactory()
1381 >>> u2.phone, u2.office
1382 '0042', 'A23-B042'
1383
1384 Inheritance
1385 When a Factory inherits from another Factory and the model of the sub‐
1386 class inherits from the model of the parent, the sequence counter is
1387 shared across the Factory classes:
1388
1389 class UserFactory(factory.Factory):
1390 class Meta:
1391 model = User
1392
1393 phone = factory.Sequence(lambda n: '123-555-%04d' % n)
1394
1395
1396 class EmployeeFactory(UserFactory):
1397 office_phone = factory.Sequence(lambda n: '%04d' % n)
1398
1399 >>> u = UserFactory()
1400 >>> u.phone
1401 '123-555-0001'
1402
1403 >>> e = EmployeeFactory()
1404 >>> e.phone, e.office_phone
1405 '123-555-0002', '0002'
1406
1407 >>> u2 = UserFactory()
1408 >>> u2.phone
1409 '123-555-0003'
1410
1411 Forcing a sequence counter
1412 If a specific value of the sequence counter is required for one
1413 instance, the __sequence keyword argument should be passed to the fac‐
1414 tory method.
1415
1416 This will force the sequence counter during the call, without altering
1417 the class-level value.
1418
1419 class UserFactory(factory.Factory):
1420 class Meta:
1421 model = User
1422
1423 uid = factory.Sequence(int)
1424
1425 >>> UserFactory()
1426 <User: 0>
1427 >>> UserFactory()
1428 <User: 1>
1429 >>> UserFactory(__sequence=42)
1430 <User: 42>
1431
1432 WARNING:
1433 The impact of setting __sequence=n on a _batch call is undefined.
1434 Each generated instance may share a same counter, or use incremental
1435 values starting from the forced value.
1436
1437 LazyAttributeSequence
1438 class factory.LazyAttributeSequence(method_to_call)
1439
1440 The LazyAttributeSequence declaration merges features of Sequence and
1441 LazyAttribute.
1442
1443 It takes a single argument, a function whose two parameters are, in
1444 order:
1445
1446 · The object being built
1447
1448 · The sequence counter
1449
1450 class UserFactory(factory.Factory):
1451 class Meta:
1452 model = User
1453
1454 login = 'john'
1455 email = factory.LazyAttributeSequence(lambda o, n: '%s@s%d.example.com' % (o.login, n))
1456
1457 >>> UserFactory().email
1458 'john@s1.example.com'
1459 >>> UserFactory(login='jack').email
1460 'jack@s2.example.com'
1461
1462 Decorator
1463 factory.lazy_attribute_sequence(method_to_call)
1464
1465 As for lazy_attribute() and sequence(), the lazy_attribute_sequence()
1466 handles more complex cases:
1467
1468 class UserFactory(factory.Factory):
1469 class Meta:
1470 model = User
1471
1472 login = 'john'
1473
1474 @lazy_attribute_sequence
1475 def email(self, n):
1476 bucket = n % 10
1477 return '%s@s%d.example.com' % (self.login, bucket)
1478
1479 SubFactory
1480 class factory.SubFactory(factory, **kwargs)
1481
1482 This attribute declaration calls another Factory subclass, selecting
1483 the same build strategy and collecting extra kwargs in the process.
1484
1485 The SubFactory attribute should be called with:
1486
1487 · A Factory subclass as first argument, or the fully qualified import
1488 path to that Factory (see Circular imports)
1489
1490 · An optional set of keyword arguments that should be passed when call‐
1491 ing that factory
1492
1493 NOTE:
1494 When passing an actual Factory for the factory argument, make sure
1495 to pass the class and not instance (i.e no () after the class):
1496
1497 class FooFactory(factory.Factory):
1498 class Meta:
1499 model = Foo
1500
1501 bar = factory.SubFactory(BarFactory) # Not BarFactory()
1502
1503 Definition
1504 # A standard factory
1505 class UserFactory(factory.Factory):
1506 class Meta:
1507 model = User
1508
1509 # Various fields
1510 first_name = 'John'
1511 last_name = factory.Sequence(lambda n: 'D%se' % ('o' * n)) # De, Doe, Dooe, Doooe, ...
1512 email = factory.LazyAttribute(lambda o: '%s.%s@example.org' % (o.first_name.lower(), o.last_name.lower()))
1513
1514 # A factory for an object with a 'User' field
1515 class CompanyFactory(factory.Factory):
1516 class Meta:
1517 model = Company
1518
1519 name = factory.Sequence(lambda n: 'FactoryBoyz' + 'z' * n)
1520
1521 # Let's use our UserFactory to create that user, and override its first name.
1522 owner = factory.SubFactory(UserFactory, first_name='Jack')
1523
1524 Calling
1525 The wrapping factory will call of the inner factory:
1526
1527 >>> c = CompanyFactory()
1528 >>> c
1529 <Company: FactoryBoyz>
1530
1531 # Notice that the first_name was overridden
1532 >>> c.owner
1533 <User: Jack De>
1534 >>> c.owner.email
1535 jack.de@example.org
1536
1537 Fields of the SubFactory may be overridden from the external factory:
1538
1539 >>> c = CompanyFactory(owner__first_name='Henry')
1540 >>> c.owner
1541 <User: Henry Doe>
1542
1543 # Notice that the updated first_name was propagated to the email LazyAttribute.
1544 >>> c.owner.email
1545 henry.doe@example.org
1546
1547 # It is also possible to override other fields of the SubFactory
1548 >>> c = CompanyFactory(owner__last_name='Jones')
1549 >>> c.owner
1550 <User: Henry Jones>
1551 >>> c.owner.email
1552 henry.jones@example.org
1553
1554 Strategies
1555 The strategy chosen for the external factory will be propagated to all
1556 subfactories:
1557
1558 >>> c = CompanyFactory()
1559 >>> c.pk # Saved to the database
1560 3
1561 >>> c.owner.pk # Saved to the database
1562 8
1563
1564 >>> c = CompanyFactory.build()
1565 >>> c.pk # Not saved
1566 None
1567 >>> c.owner.pk # Not saved either
1568 None
1569
1570 Circular imports
1571 Some factories may rely on each other in a circular manner. This issue
1572 can be handled by passing the absolute import path to the target
1573 Factory to the SubFactory.
1574
1575 New in version 1.3.0.
1576
1577
1578 class UserFactory(factory.Factory):
1579 class Meta:
1580 model = User
1581
1582 username = 'john'
1583 main_group = factory.SubFactory('users.factories.GroupFactory')
1584
1585 class GroupFactory(factory.Factory):
1586 class Meta:
1587 model = Group
1588
1589 name = "MyGroup"
1590 owner = factory.SubFactory(UserFactory)
1591
1592 Obviously, such circular relationships require careful handling of
1593 loops:
1594
1595 >>> owner = UserFactory(main_group=None)
1596 >>> UserFactory(main_group__owner=owner)
1597 <john (group: MyGroup)>
1598
1599 SelfAttribute
1600 class factory.SelfAttribute(dotted_path_to_attribute)
1601
1602 Some fields should reference another field of the object being con‐
1603 structed, or an attribute thereof.
1604
1605 This is performed by the SelfAttribute declaration. That declaration
1606 takes a single argument, a dot-delimited path to the attribute to
1607 fetch:
1608
1609 class UserFactory(factory.Factory):
1610 class Meta:
1611 model = User
1612
1613 birthdate = factory.Sequence(lambda n: datetime.date(2000, 1, 1) + datetime.timedelta(days=n))
1614 birthmonth = factory.SelfAttribute('birthdate.month')
1615
1616 >>> u = UserFactory()
1617 >>> u.birthdate
1618 date(2000, 3, 15)
1619 >>> u.birthmonth
1620 3
1621
1622 Parents
1623 When used in conjunction with SubFactory, the SelfAttribute gains an
1624 “upward” semantic through the double-dot notation, as used in Python
1625 imports.
1626
1627 factory.SelfAttribute('..country.language') means “Select the language
1628 of the country of the Factory calling me”.
1629
1630 class UserFactory(factory.Factory):
1631 class Meta:
1632 model = User
1633
1634 language = 'en'
1635
1636
1637 class CompanyFactory(factory.Factory):
1638 class Meta:
1639 model = Company
1640
1641 country = factory.SubFactory(CountryFactory)
1642 owner = factory.SubFactory(UserFactory, language=factory.SelfAttribute('..country.language'))
1643
1644 >>> company = CompanyFactory()
1645 >>> company.country.language
1646 'fr'
1647 >>> company.owner.language
1648 'fr'
1649
1650 Obviously, this “follow parents” ability also handles overriding some
1651 attributes on call:
1652
1653 >>> company = CompanyFactory(country=china)
1654 >>> company.owner.language
1655 'cn'
1656
1657 This feature is also available to LazyAttribute and
1658 LazyAttributeSequence, through the factory_parent attribute of the
1659 passed-in object:
1660
1661 class CompanyFactory(factory.Factory):
1662 class Meta:
1663 model = Company
1664 country = factory.SubFactory(CountryFactory)
1665 owner = factory.SubFactory(UserFactory,
1666 language=factory.LazyAttribute(lambda user: user.factory_parent.country.language),
1667 )
1668
1669 Iterator
1670 class factory.Iterator(iterable, cycle=True, getter=None)
1671 The Iterator declaration takes successive values from the given
1672 iterable. When it is exhausted, it starts again from zero
1673 (unless cycle=False).
1674
1675 cycle The cycle argument is only useful for advanced cases,
1676 where the provided iterable has no end (as wishing to
1677 cycle it means storing values in memory…).
1678
1679 New in version 1.3.0: The cycle argument is available as
1680 of v1.3.0; previous versions had a behaviour equivalent
1681 to cycle=False.
1682
1683
1684 getter A custom function called on each value returned by the
1685 iterable. See the Getter section for details.
1686
1687 New in version 1.3.0.
1688
1689
1690 reset()
1691 Reset the internal iterator used by the attribute, so
1692 that the next value will be the first value generated by
1693 the iterator.
1694
1695 May be called several times.
1696
1697 Each call to the factory will receive the next value from the iterable:
1698
1699 class UserFactory(factory.Factory)
1700 lang = factory.Iterator(['en', 'fr', 'es', 'it', 'de'])
1701
1702 >>> UserFactory().lang
1703 'en'
1704 >>> UserFactory().lang
1705 'fr'
1706
1707 When a value is passed in for the argument, the iterator will not be
1708 advanced:
1709
1710 >>> UserFactory().lang
1711 'en'
1712 >>> UserFactory(lang='cn').lang
1713 'cn'
1714 >>> UserFactory().lang
1715 'fr'
1716
1717 Getter
1718 Some situations may reuse an existing iterable, using only some compo‐
1719 nent. This is handled by the getter attribute: this is a function that
1720 accepts as sole parameter a value from the iterable, and returns an
1721 adequate value.
1722
1723 class UserFactory(factory.Factory):
1724 class Meta:
1725 model = User
1726
1727 # CATEGORY_CHOICES is a list of (key, title) tuples
1728 category = factory.Iterator(User.CATEGORY_CHOICES, getter=lambda c: c[0])
1729
1730 Decorator
1731 factory.iterator(func)
1732
1733 When generating items of the iterator gets too complex for a simple
1734 list comprehension, use the iterator() decorator:
1735
1736 WARNING:
1737 The decorated function takes no argument, notably no self parameter.
1738
1739 class UserFactory(factory.Factory):
1740 class Meta:
1741 model = User
1742
1743 @factory.iterator
1744 def name():
1745 with open('test/data/names.dat', 'r') as f:
1746 for line in f:
1747 yield line
1748
1749 WARNING:
1750 Values from the underlying iterator are kept in memory; once the
1751 initial iterator has been emptied, saved values are used instead of
1752 executing the function instead.
1753
1754 Use factory.Iterator(my_func, cycle=False) to disable value recy‐
1755 cling.
1756
1757 Resetting
1758 In order to start back at the first value in an Iterator, simply call
1759 the reset() method of that attribute (accessing it from the bare
1760 Factory subclass):
1761
1762 >>> UserFactory().lang
1763 'en'
1764 >>> UserFactory().lang
1765 'fr'
1766 >>> UserFactory.lang.reset()
1767 >>> UserFactory().lang
1768 'en'
1769
1770 Dict and List
1771 When a factory expects lists or dicts as arguments, such values can be
1772 generated through the whole range of factory_boy declarations, with the
1773 Dict and List attributes:
1774
1775 class factory.Dict(params[, dict_factory=factory.DictFactory])
1776 The Dict class is used for dict-like attributes. It receives as
1777 non-keyword argument a dictionary of fields to define, whose
1778 value may be any factory-enabled declarations:
1779
1780 class UserFactory(factory.Factory):
1781 class Meta:
1782 model = User
1783
1784 is_superuser = False
1785 roles = factory.Dict({
1786 'role1': True,
1787 'role2': False,
1788 'role3': factory.Iterator([True, False]),
1789 'admin': factory.SelfAttribute('..is_superuser'),
1790 })
1791
1792 NOTE:
1793 Declarations used as a Dict values are evaluated within that
1794 Dict’s context; this means that you must use the ..foo syntax
1795 to access fields defined at the factory level.
1796
1797 On the other hand, the Sequence counter is aligned on the
1798 containing factory’s one.
1799
1800 The Dict behaviour can be tuned through the following parame‐
1801 ters:
1802
1803 dict_factory
1804 The actual factory to use for generating the dict can be
1805 set as a keyword argument, if an exotic dictionary-like
1806 object (SortedDict, …) is required.
1807
1808 class factory.List(items[, list_factory=factory.ListFactory])
1809 The List can be used for list-like attributes.
1810
1811 Internally, the fields are converted into a index=value dict,
1812 which makes it possible to override some values at use time:
1813
1814 class UserFactory(factory.Factory):
1815 class Meta:
1816 model = User
1817
1818 flags = factory.List([
1819 'user',
1820 'active',
1821 'admin',
1822 ])
1823
1824 >>> u = UserFactory(flags__2='superadmin')
1825 >>> u.flags
1826 ['user', 'active', 'superadmin']
1827
1828 The List behaviour can be tuned through the following parame‐
1829 ters:
1830
1831 list_factory
1832 The actual factory to use for generating the list can be
1833 set as a keyword argument, if another type (tuple, set,
1834 …) is required.
1835
1836 Maybe
1837 class factory.Maybe(decider, yes_declaration, no_declaration)
1838
1839 Sometimes, the way to build a given field depends on the value of
1840 another, for instance of a parameter.
1841
1842 In those cases, use the Maybe declaration: it takes the name of a
1843 “decider” boolean field, and two declarations; depending on the value
1844 of the field whose name is held in the ‘decider’ parameter, it will
1845 apply the effects of one or the other declaration:
1846
1847 class UserFactory(factory.Factory):
1848 class Meta:
1849 model = User
1850
1851 is_active = True
1852 deactivation_date = factory.Maybe(
1853 'is_active',
1854 yes_declaration=None,
1855 no_declaration=factory.fuzzy.FuzzyDateTime(timezone.now() - datetime.timedelta(days=10)),
1856 )
1857
1858 >>> u = UserFactory(is_active=True)
1859 >>> u.deactivation_date
1860 None
1861 >>> u = UserFactory(is_active=False)
1862 >>> u.deactivation_date
1863 datetime.datetime(2017, 4, 1, 23, 21, 23, tzinfo=UTC)
1864
1865 NOTE:
1866 If the condition for the decider is complex, use a LazyAttribute
1867 defined in the Params section of your factory to handle the computa‐
1868 tion.
1869
1870 Post-generation hooks
1871 Some objects expect additional method calls or complex processing for
1872 proper definition. For instance, a User may need to have a related
1873 Profile, where the Profile is built from the User object.
1874
1875 To support this pattern, factory_boy provides the following tools:
1876
1877 · PostGenerationMethodCall: allows you to hook a particular
1878 attribute to a function call
1879
1880 · PostGeneration: this class allows calling a given function
1881 with the generated object as argument
1882
1883 · post_generation(): decorator performing the same functions as
1884 PostGeneration
1885
1886 · RelatedFactory: this builds or creates a given factory after
1887 building/creating the first Factory.
1888
1889 · RelatedFactoryList: this builds or creates a list of the given
1890 factory after building/creating the first Factory.
1891
1892 Post-generation hooks are called in the same order they are declared in
1893 the factory class, so that functions can rely on the side effects
1894 applied by the previous post-generation hook.
1895
1896 Extracting parameters
1897 All post-building hooks share a common base for picking parameters from
1898 the set of attributes passed to the Factory.
1899
1900 For instance, a PostGeneration hook is declared as post:
1901
1902 class SomeFactory(factory.Factory):
1903 class Meta:
1904 model = SomeObject
1905
1906 @post_generation
1907 def post(obj, create, extracted, **kwargs):
1908 obj.set_origin(create)
1909
1910 When calling the factory, some arguments will be extracted for this
1911 method:
1912
1913 · If a post argument is passed, it will be passed as the extracted
1914 field
1915
1916 · Any argument starting with post__XYZ will be extracted, its post__
1917 prefix removed, and added to the kwargs passed to the post-generation
1918 hook.
1919
1920 Extracted arguments won’t be passed to the model class.
1921
1922 Thus, in the following call:
1923
1924 >>> SomeFactory(
1925 post=1,
1926 post_x=2,
1927 post__y=3,
1928 post__z__t=42,
1929 )
1930
1931 The post hook will receive 1 as extracted and {'y': 3, 'z__t': 42} as
1932 keyword arguments; {'post_x': 2} will be passed to SomeFac‐
1933 tory._meta.model.
1934
1935 RelatedFactory
1936 class factory.RelatedFactory(factory, factory_related_name='',
1937 **kwargs)
1938 A RelatedFactory behaves mostly like a SubFactory, with the main
1939 difference that the related Factory will be generated after the
1940 base Factory.
1941
1942 factory
1943 As for SubFactory, the factory argument can be:
1944
1945 · A Factory subclass
1946
1947 · Or the fully qualified path to a Factory subclass (see
1948 Circular imports for details)
1949
1950 name The generated object (where the RelatedFactory attribute
1951 will set) may be passed to the related factory if the
1952 factory_related_name parameter is set.
1953
1954 It will be passed as a keyword argument, using the name
1955 value as keyword:
1956
1957 NOTE:
1958 When passing an actual Factory for the factory argument, make sure
1959 to pass the class and not instance (i.e no () after the class):
1960
1961 class FooFactory(factory.Factory):
1962 class Meta:
1963 model = Foo
1964
1965 bar = factory.RelatedFactory(BarFactory) # Not BarFactory()
1966
1967 class CityFactory(factory.Factory):
1968 class Meta:
1969 model = City
1970
1971 capital_of = None
1972 name = "Toronto"
1973
1974 class CountryFactory(factory.Factory):
1975 class Meta:
1976 model = Country
1977
1978 lang = 'fr'
1979 capital_city = factory.RelatedFactory(CityFactory, 'capital_of', name="Paris")
1980
1981 >>> france = CountryFactory()
1982 >>> City.objects.get(capital_of=france)
1983 <City: Paris>
1984
1985 Extra kwargs may be passed to the related factory, through the usual
1986 ATTR__SUBATTR syntax:
1987
1988 >>> england = CountryFactory(lang='en', capital_city__name="London")
1989 >>> City.objects.get(capital_of=england)
1990 <City: London>
1991
1992 If a value is passed for the RelatedFactory attribute, this disables
1993 RelatedFactory generation:
1994
1995 >>> france = CountryFactory()
1996 >>> paris = City.objects.get()
1997 >>> paris
1998 <City: Paris>
1999 >>> reunion = CountryFactory(capital_city=paris)
2000 >>> City.objects.count() # No new capital_city generated
2001 1
2002 >>> guyane = CountryFactory(capital_city=paris, capital_city__name='Kourou')
2003 >>> City.objects.count() # No new capital_city generated, ``name`` ignored.
2004 1
2005
2006 NOTE:
2007 The target of the RelatedFactory is evaluated after the initial fac‐
2008 tory has been instantiated. However, the build context is passed
2009 down to that factory; this means that calls to factory.SelfAttribute
2010 can go back to the calling factorry’s context:
2011
2012 class CountryFactory(factory.Factory):
2013 class Meta:
2014 model = Country
2015
2016 lang = 'fr'
2017 capital_city = factory.RelatedFactory(CityFactory, 'capital_of',
2018 # Would also work with SelfAttribute('capital_of.lang')
2019 main_lang=factory.SelfAttribute('..lang'),
2020 )
2021
2022 RelatedFactoryList
2023 class factory.RelatedFactoryList(factory, factory_related_name='',
2024 size=2, **kwargs)
2025 A RelatedFactoryList behaves like a RelatedFactory, only it
2026 returns a list of factories. This is useful for simulating
2027 one-to-many relations, rather than the one-to-one relation
2028 generated by RelatedFactory.
2029
2030 factory
2031 As for SubFactory, the factory argument can be:
2032
2033 · A Factory subclass
2034
2035 · Or the fully qualified path to a Factory subclass
2036 (see Circular imports for details)
2037
2038 name The generated object (where the RelatedFactory
2039 attribute will set) may be passed to the related fac‐
2040 tories if the factory_related_name parameter is set.
2041
2042 It will be passed as a keyword argument, using the
2043 name value as keyword:
2044
2045 size Either an int, or a lambda that returns an int, which
2046 will define the number of related Factories to be gen‐
2047 erated for each parent object.
2048
2049 New in version 2.12: Note that the API for RelatedFactoryList is
2050 considered experimental, and might change in a future version
2051 for increased consistency with other declarations.
2052
2053
2054 NOTE:
2055 Note that using a lambda for size allows the number of related
2056 objects per parents object to vary. This is useful for testing, when
2057 you likely don’t want your mock data to have parent objects with the
2058 exact same, static number of related objects.
2059
2060 LIST_SIZES = [1, 2, 3, 4, 5]
2061
2062 class FooFactory(factory.Factory):
2063 class Meta:
2064 model = Foo
2065 # Generate a list of `factory` objects of random size, ranging from 1 -> 5
2066 bar = factory.RelatedFactoryList(BarFactory,
2067 size=lambda: LIST_SIZES[random.randint(0,5)])
2068 # Each Foo object will have exactly 3 Bar objects generated for its foobar attribute.
2069 foobar = factory.RelatedFactoryList(BarFactory, size=3])
2070
2071 PostGeneration
2072 class factory.PostGeneration(callable)
2073
2074 The PostGeneration declaration performs actions once the model object
2075 has been generated.
2076
2077 Its sole argument is a callable, that will be called once the base
2078 object has been generated.
2079
2080 Once the base object has been generated, the provided callable will be
2081 called as callable(obj, create, extracted, **kwargs), where:
2082
2083 · obj is the base object previously generated
2084
2085 · create is a boolean indicating which strategy was used
2086
2087 · extracted is None unless a value was passed in for the PostGeneration
2088 declaration at Factory declaration time
2089
2090 · kwargs are any extra parameters passed as attr__key=value when call‐
2091 ing the Factory:
2092
2093 class UserFactory(factory.Factory):
2094 class Meta:
2095 model = User
2096
2097 login = 'john'
2098 make_mbox = factory.PostGeneration(
2099 lambda obj, create, extracted, **kwargs: os.makedirs(obj.login))
2100
2101 Decorator
2102 factory.post_generation()
2103
2104 A decorator is also provided, decorating a single method accepting the
2105 same obj, create, extracted and keyword arguments as PostGeneration.
2106
2107 class UserFactory(factory.Factory):
2108 class Meta:
2109 model = User
2110
2111 login = 'john'
2112
2113 @factory.post_generation
2114 def mbox(obj, create, extracted, **kwargs):
2115 if not create:
2116 return
2117 path = extracted or os.path.join('/tmp/mbox/', self.login)
2118 os.path.makedirs(path)
2119 return path
2120
2121 >>> UserFactory.build() # Nothing was created
2122 >>> UserFactory.create() # Creates dir /tmp/mbox/john
2123 >>> UserFactory.create(login='jack') # Creates dir /tmp/mbox/jack
2124 >>> UserFactory.create(mbox='/tmp/alt') # Creates dir /tmp/alt
2125
2126 PostGenerationMethodCall
2127 class factory.PostGenerationMethodCall(method_name, *arg, **kwargs)
2128 The PostGenerationMethodCall declaration will call a method on
2129 the generated object just after instantiation. This declaration
2130 class provides a friendly means of generating attributes of a
2131 factory instance during initialization. The declaration is cre‐
2132 ated using the following arguments:
2133
2134 method_name
2135 The name of the method to call on the model object
2136
2137 arg The default, optional, positional argument to pass to the
2138 method given in method_name
2139
2140 kwargs The default set of keyword arguments to pass to the
2141 method given in method_name
2142
2143 Once the factory instance has been generated, the method specified in
2144 method_name will be called on the generated object with any arguments
2145 specified in the PostGenerationMethodCall declaration, by default.
2146
2147 For example, to set a default password on a generated User instance
2148 during instantiation, we could make a declaration for a password
2149 attribute like below:
2150
2151 class UserFactory(factory.Factory):
2152 class Meta:
2153 model = User
2154
2155 username = 'user'
2156 password = factory.PostGenerationMethodCall('set_password',
2157 'defaultpassword')
2158
2159 When we instantiate a user from the UserFactory, the factory will cre‐
2160 ate a password attribute by calling User.set_password('defaultpass‐
2161 word'). Thus, by default, our users will have a password set to
2162 'defaultpassword'.
2163
2164 >>> u = UserFactory() # Calls user.set_password('defaultpassword')
2165 >>> u.check_password('defaultpassword')
2166 True
2167
2168 If the PostGenerationMethodCall declaration contained no arguments or
2169 one argument, an overriding value can be passed directly to the method
2170 through a keyword argument matching the attribute name. For example we
2171 can override the default password specified in the declaration above by
2172 simply passing in the desired password as a keyword argument to the
2173 factory during instantiation.
2174
2175 >>> other_u = UserFactory(password='different') # Calls user.set_password('different')
2176 >>> other_u.check_password('defaultpassword')
2177 False
2178 >>> other_u.check_password('different')
2179 True
2180
2181 NOTE:
2182 For Django models, unless the object method called by
2183 PostGenerationMethodCall saves the object back to the database, we
2184 will have to explicitly remember to save the object back if we per‐
2185 formed a create().
2186
2187 >>> u = UserFactory.create() # u.password has not been saved back to the database
2188 >>> u.save() # we must remember to do it ourselves
2189
2190 We can avoid this by subclassing from DjangoModelFactory, instead,
2191 e.g.,
2192
2193 class UserFactory(factory.django.DjangoModelFactory):
2194 class Meta:
2195 model = User
2196
2197 username = 'user'
2198 password = factory.PostGenerationMethodCall('set_password',
2199 'defaultpassword')
2200
2201 WARNING:
2202 In order to keep a consistent and simple API, a
2203 PostGenerationMethodCall allows at most one positional argument; all
2204 other parameters should be passed as keyword arguments.
2205
2206 Keywords extracted from the factory arguments are merged into the
2207 defaults present in the PostGenerationMethodCall declaration.
2208
2209 >>> UserFactory(password__disabled=True) # Calls user.set_password('', 'sha1', disabled=True)
2210
2211 Module-level functions
2212 Beyond the Factory class and the various Declarations classes and meth‐
2213 ods, factory_boy exposes a few module-level functions, mostly useful
2214 for lightweight factory generation.
2215
2216 Lightweight factory declaration
2217 factory.make_factory(klass, **kwargs)
2218 The make_factory() function takes a class, declarations as key‐
2219 word arguments, and generates a new Factory for that class
2220 accordingly:
2221
2222 UserFactory = make_factory(User,
2223 login='john',
2224 email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
2225 )
2226
2227 # This is equivalent to:
2228
2229 class UserFactory(factory.Factory):
2230 class Meta:
2231 model = User
2232
2233 login = 'john'
2234 email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)
2235
2236 An alternate base class to Factory can be specified in the FAC‐
2237 TORY_CLASS argument:
2238
2239 UserFactory = make_factory(models.User,
2240 login='john',
2241 email=factory.LazyAttribute(lambda u: '%s@example.com' % u.login),
2242 FACTORY_CLASS=factory.django.DjangoModelFactory,
2243 )
2244
2245 # This is equivalent to:
2246
2247 class UserFactory(factory.django.DjangoModelFactory):
2248 class Meta:
2249 model = models.User
2250
2251 login = 'john'
2252 email = factory.LazyAttribute(lambda u: '%s@example.com' % u.login)
2253
2254 New in version 2.0.0: The FACTORY_CLASS kwarg was added in
2255 2.0.0.
2256
2257
2258 Instance building
2259 The factory module provides a bunch of shortcuts for creating a factory
2260 and extracting instances from them:
2261
2262 factory.build(klass, FACTORY_CLASS=None, **kwargs)
2263
2264 factory.build_batch(klass, size, FACTORY_CLASS=None, **kwargs)
2265 Create a factory for klass using declarations passed in kwargs;
2266 return an instance built from that factory, or a list of size
2267 instances (for build_batch()).
2268
2269 Parameters
2270
2271 · klass (class) – Class of the instance to build
2272
2273 · size (int) – Number of instances to build
2274
2275 · kwargs – Declarations to use for the generated factory
2276
2277 · FACTORY_CLASS – Alternate base class (instead of
2278 Factory)
2279
2280 factory.create(klass, FACTORY_CLASS=None, **kwargs)
2281
2282 factory.create_batch(klass, size, FACTORY_CLASS=None, **kwargs)
2283 Create a factory for klass using declarations passed in kwargs;
2284 return an instance created from that factory, or a list of size
2285 instances (for create_batch()).
2286
2287 Parameters
2288
2289 · klass (class) – Class of the instance to create
2290
2291 · size (int) – Number of instances to create
2292
2293 · kwargs – Declarations to use for the generated factory
2294
2295 · FACTORY_CLASS – Alternate base class (instead of
2296 Factory)
2297
2298 factory.stub(klass, FACTORY_CLASS=None, **kwargs)
2299
2300 factory.stub_batch(klass, size, FACTORY_CLASS=None, **kwargs)
2301 Create a factory for klass using declarations passed in kwargs;
2302 return an instance stubbed from that factory, or a list of size
2303 instances (for stub_batch()).
2304
2305 Parameters
2306
2307 · klass (class) – Class of the instance to stub
2308
2309 · size (int) – Number of instances to stub
2310
2311 · kwargs – Declarations to use for the generated factory
2312
2313 · FACTORY_CLASS – Alternate base class (instead of
2314 Factory)
2315
2316 factory.generate(klass, strategy, FACTORY_CLASS=None, **kwargs)
2317
2318 factory.generate_batch(klass, strategy, size, FACTORY_CLASS=None,
2319 **kwargs)
2320 Create a factory for klass using declarations passed in kwargs;
2321 return an instance generated from that factory with the strategy
2322 strategy, or a list of size instances (for generate_batch()).
2323
2324 Parameters
2325
2326 · klass (class) – Class of the instance to generate
2327
2328 · strategy (str) – The strategy to use
2329
2330 · size (int) – Number of instances to generate
2331
2332 · kwargs – Declarations to use for the generated factory
2333
2334 · FACTORY_CLASS – Alternate base class (instead of
2335 Factory)
2336
2337 factory.simple_generate(klass, create, FACTORY_CLASS=None, **kwargs)
2338
2339 factory.simple_generate_batch(klass, create, size, FACTORY_CLASS=None,
2340 **kwargs)
2341 Create a factory for klass using declarations passed in kwargs;
2342 return an instance generated from that factory according to the
2343 create flag, or a list of size instances (for
2344 simple_generate_batch()).
2345
2346 Parameters
2347
2348 · klass (class) – Class of the instance to generate
2349
2350 · create (bool) – Whether to build (False) or create
2351 (True) instances
2352
2353 · size (int) – Number of instances to generate
2354
2355 · kwargs – Declarations to use for the generated factory
2356
2357 · FACTORY_CLASS – Alternate base class (instead of
2358 Factory)
2359
2360 Randomness management
2361 Using random in factories allows to “fuzz” a program efficiently. How‐
2362 ever, it’s sometimes required to reproduce a failing test.
2363
2364 factory.fuzzy and factory.Faker share a dedicated instance of ran‐
2365 dom.Random, which can be managed through the factory.random module:
2366
2367 factory.random.get_random_state()
2368 Call get_random_state() to retrieve the random generator’s cur‐
2369 rent state. The returned object is implementation-specific.
2370
2371 factory.random.set_random_state(state)
2372 Use set_random_state() to set a custom state into the random
2373 generator (fetched from get_random_state() in a previous run,
2374 for instance)
2375
2376 factory.random.reseed_random(seed)
2377 The reseed_random() function allows to load a chosen seed into
2378 the random generator. That seed can be anything accepted by
2379 random.seed().
2380
2381 See recipe-random-management for help in using those methods in a test
2382 setup.
2383
2384 Using factory_boy with ORMs
2385 factory_boy provides custom Factory subclasses for various ORMs, adding
2386 dedicated features.
2387
2388 Django
2389 The first versions of factory_boy were designed specifically for
2390 Django, but the library has now evolved to be framework-independent.
2391
2392 Most features should thus feel quite familiar to Django users.
2393
2394 The DjangoModelFactory subclass
2395 All factories for a Django Model should use the DjangoModelFactory base
2396 class.
2397
2398 class factory.django.DjangoModelFactory(factory.Factory)
2399 Dedicated class for Django Model factories.
2400
2401 This class provides the following features:
2402
2403 · The model attribute also supports the 'app.Model' syntax
2404
2405 · create() uses Model.objects.create()
2406
2407 · When using RelatedFactory or PostGeneration attributes, the
2408 base object will be saved once all post-generation hooks have
2409 run.
2410
2411 NOTE:
2412 With Django versions 1.8.0 to 1.8.3, it was no longer possible to
2413 call .build() on a factory if this factory used a SubFactory point‐
2414 ing to another model: Django refused to set a ForeignKey to an
2415 unsaved Model instance.
2416
2417 See https://code.djangoproject.com/ticket/10811 and
2418 https://code.djangoproject.com/ticket/25160 for details.
2419
2420 class factory.django.DjangoOptions(factory.base.FactoryOptions)
2421 The class Meta on a DjangoModelFactory supports extra parame‐
2422 ters:
2423
2424 database
2425 New in version 2.5.0.
2426
2427
2428 All queries to the related model will be routed to the
2429 given database. It defaults to 'default'.
2430
2431 django_get_or_create
2432 New in version 2.4.0.
2433
2434
2435 Fields whose name are passed in this list will be used to
2436 perform a Model.objects.get_or_create() instead of the
2437 usual Model.objects.create():
2438
2439 class UserFactory(factory.django.DjangoModelFactory):
2440 class Meta:
2441 model = 'myapp.User' # Equivalent to ``model = myapp.models.User``
2442 django_get_or_create = ('username',)
2443
2444 username = 'john'
2445
2446 >>> User.objects.all()
2447 []
2448 >>> UserFactory() # Creates a new user
2449 <User: john>
2450 >>> User.objects.all()
2451 [<User: john>]
2452
2453 >>> UserFactory() # Fetches the existing user
2454 <User: john>
2455 >>> User.objects.all() # No new user!
2456 [<User: john>]
2457
2458 >>> UserFactory(username='jack') # Creates another user
2459 <User: jack>
2460 >>> User.objects.all()
2461 [<User: john>, <User: jack>]
2462
2463 Extra fields
2464 class factory.django.FileField
2465 Custom declarations for django.db.models.FileField
2466
2467 __init__(self, from_path='', from_file='', from_func='',
2468 data=b'', filename='example.dat')
2469
2470 Parameters
2471
2472 · from_path (str) – Use data from the file located
2473 at from_path, and keep its filename
2474
2475 · from_file (file) – Use the contents of the pro‐
2476 vided file object; use its filename if avail‐
2477 able, unless filename is also provided.
2478
2479 · from_func (func) – Use function that returns a
2480 file object
2481
2482 · data (bytes) – Use the provided bytes as file
2483 contents
2484
2485 · filename (str) – The filename for the FileField
2486
2487 NOTE:
2488 If the value None was passed for the FileField field, this will dis‐
2489 able field generation:
2490
2491 class MyFactory(factory.django.DjangoModelFactory):
2492 class Meta:
2493 model = models.MyModel
2494
2495 the_file = factory.django.FileField(filename='the_file.dat')
2496
2497 >>> MyFactory(the_file__data=b'uhuh').the_file.read()
2498 b'uhuh'
2499 >>> MyFactory(the_file=None).the_file
2500 None
2501
2502 class factory.django.ImageField
2503 Custom declarations for django.db.models.ImageField
2504
2505 __init__(self, from_path='', from_file='', from_func='', file‐
2506 name='example.jpg', width=100, height=100, color='green', for‐
2507 mat='JPEG')
2508
2509 Parameters
2510
2511 · from_path (str) – Use data from the file located
2512 at from_path, and keep its filename
2513
2514 · from_file (file) – Use the contents of the pro‐
2515 vided file object; use its filename if available
2516
2517 · from_func (func) – Use function that returns a
2518 file object
2519
2520 · filename (str) – The filename for the ImageField
2521
2522 · width (int) – The width of the generated image
2523 (default: 100)
2524
2525 · height (int) – The height of the generated image
2526 (default: 100)
2527
2528 · color (str) – The color of the generated image
2529 (default: 'green')
2530
2531 · format (str) – The image format (as supported by
2532 PIL) (default: 'JPEG')
2533
2534 NOTE:
2535 If the value None was passed for the FileField field, this will dis‐
2536 able field generation:
2537
2538 NOTE:
2539 Just as Django’s django.db.models.ImageField requires the Python
2540 Imaging Library, this ImageField requires it too.
2541
2542 class MyFactory(factory.django.DjangoModelFactory):
2543 class Meta:
2544 model = models.MyModel
2545
2546 the_image = factory.django.ImageField(color='blue')
2547
2548 >>> MyFactory(the_image__width=42).the_image.width
2549 42
2550 >>> MyFactory(the_image=None).the_image
2551 None
2552
2553 Disabling signals
2554 Signals are often used to plug some custom code into external compo‐
2555 nents code; for instance to create Profile objects on-the-fly when a
2556 new User object is saved.
2557
2558 This may interfere with finely tuned factories, which would create both
2559 using RelatedFactory.
2560
2561 To work around this problem, use the mute_signals() decorator/context
2562 manager:
2563
2564 factory.django.mute_signals(signal1, ...)
2565 Disable the list of selected signals when calling the factory,
2566 and reactivate them upon leaving.
2567
2568 # foo/factories.py
2569
2570 import factory
2571
2572 from . import models
2573 from . import signals
2574
2575 @factory.django.mute_signals(signals.pre_save, signals.post_save)
2576 class FooFactory(factory.django.DjangoModelFactory):
2577 class Meta:
2578 model = models.Foo
2579
2580 # ...
2581
2582 def make_chain():
2583 with factory.django.mute_signals(signals.pre_save, signals.post_save):
2584 # pre_save/post_save won't be called here.
2585 return SomeFactory(), SomeOtherFactory()
2586
2587 Mogo
2588 factory_boy supports Mogo-style models, through the MogoFactory class.
2589
2590 Mogo is a wrapper around the pymongo library for MongoDB.
2591
2592 class factory.mogo.MogoFactory(factory.Factory)
2593 Dedicated class for Mogo models.
2594
2595 This class provides the following features:
2596
2597 · build() calls a model’s new() method
2598
2599 · create() builds an instance through new() then saves it.
2600
2601 MongoEngine
2602 factory_boy supports MongoEngine-style models, through the
2603 MongoEngineFactory class.
2604
2605 mongoengine is a wrapper around the pymongo library for MongoDB.
2606
2607 class factory.mongoengine.MongoEngineFactory(factory.Factory)
2608 Dedicated class for MongoEngine models.
2609
2610 This class provides the following features:
2611
2612 · build() calls a model’s __init__ method
2613
2614 · create() builds an instance through __init__ then saves it.
2615
2616 NOTE:
2617 If the associated class <factory.FactoryOptions.model is a
2618 mongoengine.EmbeddedDocument, the create() function won’t
2619 “save” it, since this wouldn’t make sense.
2620
2621 This feature makes it possible to use SubFactory to create
2622 embedded document.
2623
2624 A minimalist example:
2625
2626 import mongoengine
2627
2628 class Address(mongoengine.EmbeddedDocument):
2629 street = mongoengine.StringField()
2630
2631 class Person(mongoengine.Document):
2632 name = mongoengine.StringField()
2633 address = mongoengine.EmbeddedDocumentField(Address)
2634
2635 import factory
2636
2637 class AddressFactory(factory.mongoengine.MongoEngineFactory):
2638 class Meta:
2639 model = Address
2640
2641 street = factory.Sequence(lambda n: 'street%d' % n)
2642
2643 class PersonFactory(factory.mongoengine.MongoEngineFactory):
2644 class Meta:
2645 model = Person
2646
2647 name = factory.Sequence(lambda n: 'name%d' % n)
2648 address = factory.SubFactory(AddressFactory)
2649
2650 SQLAlchemy
2651 Factory_boy also supports SQLAlchemy models through the
2652 SQLAlchemyModelFactory class.
2653
2654 To work, this class needs an SQLAlchemy session object affected to the
2655 Meta.sqlalchemy_session attribute.
2656
2657 class factory.alchemy.SQLAlchemyModelFactory(factory.Factory)
2658 Dedicated class for SQLAlchemy models.
2659
2660 This class provides the following features:
2661
2662 · create() uses sqlalchemy.orm.session.Session.add()
2663
2664 class factory.alchemy.SQLAlchemyOptions(factory.base.FactoryOptions)
2665 In addition to the usual parameters available in class Meta, a
2666 SQLAlchemyModelFactory also supports the following settings:
2667
2668 sqlalchemy_session
2669 SQLAlchemy session to use to communicate with the data‐
2670 base when creating an object through this
2671 SQLAlchemyModelFactory.
2672
2673 sqlalchemy_session_persistence
2674 Control the action taken by sqlalchemy session at the end
2675 of a create call.
2676
2677 Valid values are:
2678
2679 · None: do nothing
2680
2681 · 'flush': perform a session flush()
2682
2683 · 'commit': perform a session commit()
2684
2685 The default value is None.
2686
2687 If force_flush is set to True, it overrides this option.
2688
2689 force_flush
2690 Force a session flush() at the end of _create().
2691
2692 NOTE:
2693 This option is deprecated. Use sqlalchemy_session_per‐
2694 sistence instead.
2695
2696 A (very) simple example:
2697
2698 from sqlalchemy import Column, Integer, Unicode, create_engine
2699 from sqlalchemy.ext.declarative import declarative_base
2700 from sqlalchemy.orm import scoped_session, sessionmaker
2701
2702 engine = create_engine('sqlite://')
2703 session = scoped_session(sessionmaker(bind=engine))
2704 Base = declarative_base()
2705
2706
2707 class User(Base):
2708 """ A SQLAlchemy simple model class who represents a user """
2709 __tablename__ = 'UserTable'
2710
2711 id = Column(Integer(), primary_key=True)
2712 name = Column(Unicode(20))
2713
2714 Base.metadata.create_all(engine)
2715
2716 import factory
2717
2718 class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
2719 class Meta:
2720 model = User
2721 sqlalchemy_session = session # the SQLAlchemy session object
2722
2723 id = factory.Sequence(lambda n: n)
2724 name = factory.Sequence(lambda n: u'User %d' % n)
2725
2726 >>> session.query(User).all()
2727 []
2728 >>> UserFactory()
2729 <User: User 1>
2730 >>> session.query(User).all()
2731 [<User: User 1>]
2732
2733 Managing sessions
2734 Since SQLAlchemy is a general purpose library, there is no “global”
2735 session management system.
2736
2737 The most common pattern when working with unit tests and factory_boy is
2738 to use SQLAlchemy’s sqlalchemy.orm.scoping.scoped_session:
2739
2740 · The test runner configures some project-wide scoped_session
2741
2742 · Each SQLAlchemyModelFactory subclass uses this scoped_session as its
2743 sqlalchemy_session
2744
2745 · The tearDown() method of tests calls Session.remove to reset the ses‐
2746 sion.
2747
2748 NOTE:
2749 See the excellent SQLAlchemy guide on scoped_session for details of
2750 scoped_session’s usage.
2751
2752 The basic idea is that declarative parts of the code (including fac‐
2753 tories) need a simple way to access the “current session”, but that
2754 session will only be created and configured at a later point.
2755
2756 The scoped_session handles this, by virtue of only creating the ses‐
2757 sion when a query is sent to the database.
2758
2759 Here is an example layout:
2760
2761 · A global (test-only?) file holds the scoped_session:
2762
2763 # myprojet/test/common.py
2764
2765 from sqlalchemy import orm
2766 Session = orm.scoped_session(orm.sessionmaker())
2767
2768 · All factory access it:
2769
2770 # myproject/factories.py
2771
2772 import factory
2773
2774 from . import models
2775 from .test import common
2776
2777 class UserFactory(factory.alchemy.SQLAlchemyModelFactory):
2778 class Meta:
2779 model = models.User
2780
2781 # Use the not-so-global scoped_session
2782 # Warning: DO NOT USE common.Session()!
2783 sqlalchemy_session = common.Session
2784
2785 name = factory.Sequence(lambda n: "User %d" % n)
2786
2787 · The test runner configures the scoped_session when it starts:
2788
2789 # myproject/test/runtests.py
2790
2791 import sqlalchemy
2792
2793 from . import common
2794
2795 def runtests():
2796 engine = sqlalchemy.create_engine('sqlite://')
2797
2798 # It's a scoped_session, and now is the time to configure it.
2799 common.Session.configure(bind=engine)
2800
2801 run_the_tests
2802
2803 · test cases use this scoped_session, and clear it after each test (for
2804 isolation):
2805
2806 # myproject/test/test_stuff.py
2807
2808 import unittest
2809
2810 from . import common
2811
2812 class MyTest(unittest.TestCase):
2813
2814 def setUp(self):
2815 # Prepare a new, clean session
2816 self.session = common.Session()
2817
2818 def test_something(self):
2819 u = factories.UserFactory()
2820 self.assertEqual([u], self.session.query(User).all())
2821
2822 def tearDown(self):
2823 # Rollback the session => no changes to the database
2824 self.session.rollback()
2825 # Remove it, so that the next test gets a new Session()
2826 common.Session.remove()
2827
2828 Common recipes
2829 NOTE:
2830 Most recipes below take on Django model examples, but can also be
2831 used on their own.
2832
2833 Dependent objects (ForeignKey)
2834 When one attribute is actually a complex field (e.g a ForeignKey to
2835 another Model), use the SubFactory declaration:
2836
2837 # models.py
2838 class User(models.Model):
2839 first_name = models.CharField()
2840 group = models.ForeignKey(Group)
2841
2842
2843 # factories.py
2844 import factory
2845 from . import models
2846
2847 class UserFactory(factory.django.DjangoModelFactory):
2848 class Meta:
2849 model = models.User
2850
2851 first_name = factory.Sequence(lambda n: "Agent %03d" % n)
2852 group = factory.SubFactory(GroupFactory)
2853
2854 Choosing from a populated table
2855 If the target of the ForeignKey should be chosen from a pre-populated
2856 table (e.g django.contrib.contenttypes.models.ContentType), simply use
2857 a factory.Iterator on the chosen queryset:
2858
2859 import factory, factory.django
2860 from . import models
2861
2862 class UserFactory(factory.django.DjangoModelFactory):
2863 class Meta:
2864 model = models.User
2865
2866 language = factory.Iterator(models.Language.objects.all())
2867
2868 Here, models.Language.objects.all() won’t be evaluated until the first
2869 call to UserFactory; thus avoiding DB queries at import time.
2870
2871 Reverse dependencies (reverse ForeignKey)
2872 When a related object should be created upon object creation (e.g a
2873 reverse ForeignKey from another Model), use a RelatedFactory declara‐
2874 tion:
2875
2876 # models.py
2877 class User(models.Model):
2878 pass
2879
2880 class UserLog(models.Model):
2881 user = models.ForeignKey(User)
2882 action = models.CharField()
2883
2884
2885 # factories.py
2886 class UserFactory(factory.django.DjangoModelFactory):
2887 class Meta:
2888 model = models.User
2889
2890 log = factory.RelatedFactory(UserLogFactory, 'user', action=models.UserLog.ACTION_CREATE)
2891
2892 When a UserFactory is instantiated, factory_boy will call UserLogFac‐
2893 tory(user=that_user, action=...) just before returning the created
2894 User.
2895
2896 Example: Django’s Profile
2897 Django (<1.5) provided a mechanism to attach a Profile to a User
2898 instance, using a OneToOneField from the Profile to the User.
2899
2900 A typical way to create those profiles was to hook a post-save signal
2901 to the User model.
2902
2903 Prior to version 2.9, the solution to this was to override the _gener‐
2904 ate() method on the factory.
2905
2906 Since version 2.9, the mute_signals() decorator should be used:
2907
2908 @factory.django.mute_signals(post_save)
2909 class ProfileFactory(factory.django.DjangoModelFactory):
2910 class Meta:
2911 model = my_models.Profile
2912
2913 title = 'Dr'
2914 # We pass in profile=None to prevent UserFactory from creating another profile
2915 # (this disables the RelatedFactory)
2916 user = factory.SubFactory('app.factories.UserFactory', profile=None)
2917
2918 @factory.django.mute_signals(post_save)
2919 class UserFactory(factory.django.DjangoModelFactory):
2920 class Meta:
2921 model = auth_models.User
2922
2923 username = factory.Sequence(lambda n: "user_%d" % n)
2924
2925 # We pass in 'user' to link the generated Profile to our just-generated User
2926 # This will call ProfileFactory(user=our_new_user), thus skipping the SubFactory.
2927 profile = factory.RelatedFactory(ProfileFactory, 'user')
2928
2929 >>> u = UserFactory(profile__title=u"Lord")
2930 >>> u.get_profile().title
2931 u"Lord"
2932
2933 Such behaviour can be extended to other situations where a signal
2934 interferes with factory_boy related factories.
2935
2936 Any factories that call these classes with SubFactory will also need to
2937 be decorated in the same manner.
2938
2939 NOTE:
2940 When any RelatedFactory or post_generation attribute is defined on
2941 the DjangoModelFactory subclass, a second save() is performed after
2942 the call to _create().
2943
2944 Code working with signals should thus use the mute_signals() decora‐
2945 tor
2946
2947 Simple Many-to-many relationship
2948 Building the adequate link between two models depends heavily on the
2949 use case; factory_boy doesn’t provide a “all in one tools” as for Sub‐
2950 Factory or RelatedFactory, users will have to craft their own depending
2951 on the model.
2952
2953 The base building block for this feature is the post_generation hook:
2954
2955 # models.py
2956 class Group(models.Model):
2957 name = models.CharField()
2958
2959 class User(models.Model):
2960 name = models.CharField()
2961 groups = models.ManyToManyField(Group)
2962
2963
2964 # factories.py
2965 class GroupFactory(factory.django.DjangoModelFactory):
2966 class Meta:
2967 model = models.Group
2968
2969 name = factory.Sequence(lambda n: "Group #%s" % n)
2970
2971 class UserFactory(factory.django.DjangoModelFactory):
2972 class Meta:
2973 model = models.User
2974
2975 name = "John Doe"
2976
2977 @factory.post_generation
2978 def groups(self, create, extracted, **kwargs):
2979 if not create:
2980 # Simple build, do nothing.
2981 return
2982
2983 if extracted:
2984 # A list of groups were passed in, use them
2985 for group in extracted:
2986 self.groups.add(group)
2987
2988 When calling UserFactory() or UserFactory.build(), no group binding
2989 will be created.
2990
2991 But when UserFactory.create(groups=(group1, group2, group3)) is called,
2992 the groups declaration will add passed in groups to the set of groups
2993 for the user.
2994
2995 Many-to-many relation with a ‘through’
2996 If only one link is required, this can be simply performed with a
2997 RelatedFactory. If more links are needed, simply add more RelatedFac‐
2998 tory declarations:
2999
3000 # models.py
3001 class User(models.Model):
3002 name = models.CharField()
3003
3004 class Group(models.Model):
3005 name = models.CharField()
3006 members = models.ManyToManyField(User, through='GroupLevel')
3007
3008 class GroupLevel(models.Model):
3009 user = models.ForeignKey(User)
3010 group = models.ForeignKey(Group)
3011 rank = models.IntegerField()
3012
3013
3014 # factories.py
3015 class UserFactory(factory.django.DjangoModelFactory):
3016 class Meta:
3017 model = models.User
3018
3019 name = "John Doe"
3020
3021 class GroupFactory(factory.django.DjangoModelFactory):
3022 class Meta:
3023 model = models.Group
3024
3025 name = "Admins"
3026
3027 class GroupLevelFactory(factory.django.DjangoModelFactory):
3028 class Meta:
3029 model = models.GroupLevel
3030
3031 user = factory.SubFactory(UserFactory)
3032 group = factory.SubFactory(GroupFactory)
3033 rank = 1
3034
3035 class UserWithGroupFactory(UserFactory):
3036 membership = factory.RelatedFactory(GroupLevelFactory, 'user')
3037
3038 class UserWith2GroupsFactory(UserFactory):
3039 membership1 = factory.RelatedFactory(GroupLevelFactory, 'user', group__name='Group1')
3040 membership2 = factory.RelatedFactory(GroupLevelFactory, 'user', group__name='Group2')
3041
3042 Whenever the UserWithGroupFactory is called, it will, as a post-genera‐
3043 tion hook, call the GroupLevelFactory, passing the generated user as a
3044 user field:
3045
3046 1. UserWithGroupFactory() generates a User instance, obj
3047
3048 2. It calls GroupLevelFactory(user=obj)
3049
3050 3. It returns obj
3051
3052 When using the UserWith2GroupsFactory, that behavior becomes:
3053
3054 1. UserWith2GroupsFactory() generates a User instance, obj
3055
3056 2. It calls GroupLevelFactory(user=obj, group__name='Group1')
3057
3058 3. It calls GroupLevelFactory(user=obj, group__name='Group2')
3059
3060 4. It returns obj
3061
3062 Copying fields to a SubFactory
3063 When a field of a related class should match one of the container:
3064
3065 # models.py
3066 class Country(models.Model):
3067 name = models.CharField()
3068 lang = models.CharField()
3069
3070 class User(models.Model):
3071 name = models.CharField()
3072 lang = models.CharField()
3073 country = models.ForeignKey(Country)
3074
3075 class Company(models.Model):
3076 name = models.CharField()
3077 owner = models.ForeignKey(User)
3078 country = models.ForeignKey(Country)
3079
3080 Here, we want:
3081
3082 · The User to have the lang of its country (factory.SelfAt‐
3083 tribute('country.lang'))
3084
3085 · The Company owner to live in the country of the company (fac‐
3086 tory.SelfAttribute('..country'))
3087
3088 # factories.py
3089 class CountryFactory(factory.django.DjangoModelFactory):
3090 class Meta:
3091 model = models.Country
3092
3093 name = factory.Iterator(["France", "Italy", "Spain"])
3094 lang = factory.Iterator(['fr', 'it', 'es'])
3095
3096 class UserFactory(factory.django.DjangoModelFactory):
3097 class Meta:
3098 model = models.User
3099
3100 name = "John"
3101 lang = factory.SelfAttribute('country.lang')
3102 country = factory.SubFactory(CountryFactory)
3103
3104 class CompanyFactory(factory.django.DjangoModelFactory):
3105 class Meta:
3106 model = models.Company
3107
3108 name = "ACME, Inc."
3109 country = factory.SubFactory(CountryFactory)
3110 owner = factory.SubFactory(UserFactory, country=factory.SelfAttribute('..country'))
3111
3112 If the value of a field on the child factory is indirectly derived from
3113 a field on the parent factory, you will need to use LazyAttribute and
3114 poke the “factory_parent” attribute.
3115
3116 This time, we want the company owner to live in a country neighboring
3117 the country of the company:
3118
3119 class CompanyFactory(factory.django.DjangoModelFactory):
3120 class Meta:
3121 model = models.Company
3122
3123 name = "ACME, Inc."
3124 country = factory.SubFactory(CountryFactory)
3125 owner = factory.SubFactory(UserFactory,
3126 country=factory.LazyAttribute(lambda o: get_random_neighbor(o.factory_parent.country)))
3127
3128 Custom manager methods
3129 Sometimes you need a factory to call a specific manager method other
3130 then the default Model.objects.create() method:
3131
3132 class UserFactory(factory.django.DjangoModelFactory):
3133 class Meta:
3134 model = UserenaSignup
3135
3136 username = "l7d8s"
3137 email = "my_name@example.com"
3138 password = "my_password"
3139
3140 @classmethod
3141 def _create(cls, model_class, *args, **kwargs):
3142 """Override the default ``_create`` with our custom call."""
3143 manager = cls._get_manager(model_class)
3144 # The default would use ``manager.create(*args, **kwargs)``
3145 return manager.create_user(*args, **kwargs)
3146
3147 Forcing the sequence counter
3148 A common pattern with factory_boy is to use a factory.Sequence declara‐
3149 tion to provide varying values to attributes declared as unique.
3150
3151 However, it is sometimes useful to force a given value to the counter,
3152 for instance to ensure that tests are properly reproductible.
3153
3154 factory_boy provides a few hooks for this:
3155
3156 Forcing the value on a per-call basis
3157 In order to force the counter for a specific Factory instantia‐
3158 tion, just pass the value in the __sequence=42 parameter:
3159
3160 class AccountFactory(factory.Factory):
3161 class Meta:
3162 model = Account
3163 uid = factory.Sequence(lambda n: n)
3164 name = "Test"
3165
3166 >>> obj1 = AccountFactory(name="John Doe", __sequence=10)
3167 >>> obj1.uid # Taken from the __sequence counter
3168 10
3169 >>> obj2 = AccountFactory(name="Jane Doe")
3170 >>> obj2.uid # The base sequence counter hasn't changed
3171 1
3172
3173 Resetting the counter globally
3174 If all calls for a factory must start from a deterministic num‐
3175 ber, use factory.Factory.reset_sequence(); this will reset the
3176 counter to its initial value (as defined by factory.Fac‐
3177 tory._setup_next_sequence()).
3178
3179 >>> AccountFactory().uid
3180 1
3181 >>> AccountFactory().uid
3182 2
3183 >>> AccountFactory.reset_sequence()
3184 >>> AccountFactory().uid # Reset to the initial value
3185 1
3186 >>> AccountFactory().uid
3187 2
3188
3189 It is also possible to reset the counter to a specific value:
3190
3191 >>> AccountFactory.reset_sequence(10)
3192 >>> AccountFactory().uid
3193 10
3194 >>> AccountFactory().uid
3195 11
3196
3197 This recipe is most useful in a TestCase’s setUp() method.
3198
3199 Forcing the initial value for all projects
3200 The sequence counter of a Factory can also be set automatically
3201 upon the first call through the _setup_next_sequence() method;
3202 this helps when the objects’s attributes mustn’t conflict with
3203 pre-existing data.
3204
3205 A typical example is to ensure that running a Python script
3206 twice will create non-conflicting objects, by setting up the
3207 counter to “max used value plus one”:
3208
3209 class AccountFactory(factory.django.DjangoModelFactory):
3210 class Meta:
3211 model = models.Account
3212
3213 @classmethod
3214 def _setup_next_sequence(cls):
3215 try:
3216 return models.Accounts.objects.latest('uid').uid + 1
3217 except models.Account.DoesNotExist:
3218 return 1
3219
3220 >>> Account.objects.create(uid=42, name="Blah")
3221 >>> AccountFactory.create() # Sets up the account number based on the latest uid
3222 <Account uid=43, name=Test>
3223
3224 Using reproducible randomness
3225 Although using random values is great, it can provoke test flakyness.
3226 factory_boy provides a few helpers for this.
3227
3228 NOTE:
3229 Those methods will seed the random engine used in both factory.Faker
3230 and factory.fuzzy objects.
3231
3232 Seeding the random engine
3233 The simplest way to manage randomness is to push a selected seed
3234 when starting tests:
3235
3236 import factory.random
3237 # Pass in any value
3238 factory.random.reseed_random('my awesome project')
3239
3240 Reproducing unseeded tests
3241 A project might choose not to use an explicit random seed (for
3242 better fuzzing), but still wishes to have reproducible tests.
3243
3244 For such cases, use a combination of factory.random.get_ran‐
3245 dom_state() and factory.random.set_random_state().
3246
3247 Since the random state structure is implementation-specific, we
3248 recommand passing it around as a base64-encoded pickle dump.
3249
3250 class MyTestRunner:
3251
3252 def setup_test_environment(self):
3253 state = os.environ.get('TEST_RANDOM_STATE')
3254 if state:
3255 try:
3256 decoded_state = pickle.loads(base64.b64decode(state.encode('ascii')))
3257 except ValueError:
3258 decoded_state = None
3259 if decoded_state:
3260 factory.random.set_random_state(decoded_state)
3261 else:
3262 encoded_state = base64.b64encode(pickle.dumps(factory.random.get_random_state()))
3263 print("Current random state: %s" % encoded_state.decode('ascii'))
3264 super().setup_test_environment()
3265
3266 Converting a factory’s output to a dict
3267 In order to inject some data to, say, a REST API, it can be useful to
3268 fetch the factory’s data as a dict.
3269
3270 Internally, a factory will:
3271
3272 1. Merge declarations and overrides from all sources (class definition,
3273 call parameters, …)
3274
3275 2. Resolve them into a dict
3276
3277 3. Pass that dict as keyword arguments to the model’s build / create
3278 function
3279
3280 In order to get a dict, we’ll just have to swap the model; the easiest
3281 way is to use factory.build():
3282
3283 class UserFactory(factory.django.DjangoModelFactory):
3284 class Meta:
3285 model = models.User
3286
3287 first_name = factory.Sequence(lambda n: "Agent %03d" % n)
3288 username = factory.Faker('user_name')
3289
3290 >>> factory.build(dict, FACTORY_CLASS=UserFactory)
3291 {'first_name': "Agent 001", 'username': 'john_doe'}
3292
3293 Fuzzying Django model field choices
3294 When defining a FuzzyChoice you can reuse the same choice list from the
3295 model field descriptor.
3296
3297 Use the getter kwarg to select the first element from each choice
3298 tuple.
3299
3300 class UserFactory(factory.Factory):
3301 class Meta:
3302 model = User
3303
3304 # CATEGORY_CHOICES is a list of (key, title) tuples
3305 category = factory.fuzzy.FuzzyChoice(User.CATEGORY_CHOICES, getter=lambda c: c[0])
3306
3307 Django models with GenericForeignKeys
3308 For model which uses GenericForeignKey
3309
3310 from __future__ import unicode_literals
3311
3312 from django.db import models
3313 from django.contrib.contenttypes.models import ContentType
3314 from django.contrib.contenttypes.fields import GenericForeignKey
3315
3316
3317 class TaggedItem(models.Model):
3318 """Example GenericForeignKey model from django docs"""
3319 tag = models.SlugField()
3320 content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
3321 object_id = models.PositiveIntegerField()
3322 content_object = GenericForeignKey('content_type', 'object_id')
3323
3324 def __str__(self): # __unicode__ on Python 2
3325 return self.tag
3326
3327
3328 We can create factories like this:
3329
3330 import factory
3331 from django.contrib.auth.models import User, Group
3332 from django.contrib.contenttypes.models import ContentType
3333
3334 from .models import TaggedItem
3335
3336
3337 class UserFactory(factory.django.DjangoModelFactory):
3338 first_name = 'Adam'
3339
3340 class Meta:
3341 model = User
3342
3343
3344 class GroupFactory(factory.django.DjangoModelFactory):
3345 name = 'group'
3346
3347 class Meta:
3348 model = Group
3349
3350
3351 class TaggedItemFactory(factory.django.DjangoModelFactory):
3352 object_id = factory.SelfAttribute('content_object.id')
3353 content_type = factory.LazyAttribute(
3354 lambda o: ContentType.objects.get_for_model(o.content_object))
3355
3356 class Meta:
3357 exclude = ['content_object']
3358 abstract = True
3359
3360
3361 class TaggedUserFactory(TaggedItemFactory):
3362 content_object = factory.SubFactory(UserFactory)
3363
3364 class Meta:
3365 model = TaggedItem
3366
3367
3368 class TaggedGroupFactory(TaggedItemFactory):
3369 content_object = factory.SubFactory(GroupFactory)
3370
3371 class Meta:
3372 model = TaggedItem
3373
3374
3375 Fuzzy attributes
3376 NOTE:
3377 Now that FactoryBoy includes the factory.Faker class, most of these
3378 built-in fuzzers are deprecated in favor of their Faker equivalents.
3379 Further discussion here:
3380 https://github.com/FactoryBoy/factory_boy/issues/271/
3381
3382 Some tests may be interested in testing with fuzzy, random values.
3383
3384 This is handled by the factory.fuzzy module, which provides a few ran‐
3385 dom declarations.
3386
3387 NOTE:
3388 Use import factory.fuzzy to load this module.
3389
3390 FuzzyAttribute
3391 class factory.fuzzy.FuzzyAttribute
3392 The FuzzyAttribute uses an arbitrary callable as fuzzer. It is
3393 expected that successive calls of that function return various
3394 values.
3395
3396 fuzzer The callable that generates random values
3397
3398 FuzzyText
3399 class factory.fuzzy.FuzzyText(length=12, chars=string.ascii_letters,
3400 prefix='')
3401 The FuzzyText fuzzer yields random strings beginning with the
3402 given prefix, followed by length charactes chosen from the chars
3403 character set, and ending with the given suffix.
3404
3405 length int, the length of the random part
3406
3407 prefix text, an optional prefix to prepend to the random part
3408
3409 suffix text, an optional suffix to append to the random part
3410
3411 chars
3412
3413 char iterable, the chars to choose from; defaults to the
3414 list of ascii
3415 letters and numbers.
3416
3417 FuzzyChoice
3418 class factory.fuzzy.FuzzyChoice(choices)
3419 The FuzzyChoice fuzzer yields random choices from the given
3420 iterable.
3421
3422 NOTE:
3423 The passed in choices will be converted into a list upon
3424 first use, not at declaration time.
3425
3426 This allows passing in, for instance, a Django queryset that
3427 will only hit the database during the database, not at import
3428 time.
3429
3430 WARNING:
3431 When using Python2 and list comprehension, use private vari‐
3432 able names as in:
3433
3434 [_x.name for _x in items]
3435
3436 instead of:
3437
3438 [x.name for x in items]
3439
3440 choices
3441 The list of choices to select randomly
3442
3443 FuzzyInteger
3444 class factory.fuzzy.FuzzyInteger(low[, high[, step]])
3445 The FuzzyInteger fuzzer generates random integers within a given
3446 inclusive range.
3447
3448 The low bound may be omitted, in which case it defaults to 0:
3449
3450 >>> fi = FuzzyInteger(0, 42)
3451 >>> fi.low, fi.high
3452 0, 42
3453
3454 >>> fi = FuzzyInteger(42)
3455 >>> fi.low, fi.high
3456 0, 42
3457
3458 low int, the inclusive lower bound of generated integers
3459
3460 high int, the inclusive higher bound of generated integers
3461
3462 step int, the step between values in the range; for instance,
3463 a FuzzyInteger(0, 42, step=3) might only yield values
3464 from [0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39,
3465 42].
3466
3467 FuzzyDecimal
3468 class factory.fuzzy.FuzzyDecimal(low[, high[, precision=2]])
3469 The FuzzyDecimal fuzzer generates random decimals within a given
3470 inclusive range.
3471
3472 The low bound may be omitted, in which case it defaults to 0:
3473
3474 >>> FuzzyDecimal(0.5, 42.7)
3475 >>> fi.low, fi.high
3476 0.5, 42.7
3477
3478 >>> fi = FuzzyDecimal(42.7)
3479 >>> fi.low, fi.high
3480 0.0, 42.7
3481
3482 >>> fi = FuzzyDecimal(0.5, 42.7, 3)
3483 >>> fi.low, fi.high, fi.precision
3484 0.5, 42.7, 3
3485
3486 low decimal, the inclusive lower bound of generated decimals
3487
3488 high decimal, the inclusive higher bound of generated decimals
3489
3490 precision
3491
3492 int, the number of digits to generate after the dot. The default
3493 is 2 digits.
3494
3495 FuzzyFloat
3496 class factory.fuzzy.FuzzyFloat(low[, high])
3497 The FuzzyFloat fuzzer provides random float objects within a
3498 given inclusive range.
3499
3500 >>> FuzzyFloat(0.5, 42.7)
3501 >>> fi.low, fi.high
3502 0.5, 42.7
3503
3504 >>> fi = FuzzyFloat(42.7)
3505 >>> fi.low, fi.high
3506 0.0, 42.7
3507
3508 low decimal, the inclusive lower bound of generated floats
3509
3510 high decimal, the inclusive higher bound of generated floats
3511
3512 FuzzyDate
3513 class factory.fuzzy.FuzzyDate(start_date[, end_date])
3514 The FuzzyDate fuzzer generates random dates within a given
3515 inclusive range.
3516
3517 The end_date bound may be omitted, in which case it defaults to
3518 the current date:
3519
3520 >>> fd = FuzzyDate(datetime.date(2008, 1, 1))
3521 >>> fd.start_date, fd.end_date
3522 datetime.date(2008, 1, 1), datetime.date(2013, 4, 16)
3523
3524 start_date
3525 datetime.date, the inclusive lower bound of generated
3526 dates
3527
3528 end_date
3529 datetime.date, the inclusive higher bound of generated
3530 dates
3531
3532 FuzzyDateTime
3533 class factory.fuzzy.FuzzyDateTime(start_dt[, end_dt], force_year=None,
3534 force_month=None, force_day=None, force_hour=None, force_minute=None,
3535 force_second=None, force_microsecond=None)
3536 The FuzzyDateTime fuzzer generates random timezone-aware date‐
3537 time within a given inclusive range.
3538
3539 The end_dt bound may be omitted, in which case it defaults to
3540 datetime.datetime.now() localized into the UTC timezone.
3541
3542 >>> fdt = FuzzyDateTime(datetime.datetime(2008, 1, 1, tzinfo=UTC))
3543 >>> fdt.start_dt, fdt.end_dt
3544 datetime.datetime(2008, 1, 1, tzinfo=UTC), datetime.datetime(2013, 4, 21, 19, 13, 32, 458487, tzinfo=UTC)
3545
3546 The force_XXX keyword arguments force the related value of gen‐
3547 erated datetimes:
3548
3549 >>> fdt = FuzzyDateTime(datetime.datetime(2008, 1, 1, tzinfo=UTC), datetime.datetime(2009, 1, 1, tzinfo=UTC),
3550 ... force_day=3, force_second=42)
3551 >>> fdt.evaluate(2, None, False) # Actual code used by ``SomeFactory.build()``
3552 datetime.datetime(2008, 5, 3, 12, 13, 42, 124848, tzinfo=UTC)
3553
3554 start_dt
3555 datetime.datetime, the inclusive lower bound of generated
3556 datetimes
3557
3558 end_dt datetime.datetime, the inclusive upper bound of generated
3559 datetimes
3560
3561 force_year
3562 int or None; if set, forces the year of generated date‐
3563 time.
3564
3565 force_month
3566 int or None; if set, forces the month of generated date‐
3567 time.
3568
3569 force_day
3570 int or None; if set, forces the day of generated date‐
3571 time.
3572
3573 force_hour
3574 int or None; if set, forces the hour of generated date‐
3575 time.
3576
3577 force_minute
3578 int or None; if set, forces the minute of generated date‐
3579 time.
3580
3581 force_second
3582 int or None; if set, forces the second of generated date‐
3583 time.
3584
3585 force_microsecond
3586 int or None; if set, forces the microsecond of generated
3587 datetime.
3588
3589 FuzzyNaiveDateTime
3590 class factory.fuzzy.FuzzyNaiveDateTime(start_dt[, end_dt],
3591 force_year=None, force_month=None, force_day=None, force_hour=None,
3592 force_minute=None, force_second=None, force_microsecond=None)
3593 The FuzzyNaiveDateTime fuzzer generates random naive datetime
3594 within a given inclusive range.
3595
3596 The end_dt bound may be omitted, in which case it defaults to
3597 datetime.datetime.now():
3598
3599 >>> fdt = FuzzyNaiveDateTime(datetime.datetime(2008, 1, 1))
3600 >>> fdt.start_dt, fdt.end_dt
3601 datetime.datetime(2008, 1, 1), datetime.datetime(2013, 4, 21, 19, 13, 32, 458487)
3602
3603 The force_XXX keyword arguments force the related value of gen‐
3604 erated datetimes:
3605
3606 >>> fdt = FuzzyNaiveDateTime(datetime.datetime(2008, 1, 1), datetime.datetime(2009, 1, 1),
3607 ... force_day=3, force_second=42)
3608 >>> fdt.evaluate(2, None, False) # Actual code used by ``SomeFactory.build()``
3609 datetime.datetime(2008, 5, 3, 12, 13, 42, 124848)
3610
3611 start_dt
3612 datetime.datetime, the inclusive lower bound of generated
3613 datetimes
3614
3615 end_dt datetime.datetime, the inclusive upper bound of generated
3616 datetimes
3617
3618 force_year
3619 int or None; if set, forces the year of generated date‐
3620 time.
3621
3622 force_month
3623 int or None; if set, forces the month of generated date‐
3624 time.
3625
3626 force_day
3627 int or None; if set, forces the day of generated date‐
3628 time.
3629
3630 force_hour
3631 int or None; if set, forces the hour of generated date‐
3632 time.
3633
3634 force_minute
3635 int or None; if set, forces the minute of generated date‐
3636 time.
3637
3638 force_second
3639 int or None; if set, forces the second of generated date‐
3640 time.
3641
3642 force_microsecond
3643 int or None; if set, forces the microsecond of generated
3644 datetime.
3645
3646 Custom fuzzy fields
3647 Alternate fuzzy fields may be defined. They should inherit from the
3648 BaseFuzzyAttribute class, and override its fuzz() method.
3649
3650 class factory.fuzzy.BaseFuzzyAttribute
3651 Base class for all fuzzy attributes.
3652
3653 fuzz(self)
3654 The method responsible for generating random values.
3655 Must be overridden in subclasses.
3656
3657 WARNING:
3658 Custom BaseFuzzyAttribute subclasses MUST use factory.ran‐
3659 dom.randgen as a randomness source; this ensures that data
3660 they generate can be regenerated using the simple state from
3661 get_random_state().
3662
3663 Examples
3664 Here are some real-world examples of using FactoryBoy.
3665
3666 Objects
3667 First, let’s define a couple of objects:
3668
3669 class Account(object):
3670 def __init__(self, username, email, date_joined):
3671 self.username = username
3672 self.email = email
3673 self.date_joined = date_joined
3674
3675 def __str__(self):
3676 return '%s (%s)' % (self.username, self.email)
3677
3678
3679 class Profile(object):
3680
3681 GENDER_MALE = 'm'
3682 GENDER_FEMALE = 'f'
3683 GENDER_UNKNOWN = 'u' # If the user refused to give it
3684
3685 def __init__(self, account, gender, firstname, lastname, planet='Earth'):
3686 self.account = account
3687 self.gender = gender
3688 self.firstname = firstname
3689 self.lastname = lastname
3690 self.planet = planet
3691
3692 def __unicode__(self):
3693 return u'%s %s (%s)' % (
3694 unicode(self.firstname),
3695 unicode(self.lastname),
3696 unicode(self.account.username),
3697 )
3698
3699 Factories
3700 And now, we’ll define the related factories:
3701
3702 import datetime
3703 import factory
3704 import random
3705
3706 from . import objects
3707
3708
3709 class AccountFactory(factory.Factory):
3710 class Meta:
3711 model = objects.Account
3712
3713 username = factory.Sequence(lambda n: 'john%s' % n)
3714 email = factory.LazyAttribute(lambda o: '%s@example.org' % o.username)
3715 date_joined = factory.LazyFunction(datetime.datetime.now)
3716
3717
3718 class ProfileFactory(factory.Factory):
3719 class Meta:
3720 model = objects.Profile
3721
3722 account = factory.SubFactory(AccountFactory)
3723 gender = factory.Iterator([objects.Profile.GENDER_MALE, objects.Profile.GENDER_FEMALE])
3724 firstname = u'John'
3725 lastname = u'Doe'
3726
3727 We have now defined basic factories for our Account and Profile
3728 classes.
3729
3730 If we commonly use a specific variant of our objects, we can refine a
3731 factory accordingly:
3732
3733 class FemaleProfileFactory(ProfileFactory):
3734 gender = objects.Profile.GENDER_FEMALE
3735 firstname = u'Jane'
3736 user__username = factory.Sequence(lambda n: 'jane%s' % n)
3737
3738 Using the factories
3739 We can now use our factories, for tests:
3740
3741 import unittest
3742
3743 from . import business_logic
3744 from . import factories
3745 from . import objects
3746
3747
3748 class MyTestCase(unittest.TestCase):
3749
3750 def test_send_mail(self):
3751 account = factories.AccountFactory()
3752 email = business_logic.prepare_email(account, subject='Foo', text='Bar')
3753
3754 self.assertEqual(email.to, account.email)
3755
3756 def test_get_profile_stats(self):
3757 profiles = []
3758
3759 profiles.extend(factories.ProfileFactory.create_batch(4))
3760 profiles.extend(factories.FemaleProfileFactory.create_batch(2))
3761 profiles.extend(factories.ProfileFactory.create_batch(2, planet="Tatooine"))
3762
3763 stats = business_logic.profile_stats(profiles)
3764 self.assertEqual({'Earth': 6, 'Mars': 2}, stats.planets)
3765 self.assertLess(stats.genders[objects.Profile.GENDER_FEMALE], 2)
3766
3767 Or for fixtures:
3768
3769 from . import factories
3770
3771 def make_objects():
3772 factories.ProfileFactory.create_batch(size=50)
3773
3774 # Let's create a few, known objects.
3775 factories.ProfileFactory(
3776 gender=objects.Profile.GENDER_MALE,
3777 firstname='Luke',
3778 lastname='Skywalker',
3779 planet='Tatooine',
3780 )
3781
3782 factories.ProfileFactory(
3783 gender=objects.Profile.GENDER_FEMALE,
3784 firstname='Leia',
3785 lastname='Organa',
3786 planet='Alderaan',
3787 )
3788
3789 Internals
3790 Behind the scenes: steps performed when parsing a factory declaration,
3791 and when calling it.
3792
3793 This section will be based on the following factory declaration:
3794
3795 class UserFactory(factory.Factory):
3796 class Meta:
3797 model = User
3798
3799 class Params:
3800 # Allow us to quickly enable staff/superuser flags
3801 superuser = factory.Trait(
3802 is_superuser=True,
3803 is_staff=True,
3804 )
3805 # Meta parameter handling all 'enabled'-related fields
3806 enabled = True
3807
3808 # Classic fields
3809 username = factory.Faker('user_name')
3810 full_name = factory.Faker('name')
3811 creation_date = factory.fuzzy.FuzzyDateTime(
3812 datetime.datetime(2000, 1, 1, tzinfo=UTC),
3813 datetime.datetime(2015, 12, 31, 20, tzinfo=UTC)
3814 )
3815
3816 # Conditional flags
3817 is_active = factory.SelfAttribute('enabled')
3818 deactivation_date = factory.Maybe(
3819 'enabled',
3820 None,
3821 factory.fuzzy.FuzzyDateTime(
3822 datetime.datetime.now().replace(tzinfo=UTC) - datetime.timedelta(days=10),
3823 datetime.datetime.now().replace(tzinfo=UTC) - datetime.timedelta(days=1),
3824 ),
3825 )
3826
3827 # Related logs
3828 creation_log = factory.RelatedFactory(
3829 UserLogFactory, 'user',
3830 action='create', timestamp=factory.SelfAttribute('user.creation_date'),
3831 )
3832
3833
3834 Parsing, Step 1: Metaclass and type declaration
3835 1. Python parses the declaration and calls (thanks to the metaclass
3836 declaration):
3837
3838 factory.base.BaseFactory.__new__(
3839 'UserFactory',
3840 (factory.Factory,),
3841 attributes,
3842 )
3843
3844 2. That metaclass removes Meta and Params from the class attributes,
3845 then generate the actual factory class (according to standard Python
3846 rules)
3847
3848 3. It initializes a FactoryOptions object, and links it to the class
3849
3850 Parsing, Step 2: adapting the class definition
3851 1. The FactoryOptions reads the options from the class Meta declaration
3852
3853 2. It finds a few specific pointer (loading the model class, finding
3854 the reference factory for the sequence counter, etc.)
3855
3856 3. It copies declarations and parameters from parent classes
3857
3858 4. It scans current class attributes (from vars()) to detect pre/post
3859 declarations
3860
3861 5. Declarations are split among pre-declarations and post-declarations
3862 (a raw value shadowing a post-declaration is seen as a post-declara‐
3863 tion)
3864
3865 NOTE:
3866 A declaration for foo__bar will be converted into parameter bar for
3867 declaration foo.
3868
3869 Instantiating, Step 1: Converging entrypoints
3870 First, decide the strategy:
3871
3872 · If the entrypoint is specific to a strategy (build(), create_batch(),
3873 …), use it
3874
3875 · If it is generic (generate(), Factory.__call__()), use the strategy
3876 defined at the class Meta level
3877
3878 Then, we’ll pass the strategy and passed-in overrides to the _gener‐
3879 ate() method.
3880
3881 NOTE:
3882 According to the project roadmap, a future version will use a _gen‐
3883 erate_batch`() at its core instead.
3884
3885 A factory’s _generate() function actually delegates to a StepBuilder()
3886 object. This object will carry the overall “build an object” context
3887 (strategy, depth, and possibly other).
3888
3889 Instantiating, Step 2: Preparing values
3890 1. The StepBuilder merges overrides with the class-level declarations
3891
3892 2. The sequence counter for this instance is initialized
3893
3894 3. A Resolver is set up with all those declarations, and parses them in
3895 order; it will call each value’s evaluate() method, including extra
3896 parameters.
3897
3898 4. If needed, the Resolver might recurse (through the StepBuilder, e.g
3899 when encountering a SubFactory.
3900
3901 Instantiating, Step 3: Building the object
3902 1. The StepBuilder fetches the attributes computed by the Resolver.
3903
3904 2. It applies renaming/adjustment rules
3905
3906 3. It passes them to the FactoryOptions.instantiate() method, which
3907 forwards to the proper methods.
3908
3909 4. Post-declaration are applied (in declaration order)
3910
3911 NOTE:
3912 This document discusses implementation details; there is no guaran‐
3913 tee that the described methods names and signatures will be kept as
3914 is.
3915
3916 ChangeLog
3917 2.12.0 (2019-05-11)
3918 New:
3919
3920 · Add support for Python 3.7
3921
3922 · Add support for Django 2.1
3923
3924 · Add getter to FuzzyChoice that mimics the behavior of getter in
3925 Iterator
3926
3927 · Make the extra_kwargs parameter of generate() optional
3928
3929 · Add RelatedFactoryList class for one-to-many support, thanks Sean
3930 Harrington.
3931
3932 · Make the locale argument for Faker keyword-only
3933
3934 Bugfix:
3935
3936 · Allow renamed arguments to be optional, thanks to Justin Crown.
3937
3938 · Fix django_get_or_create behavior when using multiple fields with
3939 unique=True, thanks to @YPCrumble <https://github.com/YPCrumble>
3940
3941 2.11.1 (2018-05-05)
3942 Bugfix:
3943
3944 · Fix passing deep context to a SubFactory (Foo(x__y__z=fac‐
3945 tory.Faker('name'))
3946
3947 2.11.0 (2018-05-05)
3948 Bugfix:
3949
3950 · Fix FuzzyFloat to return a 15 decimal digits precision float by
3951 default
3952
3953 · issue #451: Restore FileField to a ParameteredAttribute, relying
3954 on composition to parse the provided parameters.
3955
3956 · issue #389: Fix random state management with faker.
3957
3958 · issue #466: Restore mixing Trait and post_generation().
3959
3960 2.10.0 (2018-01-28)
3961 Bugfix:
3962
3963 · issue #443: Don’t crash when calling factory.Iterator.reset() on a
3964 brand new iterator.
3965
3966 New:
3967
3968 · issue #397: Allow a factory.Maybe to contain a PostGenerationDec‐
3969 laration. This also applies to factory.Trait, since they use a
3970 factory.Maybe declaration internally.
3971
3972 2.9.2 (2017-08-03)
3973 Bugfix:
3974
3975 · Fix declaration corruption bug when a factory defined
3976 foo__bar__baz=1 and a caller provided a foo__bar=x parameter at
3977 call time: this got merged into the factory’s base declarations.
3978
3979 2.9.1 (2017-08-02)
3980 Bugfix:
3981
3982 · Fix packaging issues (see
3983 https://github.com/zestsoftware/zest.releaser/issues/212)
3984
3985 · Don’t crash when debugging PostGenerationDeclaration
3986
3987 2.9.0 (2017-07-30)
3988 This version brings massive changes to the core engine, thus reducing
3989 the number of corner cases and weird behaviourrs.
3990
3991 New:
3992
3993 · issue #275: factory.fuzzy and factory.faker now use the same ran‐
3994 dom seed.
3995
3996 · Add factory.Maybe, which chooses among two possible declarations
3997 based on another field’s value (powers the Trait feature).
3998
3999 · PostGenerationMethodCall only allows to pass one positional argu‐
4000 ment; use keyword arguments for extra parameters.
4001
4002 Deprecation:
4003
4004 · factory.fuzzy.get_random_state is deprecated, factory.ran‐
4005 dom.get_random_state should be used instead.
4006
4007 · factory.fuzzy.set_random_state is deprecated, factory.ran‐
4008 dom.set_random_state should be used instead.
4009
4010 · factory.fuzzy.reseed_random is deprecated, factory.ran‐
4011 dom.reseed_random should be used instead.
4012
4013 2.8.1 (2016-12-17)
4014 Bugfix:
4015
4016 · Fix packaging issues.
4017
4018 2.8.0 (2016-12-17)
4019 New:
4020
4021 · issue #240: Call post-generation declarations in the order they
4022 were declared, thanks to Oleg Pidsadnyi.
4023
4024 · issue #309: Provide new options for SQLAlchemy session persistence
4025
4026 Bugfix:
4027
4028 · issue #334: Adjust for the package change in faker
4029
4030 2.7.0 (2016-04-19)
4031 New:
4032
4033 · pull request #267: Add factory.LazyFunction to remove unneeded
4034 lambda parameters, thanks to Hervé Cauwelier.
4035
4036 · issue #251: Add parameterized factories and traits
4037
4038 · pull request #256, pull request #292: Improve error messages in
4039 corner cases
4040
4041 Removed:
4042
4043 · pull request #278: Formally drop support for Python2.6
4044
4045 WARNING:
4046 Version 2.7.0 moves all error classes to factory.errors. This breaks
4047 existing import statements for any error classes except those
4048 importing FactoryError directly from the factory module.
4049
4050 2.6.1 (2016-02-10)
4051 New:
4052
4053 · pull request #262: Allow optional forced flush on SQLAlchemy,
4054 courtesy of Minjung.
4055
4056 2.6.0 (2015-10-20)
4057 New:
4058
4059 · Add factory.FactoryOptions.rename to help handle conflicting names
4060 (issue #206)
4061
4062 · Add support for random-yet-realistic values through fake-factory,
4063 through the factory.Faker class.
4064
4065 · factory.Iterator no longer begins iteration of its argument at
4066 import time, thus allowing to pass in a lazy iterator such as a
4067 Django queryset (i.e factory.Iterator(mod‐
4068 els.MyThingy.objects.all())).
4069
4070 · Simplify imports for ORM layers, now available through a simple
4071 factory import, at factory.alchemy.SQLAlchemyModelFactory / fac‐
4072 tory.django.DjangoModelFactory / factory.mongoengine.MongoEngine‐
4073 Factory.
4074
4075 Bugfix:
4076
4077 · issue #201: Properly handle custom Django managers when dealing
4078 with abstract Django models.
4079
4080 · issue #212: Fix factory.django.mute_signals() to handle Django’s
4081 signal caching
4082
4083 · issue #228: Don’t load django.apps.apps.get_model() until required
4084
4085 · pull request #219: Stop using mogo.model.Model.new(), deprecated 4
4086 years ago.
4087
4088 2.5.2 (2015-04-21)
4089 Bugfix:
4090
4091 · Add support for Django 1.7/1.8
4092
4093 · Add support for mongoengine>=0.9.0 / pymongo>=2.1
4094
4095 2.5.1 (2015-03-27)
4096 Bugfix:
4097
4098 · Respect custom managers in DjangoModelFactory (see issue #192)
4099
4100 · Allow passing declarations (e.g Sequence) as parameters to File‐
4101 Field and ImageField.
4102
4103 2.5.0 (2015-03-26)
4104 New:
4105
4106 · Add support for getting/setting factory.fuzzy’s random state (see
4107 issue #175, issue #185).
4108
4109 · Support lazy evaluation of iterables in factory.fuzzy.FuzzyChoice
4110 (see issue #184).
4111
4112 · Support non-default databases at the factory level (see issue
4113 #171)
4114
4115 · Make factory.django.FileField and factory.django.ImageField
4116 non-post_generation, i.e normal fields also available in save()
4117 (see issue #141).
4118
4119 Bugfix:
4120
4121 · Avoid issues when using factory.django.mute_signals() on a base
4122 factory class (see issue #183).
4123
4124 · Fix limitations of factory.StubFactory, that can now use fac‐
4125 tory.SubFactory and co (see issue #131).
4126
4127 Deprecation:
4128
4129 · Remove deprecated features from 2.4.0 (2014-06-21)
4130
4131 · Remove the auto-magical sequence setup (based on the latest pri‐
4132 mary key value in the database) for Django and SQLAlchemy; this
4133 relates to issues issue #170, issue #153, issue #111, issue #103,
4134 issue #92, issue #78. See
4135 https://github.com/FactoryBoy/factory_boy/commit/13d310f for tech‐
4136 nical details.
4137
4138 WARNING:
4139 Version 2.5.0 removes the ‘auto-magical sequence setup’ bug-and-fea‐
4140 ture. This could trigger some bugs when tests expected a non-zero
4141 sequence reference.
4142
4143 Upgrading
4144 WARNING:
4145 Version 2.5.0 removes features that were marked as deprecated in
4146 v2.4.0.
4147
4148 All FACTORY_*-style attributes are now declared in a class Meta: sec‐
4149 tion:
4150
4151 # Old-style, deprecated
4152 class MyFactory(factory.Factory):
4153 FACTORY_FOR = models.MyModel
4154 FACTORY_HIDDEN_ARGS = ['a', 'b', 'c']
4155
4156 # New-style
4157 class MyFactory(factory.Factory):
4158 class Meta:
4159 model = models.MyModel
4160 exclude = ['a', 'b', 'c']
4161
4162 A simple shell command to upgrade the code would be:
4163
4164 # sed -i: inplace update
4165 # grep -l: only file names, not matching lines
4166 sed -i 's/FACTORY_FOR =/class Meta:\n model =/' $(grep -l FACTORY_FOR $(find . -name '*.py'))
4167
4168 This takes care of all FACTORY_FOR occurrences; the files containing
4169 other attributes to rename can be found with grep -R FACTORY .
4170
4171 2.4.1 (2014-06-23)
4172 Bugfix:
4173
4174 · Fix overriding deeply inherited attributes (set in one factory,
4175 overridden in a subclass, used in a sub-sub-class).
4176
4177 2.4.0 (2014-06-21)
4178 New:
4179
4180 · Add support for factory.fuzzy.FuzzyInteger.step, thanks to
4181 ilya-pirogov (pull request #120)
4182
4183 · Add mute_signals() decorator to temporarily disable some signals,
4184 thanks to ilya-pirogov (pull request #122)
4185
4186 · Add FuzzyFloat (issue #124)
4187
4188 · Declare target model and other non-declaration fields in a class
4189 Meta section.
4190
4191 Deprecation:
4192
4193 · Use of FACTORY_FOR and other FACTORY class-level attributes is
4194 deprecated and will be removed in 2.5. Those attributes should
4195 now declared within the class Meta attribute:
4196
4197 For factory.Factory:
4198
4199 · Rename FACTORY_FOR to model
4200
4201 · Rename ABSTRACT_FACTORY to abstract
4202
4203 · Rename FACTORY_STRATEGY to strategy
4204
4205 · Rename FACTORY_ARG_PARAMETERS to inline_args
4206
4207 · Rename FACTORY_HIDDEN_ARGS to exclude
4208
4209 For factory.django.DjangoModelFactory:
4210
4211 · Rename FACTORY_DJANGO_GET_OR_CREATE to django_get_or_create
4212
4213 For factory.alchemy.SQLAlchemyModelFactory:
4214
4215 · Rename FACTORY_SESSION to sqlalchemy_session
4216
4217 2.3.1 (2014-01-22)
4218 Bugfix:
4219
4220 · Fix badly written assert containing state-changing code, spotted
4221 by chsigi (pull request #126)
4222
4223 · Don’t crash when handling objects whose __repr__ is non-pure-ascii
4224 bytes on Py2, discovered by mbertheau (issue #123) and strycore (‐
4225 pull request #127)
4226
4227 2.3.0 (2013-12-25)
4228 New:
4229
4230 · Add FuzzyText, thanks to jdufresne (pull request #97)
4231
4232 · Add FuzzyDecimal, thanks to thedrow (pull request #94)
4233
4234 · Add support for EmbeddedDocument, thanks to imiric (pull request
4235 #100)
4236
4237 2.2.1 (2013-09-24)
4238 Bugfix:
4239
4240 · Fixed sequence counter for DjangoModelFactory when a factory
4241 inherits from another factory relating to an abstract model.
4242
4243 2.2.0 (2013-09-24)
4244 Bugfix:
4245
4246 · Removed duplicated SQLAlchemyModelFactory lurking in factory (pull
4247 request #83)
4248
4249 · Properly handle sequences within object inheritance chains. If
4250 FactoryA inherits from FactoryB, and their associated classes
4251 share the same link, sequence counters will be shared (issue #93)
4252
4253 · Properly handle nested SubFactory overrides
4254
4255 New:
4256
4257 · The DjangoModelFactory now supports the FACTORY_FOR =
4258 'myapp.MyModel' syntax, making it easier to shove all factories in
4259 a single module (issue #66).
4260
4261 · Add factory.debug() helper for easier backtrace analysis
4262
4263 · Adding factory support for mongoengine with MongoEngineFactory.
4264
4265 2.1.2 (2013-08-14)
4266 New:
4267
4268 · The ABSTRACT_FACTORY keyword is now optional, and automatically
4269 set to True if neither the Factory subclass nor its parent declare
4270 the FACTORY_FOR attribute (issue #74)
4271
4272 2.1.1 (2013-07-02)
4273 Bugfix:
4274
4275 · Properly retrieve the color keyword argument passed to ImageField
4276
4277 2.1.0 (2013-06-26)
4278 New:
4279
4280 · Add FuzzyDate thanks to saulshanabrook
4281
4282 · Add FuzzyDateTime and FuzzyNaiveDateTime.
4283
4284 · Add a factory_parent attribute to the Resolver passed to LazyAt‐
4285 tribute, in order to access fields defined in wrapping factories.
4286
4287 · Move DjangoModelFactory and MogoFactory to their own modules (fac‐
4288 tory.django and factory.mogo)
4289
4290 · Add the reset_sequence() classmethod to Factory to ease resetting
4291 the sequence counter for a given factory.
4292
4293 · Add debug messages to factory logger.
4294
4295 · Add a reset() method to Iterator (issue #63)
4296
4297 · Add support for the SQLAlchemy ORM through SQLAlchemyModelFactory
4298 (pull request #64, thanks to Romain Commandé)
4299
4300 · Add factory.django.FileField and factory.django.ImageField hooks
4301 for related Django model fields (issue #52)
4302
4303 Bugfix
4304
4305 · Properly handle non-integer pks in DjangoModelFactory (issue #57).
4306
4307 · Disable RelatedFactory generation when a specific value was passed
4308 (issue #62, thanks to Gabe Koscky)
4309
4310 Deprecation:
4311
4312 · Rename RelatedFactory’s name argument to factory_related_name (See
4313 issue #58)
4314
4315 2.0.2 (2013-04-16)
4316 New:
4317
4318 · When FACTORY_DJANGO_GET_OR_CREATE is empty, use Model.objects.cre‐
4319 ate() instead of Model.objects.get_or_create.
4320
4321 2.0.1 (2013-04-16)
4322 New:
4323
4324 · Don’t push defaults to get_or_create when FAC‐
4325 TORY_DJANGO_GET_OR_CREATE is not set.
4326
4327 2.0.0 (2013-04-15)
4328 New:
4329
4330 · Allow overriding the base factory class for make_factory() and
4331 friends.
4332
4333 · Add support for Python3 (Thanks to kmike and nkryptic)
4334
4335 · The default type for Sequence is now int
4336
4337 · Fields listed in FACTORY_HIDDEN_ARGS won’t be passed to the asso‐
4338 ciated class’ constructor
4339
4340 · Add support for get_or_create in DjangoModelFactory, through FAC‐
4341 TORY_DJANGO_GET_OR_CREATE.
4342
4343 · Add support for fuzzy attribute definitions.
4344
4345 · The Sequence counter can be overridden when calling a generating
4346 function
4347
4348 · Add Dict and List declarations (Closes issue #18).
4349
4350 Removed:
4351
4352 · Remove associated class discovery
4353
4354 · Remove InfiniteIterator and infinite_iterator()
4355
4356 · Remove CircularSubFactory
4357
4358 · Remove extract_prefix kwarg to post-generation hooks.
4359
4360 · Stop defaulting to Django’s Foo.objects.create() when “creating”
4361 instances
4362
4363 · Remove STRATEGY_*
4364
4365 · Remove set_building_function() / set_creation_function()
4366
4367 1.3.0 (2013-03-11)
4368 WARNING:
4369 This version deprecates many magic or unexplicit features that will
4370 be removed in v2.0.0.
4371
4372 Please read the Upgrading section, then run your tests with python
4373 -W default to see all remaining warnings.
4374
4375 New
4376 ·
4377
4378 Global:
4379
4380 · Rewrite the whole documentation
4381
4382 · Provide a dedicated MogoFactory subclass of Factory
4383
4384 ·
4385
4386 The Factory class:
4387
4388 · Better creation/building customization hooks at factory.Fac‐
4389 tory._build() and factory.Factory.create()
4390
4391 · Add support for passing non-kwarg parameters to a Factory
4392 wrapped class through FACTORY_ARG_PARAMETERS.
4393
4394 · Keep the FACTORY_FOR attribute in Factory classes
4395
4396 ·
4397
4398 Declarations:
4399
4400 · Allow SubFactory to solve circular dependencies between fac‐
4401 tories
4402
4403 · Enhance SelfAttribute to handle “container” attribute fetch‐
4404 ing
4405
4406 · Add a getter to Iterator declarations
4407
4408 · A Iterator may be prevented from cycling by setting its
4409 cycle argument to False
4410
4411 · Allow overriding default arguments in a PostGeneration‐
4412 MethodCall when generating an instance of the factory
4413
4414 · An object created by a DjangoModelFactory will be saved
4415 again after PostGeneration hooks execution
4416
4417 Pending deprecation
4418 The following features have been deprecated and will be removed in an
4419 upcoming release.
4420
4421 ·
4422
4423 Declarations:
4424
4425 · InfiniteIterator is deprecated in favor of Iterator
4426
4427 · CircularSubFactory is deprecated in favor of SubFactory
4428
4429 · The extract_prefix argument to post_generation() is now dep‐
4430 recated
4431
4432 ·
4433
4434 Factory:
4435
4436 · Usage of set_creation_function() and set_building_function()
4437 are now deprecated
4438
4439 · Implicit associated class discovery is no longer supported,
4440 you must set the FACTORY_FOR attribute on all Factory sub‐
4441 classes
4442
4443 Upgrading
4444 This version deprecates a few magic or undocumented features. All
4445 warnings will turn into errors starting from v2.0.0.
4446
4447 In order to upgrade client code, apply the following rules:
4448
4449 · Add a FACTORY_FOR attribute pointing to the target class to each Fac‐
4450 tory, instead of relying on automagic associated class discovery
4451
4452 · When using factory_boy for Django models, have each factory inherit
4453 from DjangoModelFactory
4454
4455 · Replace factory.CircularSubFactory('some.module', 'Symbol') with fac‐
4456 tory.SubFactory('some.module.Symbol')
4457
4458 · Replace factory.InfiniteIterator(iterable) with factory.Itera‐
4459 tor(iterable)
4460
4461 · Replace @factory.post_generation() with @factory.post_generation
4462
4463 · Replace factory.set_building_function(SomeFactory, building_function)
4464 with an override of the _build() method of SomeFactory
4465
4466 · Replace factory.set_creation_function(SomeFactory, creation_function)
4467 with an override of the _create() method of SomeFactory
4468
4469 1.2.0 (2012-09-08)
4470 New:
4471
4472 · Add CircularSubFactory to solve circular dependencies between fac‐
4473 tories
4474
4475 1.1.5 (2012-07-09)
4476 Bugfix:
4477
4478 · Fix PostGenerationDeclaration and derived classes.
4479
4480 1.1.4 (2012-06-19)
4481 New:
4482
4483 · Add use_strategy() decorator to override a Factory’s default
4484 strategy
4485
4486 · Improve test running (tox, python2.6/2.7)
4487
4488 · Introduce PostGeneration and RelatedFactory
4489
4490 1.1.3 (2012-03-09)
4491 Bugfix:
4492
4493 · Fix packaging rules
4494
4495 1.1.2 (2012-02-25)
4496 New:
4497
4498 · Add Iterator and InfiniteIterator for Factory attribute declara‐
4499 tions.
4500
4501 · Provide generate() and simple_generate(), that allow specifying
4502 the instantiation strategy directly. Also provides gener‐
4503 ate_batch() and simple_generate_batch().
4504
4505 1.1.1 (2012-02-24)
4506 New:
4507
4508 · Add build_batch(), create_batch() and stub_batch(), to instantiate
4509 factories in batch
4510
4511 1.1.0 (2012-02-24)
4512 New:
4513
4514 · Improve the SelfAttribute syntax to fetch sub-attributes using the
4515 foo.bar syntax;
4516
4517 · Add ContainerAttribute to fetch attributes from the container of a
4518 SubFactory.
4519
4520 · Provide the make_factory() helper: MyClassFactory = make_fac‐
4521 tory(MyClass, x=3, y=4)
4522
4523 · Add build(), create(), stub() helpers
4524
4525 Bugfix:
4526
4527 · Allow classmethod/staticmethod on factories
4528
4529 Deprecation:
4530
4531 · Auto-discovery of FACTORY_FOR based on class name is now depre‐
4532 cated
4533
4534 1.0.4 (2011-12-21)
4535 New:
4536
4537 · Improve the algorithm for populating a Factory attributes dict
4538
4539 · Add python setup.py test command to run the test suite
4540
4541 · Allow custom build functions
4542
4543 · Introduce MOGO_BUILD build function
4544
4545 · Add support for inheriting from multiple Factory
4546
4547 · Base Factory classes can now be declared abstract.
4548
4549 · Provide DjangoModelFactory, whose Sequence counter starts at the
4550 next free database id
4551
4552 · Introduce SelfAttribute, a shortcut for factory.LazyAt‐
4553 tribute(lambda o: o.foo.bar.baz.
4554
4555 Bugfix:
4556
4557 · Handle nested SubFactory
4558
4559 · Share sequence counter between parent and subclasses
4560
4561 · Fix SubFactory / Sequence interferences
4562
4563 1.0.2 (2011-05-16)
4564 New:
4565
4566 · Introduce SubFactory
4567
4568 1.0.1 (2011-05-13)
4569 New:
4570
4571 · Allow Factory inheritance
4572
4573 · Improve handling of custom build/create functions
4574
4575 Bugfix:
4576
4577 · Fix concurrency between LazyAttribute and Sequence
4578
4579 1.0.0 (2010-08-22)
4580 New:
4581
4582 · First version of factory_boy
4583
4584 Credits
4585 · Initial version by Mark Sandstrom (2010)
4586
4587 · Developed by Raphaël Barrois since 2011
4588
4589 Credits
4590 Maintainers
4591 The factory_boy project is operated and maintained by:
4592
4593 · Jeff Widman <jeff@jeffwidman.com> (https://github.com/jeffwidman)
4594
4595 · Raphaël Barrois <raphael.barrois+fboy@polytechnique.org> (‐
4596 https://github.com/rbarrois)
4597
4598 Contributors
4599 The project was initially created by Mark Sandstrom <‐
4600 mark@deliciouslynerdy.com>.
4601
4602 The project has received contributions from (in alphabetical order):
4603
4604 · Adam Chainz <adam@adamj.eu>
4605
4606 · Alejandro <tovarich@gmail.com>
4607
4608 · Alexey Kotlyarov <a@koterpillar.com>
4609
4610 · Amit Shah <amit@amwam.me>
4611
4612 · Anas Zahim <zanass0@gmail.com> (https://github.com/kamotos)
4613
4614 · Andrey Voronov <voronov84@gmail.com>
4615
4616 · Branko Majic <branko@majic.rs>
4617
4618 · Carl Meyer <carl@oddbird.net>
4619
4620 · Chris Lasher <chris.lasher@gmail.com>
4621
4622 · Chris Seto <chriskseto@gmail.com>
4623
4624 · Christoph Sieghart <sigi@0x2a.at>
4625
4626 · David Baumgold <david@davidbaumgold.com>
4627
4628 · Demur Nodia <demur.nodia@gmail.com> (https://github.com/demonno)
4629
4630 · Eduard Iskandarov <edikexp@gmail.com>
4631
4632 · Federico Bond <federicobond@gmail.com> (‐
4633 https://github.com/federicobond)
4634
4635 · Flavio Curella <flavio.curella@gmail.com>
4636
4637 · François Freitag <mail@franek.fr>
4638
4639 · George Hickman <george@ghickman.co.uk>
4640
4641 · Hervé Cauwelier <herve.cauwelier@polyconseil.fr>
4642
4643 · Ilya Baryshev <baryshev@gmail.com>
4644
4645 · Ilya Pirogov <ilja.pirogov@gmail.com>
4646
4647 · Ionuț Arțăriși <ionut@artarisi.eu>
4648
4649 · Issa Jubril <issa.jubril@andela.com>
4650
4651 · Ivan Miric <imiric@gmail.com>
4652
4653 · Janusz Skonieczny <wooyek@users.noreply.github.com>
4654
4655 · Jeff Widman <jeff@jeffwidman.com> (https://github.com/jeffwidman)
4656
4657 · Jon Dufresne <jon.dufresne@gmail.com>
4658
4659 · Jonathan Tushman <jtushman@pipewave.com>
4660
4661 · Joshua Carp <jm.carp@gmail.com>
4662
4663 · Leonardo Lazzaro <llazzaro@dc.uba.ar>
4664
4665 · Luke GB <github@lukegb.com>
4666
4667 · Marc Abramowitz <marc@marc-abramowitz.com>
4668
4669 · Mark Sandstrom <mark@deliciouslynerdy.com>
4670
4671 · Martin Bächtold <martin+factoryboy@baechtold.me> (‐
4672 https://github.com/mbaechtold)
4673
4674 · Michael Joseph <michaeljoseph+github@gmail.com>
4675
4676 · Mikhail Korobov <kmike84@gmail.com>
4677
4678 · Oleg Pidsadnyi <oleg.pidsadnyi@gmail.com>
4679
4680 · Omer <omer@stokeet.com>
4681
4682 · Pauly Fenwar <fenney@gmail.com>
4683
4684 · Peter Marsh <pete@skimlinks.com>
4685
4686 · Puneeth Chaganti <punchagan@muse-amuse.in>
4687
4688 · QuantumGhost <obelisk.reg+github@gmail.com>
4689
4690 · Raphaël Barrois <raphael.barrois+fboy@polytechnique.org> (‐
4691 https://github.com/rbarrois)
4692
4693 · Rich Rauenzahn <rich@vmware.com>
4694
4695 · Richard Moch <richard@mbp.polyconseil.fr>
4696
4697 · Rob Zyskowski <zyskowski.rob@gmail.com>
4698
4699 · Robrecht De Rouck <Robrecht.De.Rouck@gmail.com>
4700
4701 · Samuel Paccoud <samuel@sampaccoud.com>
4702
4703 · Saul Shanabrook <s.shanabrook@gmail.com>
4704
4705 · Sean Löfgren <SeanBE@users.noreply.github.com>
4706
4707 · Tom <tom@tomleo.com>
4708
4709 · alex-netquity <alex@netquity.com>
4710
4711 · anentropic <ego@anentropic.com>
4712
4713 · minimumserious <commande.romain@gmail.com>
4714
4715 · mluszczyk <mluszczyk@users.noreply.github.com>
4716
4717 · nkryptic <nkryptic@gmail.com>
4718
4719 · obiwanus <ivan@ivanovs.info>
4720
4721 · tsouvarev <tsouvarev@mail.ru>
4722
4723 · yamaneko <yamaneko1212@gmail.com>
4724
4725 Contributor license agreement
4726 NOTE:
4727 This agreement is required to allow redistribution of submitted con‐
4728 tributions. See http://oss-watch.ac.uk/resources/cla for an expla‐
4729 nation.
4730
4731 Any contributor proposing updates to the code or documentation of this
4732 project MUST add its name to the list in the Contributors section,
4733 thereby “signing” the following contributor license agreement:
4734
4735 They accept and agree to the following terms for their present end
4736 future contributions submitted to the factory_boy project:
4737
4738 · They represent that they are legally entitled to grant this license,
4739 and that their contributions are their original creation
4740
4741 · They grant the factory_boy project a perpetual, worldwide, non-exclu‐
4742 sive, no-charge, royalty-free, irrevocable copyright license to
4743 reproduce, prepare derivative works of, publicly display, sublicense
4744 and distribute their contributions and such derivative works.
4745
4746 · They are not expected to provide support for their contributions,
4747 except to the extent they desire to provide support.
4748
4749 NOTE:
4750 The above agreement is inspired by the Apache Contributor License
4751 Agreement.
4752
4753 Ideas
4754 This is a list of future features that may be incorporated into fac‐
4755 tory_boy:
4756
4757 · When a Factory is built or created, pass the calling context through‐
4758 out the calling chain instead of custom solutions everywhere
4759
4760 · Define a proper set of rules for the support of third-party ORMs
4761
4762 · Properly evaluate nested declarations (e.g factory.fuzzy.Fuzzy‐
4763 Date(start_date=factory.SelfAttribute('since')))
4764
4765 · genindex
4766
4767 · modindex
4768
4769 · search
4770
4772 Raphaël Barrois, Mark Sandstrom
4773
4775 2011-2020, Raphaël Barrois, Mark Sandstrom
4776
4777
4778
4779
47802.12 Jan 30, 2020 FACTORYBOY(1)