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