pytest-dev / pytest-factoryboy Goto Github PK
View Code? Open in Web Editor NEWfactory_boy integration the pytest runner
License: MIT License
factory_boy integration the pytest runner
License: MIT License
Hi all,
When you have a project with many apps and many factories, you may not want to import them all explicitely in the conftest.py. So you import them with a star per package. (in general not a good practice)
IMHO, it would be great if pytest-factoryboy could emit an error for clashing names, rather than silently ignoring/overwriting them.
Thanks for the great work else!
'addhooks' attribute of PytestPluginManager is removed at pytest 5.0.0.
Because of this, add_hookspecs = getattr(pluginmanager, 'add_hookspecs', pluginmanager.addhooks)
does not work (#16). It occur following error.
Traceback (most recent call last):
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/bin/pytest", line 10, in <module>
sys.exit(main())
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 55, in main
config = _prepareconfig(args, plugins)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 200, in _prepareconfig
pluginmanager=pluginmanager, args=args
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/hooks.py", line 289, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 87, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 81, in <lambda>
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 203, in _multicall
gen.send(outcome)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/helpconfig.py", line 89, in pytest_cmdline_parse
config = outcome.get_result()
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 661, in pytest_cmdline_parse
self.parse(args)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 869, in parse
self._preparse(args, addopts=addopts)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 815, in _preparse
self.pluginmanager.load_setuptools_entrypoints("pytest11")
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 293, in load_setuptools_entrypoints
self.register(plugin, name=ep.name)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/_pytest/config/__init__.py", line 302, in register
ret = super().register(plugin, name)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 121, in register
hook._maybe_apply_history(hookimpl)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/hooks.py", line 336, in _maybe_apply_history
res = self._hookexec(self, [method], kwargs)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 87, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/manager.py", line 81, in <lambda>
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pluggy/callers.py", line 187, in _multicall
res = hook_impl.function(*args)
File "/Users/ohing/.virtualenvs/django-drf-project-template-Kk8KycnX/lib/python3.7/site-packages/pytest_factoryboy/plugin.py", line 117, in pytest_addhooks
add_hookspecs = getattr(pluginmanager, 'add_hookspecs', pluginmanager.addhooks)
AttributeError: 'PytestPluginManager' object has no attribute 'addhooks'
factory_boy List declarations are not working with pytest_factoryboy for me. Below is a simple example that should bring out the issue (and an attachment). Could I please get any feedback on this?
Thanks in advance
list_declaration_example.py.zip
import factory
from pytest_factoryboy import register
class ClassA(object):
def __init__(self):
self._val = 'test_value'
@property
def val(self):
return self._val
class ClassB(object):
def __init__(self):
self._arr = [ClassA()]
@property
def arr(self):
return self._arr
class ClassAFactory(factory.Factory):
"""TestClassA factory."""
class Meta:
model = ClassA
_val = 'test_value'
class ClassBFactory(factory.Factory):
"""TestClassB factory."""
class Meta:
model = ClassB
arr = factory.List([
factory.SubFactory(ClassAFactory)
])
register(ClassAFactory)
register(ClassBFactory)
def test_example_a(class_a):
"""
Assert that the nested list is properly tested
"""
assert class_a.val == 'test_value'
def test_example_b(class_b):
"""
Assert that the nested list is properly tested
"""
assert len(class_b.arr) == 1
============================= test session starts ==============================
platform darwin -- Python 3.5.2, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /Users/alejandrosanchez/Development/testdir, inifile: setup.cfg
plugins: factoryboy-2.0.1, cov-2.5.1
collected 2 items
list_declaration_example.py .E [100%]
test setup failed
file /Users/alejandrosanchez/Development/testdir/list_declaration_example.py, line 49
def test_example_b(class_b):
file <string>, line 2: source code not available
file <string>, line 2: source code not available
E fixture 'list' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, class_a, class_a_factory, class_b, class_b__arr, class_b_factory, cov, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
<string>:2
==================================== ERRORS ====================================
_______________________ ERROR at setup of test_example_b _______________________
file /Users/alejandrosanchez/Development/testdir/list_declaration_example.py, line 49
def test_example_b(class_b):
file <string>, line 2: source code not available
file <string>, line 2: source code not available
E fixture 'list' not found
> available fixtures: cache, capfd, capfdbinary, caplog, capsys, capsysbinary, class_a, class_a_factory, class_b, class_b__arr, class_b_factory, cov, doctest_namespace, factoryboy_request, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
<string>:2
====================== 1 passed, 1 error in 0.10 seconds =======================
Process finished with exit code 0
Might be worth adding fixtures for creating models with build
instead of create
I know this exists because I've used FactoryBot in Rails and I knew to look for it, but others might not, and it's probably worth nudging people towards writing non-db tests when they can
If I've understood correctly, currently the only way to build
is to use the factory fixture and call build?
def test(asset_factory):
asset = asset_factory.build()
Automatically registering fixtures like asset_build
or similar might be a way to go. Thoughts?
I'm not sure if this is currently supported or not, but I'm not actually trying to work with objects. I'd like to use factoryboy to just generate dicts for test data:
test.py:
import factory
import pytest_factoryboy
class ChildFactory(factory.Factory):
class Meta:
model = dict
child_attr = 'default'
class ParentFactory(factory.Factory):
class Meta:
model = dict
child = factory.SubFactory(ChildFactory)
pytest_factoryboy.register(ParentFactory, 'parent')
def test_basic(parent):
assert parent.child.child_attr == 'default'
Test output:
$ pytest test.py
========================================================================================================================================================================== test session starts ===========================================================================================================================================================================
platform linux2 -- Python 2.7.6, pytest-3.1.2, py-1.4.34, pluggy-0.4.0
rootdir: /tmp, inifile:
plugins: factoryboy-1.3.1
collected 1 items
test.py E
================================================================================================================================================================================= ERRORS =================================================================================================================================================================================
______________________________________________________________________________________________________________________________________________________________________ ERROR at setup of test_basic ______________________________________________________________________________________________________________________________________________________________________
file /tmp/test.py, line 22
def test_basic(parent):
file <string>, line 2: source code not available
file <string>, line 2: source code not available
E fixture 'dict__child_attr' not found
> available fixtures: cache, capfd, capsys, doctest_namespace, factoryboy_request, monkeypatch, parent, parent__child, parent_factory, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
<string>:2
======================================================================================================================================================================== 1 error in 0.02 seconds =========================================================================================================================================================================
Output of pip freeze
:
factory-boy==2.8.1
Faker==0.7.17
inflection==0.3.1
ipaddress==1.0.18
py==1.4.34
pytest==3.1.2
pytest-factoryboy==1.3.1
python-dateutil==2.6.0
six==1.10.0
If this shouldn't be supported in the plugin, I'd be happy to use some other workaround that pokes through factoryboy/pytest_factoryboy internals.
I'm using Django and have a Model with multiple ForeginKey pointing to the same Model. I have factories created like:
class FooFactory(DjangoModelFactory):
class Meta:
model = Foo
value = factory.fuzzy.FuzzyInteger(100)
active = False
class BarFactory(DjangoModelFactory):
class Meta:
model = Bar
a = factory.SubFactory(FooFactory, active=True)
b = factory.SubFactory(FooFactory, active=False)
c = factory.SubFactory(FooFactory)
register(FooFactory, "foo")
register(BarFactory, "bar")
When I call BarFactory in test it creates object having different objects having different values. But when i get it by fixture it returns all fields having the same model attached ignoring additional flags.
So far I have made a workaround assigning a, b and c in BarFactory _create() method, but in that way i loose all benefits of this plugin.
In conftest.py I am registering factory classes from the django ORM factoryboy base class
I am importing register by
"from pytest_factoryboy import register" [I have found that it matters]
This issue occurs on either of the two below as the factory class:
factory.Factory or factory.djangoORM...Factory (sorry can't remember)
To produce error:
Running the command
"py.test --fixtures DIRECTORY"
where DIRECTORY is folder containing pytest.ini & manage.py
That command lists the fixtures available for the test configuration.
That command produces: "unorderable types: module() < str()"
I traced it back through and by modifying
pytest_factorboy\fixture.py
in the make_fixture function where it was
fixture_func.module = module
I changed it to
fixture_func.module = str(module)
and all the fixtures were listed properly, but the fixtures I registered through pytest_factoryboy had the fixture module grouping in "c:\folder\folder\conftest.py"
I then changed it to
fixture_func.module = os.path.basename(module.path[0])
or sorry something like it, but gave it the base filename of conftest
fixture_func.module = "conftest"
and the fixtures were grouped in the correct location with py.test --fixtures
Django is amazing
factoryboy is great
py.test is wonderful
&
pytest_factoryboy is a must have! Thank you all for the work you do!
Successfully just had world class Test Driven Development today with what I consider good tests. Implementing your library was a very good call....
when I do
register(AuthorFactory)
it creates fixture author_factory
my question is how can I specify a scope='session'
to the fixture ?
Hi guys. Thanks for the work you've done. I use this project quite often and there is a little problem.
It's possible to pass in create=True
param to register
function to override default behavior of a factory fixture.
Unfortunately it does not affect a model fixture and it's impossible to override this behavior. Quite often my tests need in-db model instance. Right now I need to do:
def test_my_test(some_obj):
some_obj.save()
...
This is a little be annoying and to me eliminates the benefit of that fixture. Because I can achieve the same goal with:
def test_my_tests(some_obj_factory):
some_obj = some_obj_factory()
It would very convenient to be able not to call save
each time before the test.
It is very strange why object is not saved in DB.
Multi-Table Inheritance is presenting some challenges with pytest-factoryboy
We currently have one-to-one's for some models so a lot of our tests are based on this concept:
def test_assets(db, asset, photo):
assert asset == photo.asset
But now we're switching to MTI where the Photo
model is a subtype of Asset
and thus our PhotoFactory
inherits from AssetFactory
This means the asset
and photo
fixtures generate independent asset records – photo.asset
is still an Asset
but that is now a "parent record" and is not assignable afaik
@olegpidsadnyi It would be good if the above test could still pass, but I am not sure how to achieve this, I've tried throwing more LazyFixture('asset')
in but that doesn't seem to help – any guidance?
It seems to be that SubFactory
does not work with self-referencing ForeignKey relationships. I have a model with a foreign key to self
:
class MyAuthor(Model):
full_name = CharField('Full name', max_length=255)
original_author = ForeignKey('self', null=True)
This is the factory I tried to use:
class MyAuthorFactory(factory.django.DjangoModelFactory):
full_name = 'John Doe'
original_author = factory.SubFactory('app.factories.MyAuthorFactory')
class Meta:
model = 'app.models.Author'
I registered the factory like this:
register(MyAuthorFactory, 'myauthor')
And got this error:
recursive dependency involving fixture 'myauthor' detected
available fixtures: ... myauthor, myauthor__full_name, ...
With pytest 3.8 using pytest-factoryboy starts producing
/.../python3.6/site-packages/pytest_factoryboy/plugin.py:107: DeprecationWarning: getfuncargvalue is deprecated, use getfixturevalue
factoryboy_request = request.getfuncargvalue("factoryboy_request")
Here (https://docs.pytest.org/en/latest/warnings.html#deprecationwarning-and-pendingdeprecationwarning) is chagne in pytest that make this issue visible again, but its till there.
This is similar/same issue as #41 . Even after rewrite latest pytest-factoryboy still uses getfuncargvalue
in pytest_factoryboy/plugin.py
lines 73 and 107.
If this is not intentional can prepare PR to fix this.
This is with py.test 2.8.5.
The py.test warning is "use pluginmanager.add_hookspecs instead of deprecated addhooks() method."
Most m2m relation handling for factories in Django is pretty simple, is this of interest?
class ManyToManyPostGeneration(factory.PostGeneration):
"""
Simplified factory post_generation for many-to-many relationships - sets values passed to the collection
https://factoryboy.readthedocs.io/en/latest/recipes.html?highlight=many#simple-many-to-many-relationship
Arguments:
name: the name of the many-to-many relation
Usage:
You can pass the factory a list of model instances
- article_factory.create(tags=LazyFixture(lambda tag: [tag])))
Or you can use the parametrize decorator
- @pytest.mark.parametrize('article__tags', [LazyFixture(lambda tag: [tag])])
"""
def __init__(self, name):
def func(self, create, extracted, **kwargs):
if create and extracted:
getattr(self, name).set(extracted)
func.__name__ = name
return super().__init__(func)
Makes basic m2m declarations as simple as
class ArticleFactory(factory.django.DjangoModelFactory):
tags = ManyToManyPostGeneration('tags')
You can also define and use the inverse side too
class TagFactory(factory.django.DjangoModelFactory):
articles = ManyToManyPostGeneration('articles')
I'd drop the string arg but I couldn't figure out how to know the relation name otherwise
Another thought was whether it should add
or set
– the examples provided use add
but I figure given the whole list is passed in an explicit set
is probably what is expected (i.e. clobber)
Any interest in something like this in pytest-factoryboy?
I'd like to override the sequence counter.
My first attempt:
# models.py
from django.db import models
class Foo(models.Model):
a = models.IntegerField()
b = models.IntegerField()
# factories.py
from factory import DjangoModelFactory, Sequence
from .models import Foo
class FooFactory(DjangoModelFactory):
class Meta:
model = Foo
a = Sequence(lambda x: x)
b = Sequence(lambda x: x)
# test_one.py
from pytest_factoryboy import register
from .factories import FooFactory
register(FooFactory, __sequence=8)
@pytest.fixture
def foo__sequence():
return 9
@pytest.fixture
def foo____sequence():
return 10
def test_1(db, foo):
assert foo.a in (8, 9, 10)
I ended up with the following workaround:
# factories.py
from factory import DjangoModelFactory, Sequence, SelfAttribute
from .models import Foo
class FooFactory(DjangoModelFactory):
class Meta:
model = Foo
exclude = ('i',)
i = Sequence(lambda x: x)
a = SelfAttribute('i')
b = SelfAttribute('i')
# test_one.py
from pytest_factoryboy import register
from .factories import FooFactory
register(FooFactory, i=8)
@pytest.fixture
def foo__i():
return 9
def test_1(db, foo):
assert foo.a in (8, 9)
assert foo.b in (8, 9)
Either register
or foo__i
work, no need for both of course.
The workaround is simple, so it may suffice to just note the workaround in the docs for now. Or if I've missed something, please let me know.
Thanks for the nice plugin.
This really puzzled me. It's a typo and probably and easy fix.
Hello,
I use pytest == 3.1.0 and get this warning:
DeprecationWarning: use of getfuncargvalue is deprecated, use getfixturevalue
While reviewing NixOS/nixpkgs#89248, I found that this project claims the MIT license but doesn't include the MIT license text in the repository anywhere. Best practice is to include the license along with your source code. To remedy, follow the steps listed: https://www.freecodecamp.org/news/how-open-source-licenses-work-and-how-to-add-them-to-your-projects-34310c3cf94/ (Heading: Applying a license to your open source projects
)
Factoryboy documents the creation of circular dependencies like this:
class UserFactory(factory.Factory):
class Meta:
model = User
username = 'john'
main_group = factory.SubFactory('users.factories.GroupFactory')
class GroupFactory(factory.Factory):
class Meta:
model = Group
name = "MyGroup"
owner = factory.SubFactory(UserFactory)
That example will not work with the @register
decorator:
@register
class UserFactory(factory.Factory):
class Meta:
model = User
username = 'john'
main_group = factory.SubFactory('users.factories.GroupFactory')
@register
class GroupFactory(factory.Factory):
class Meta:
model = Group
name = "MyGroup"
owner = factory.SubFactory(UserFactory)
Throws:
ImportError while loading conftest '/app/_python/conftest.py'.
conftest.py:58: in <module>
class UserFactory(factory.Factory):
/usr/local/lib/python3.5/site-packages/pytest_factoryboy/fixture.py:91: in register
subfactory_class = value.get_factory()
/usr/local/lib/python3.5/site-packages/factory/declarations.py:647: in get_factory
return self.factory_wrapper.get()
/usr/local/lib/python3.5/site-packages/factory/declarations.py:363: in get
self.name,
/usr/local/lib/python3.5/site-packages/factory/utils.py:20: in import_object
return getattr(module, str(attribute_name))
E AttributeError: module 'conftest' has no attribute 'GroupFactory'
The issue seems to be that @register
resolves the imports when applied, before the later classes are defined. So a workaround is to use the non-decorator version at the end of the file. This works:
# same as first code block, then ...
register(UserFactory)
register(GroupFactory)
Ideally the decorator form could Just Work, by delaying resolution of the imports until needed. Alternatively maybe the problem could be documented, and register() could detect what's happening and throw a more useful error?
I tried to look at the source (for a PR) by clicking "view source" in rtd.io, however has stumbled into a 404 here: https://github.com/pytest-dev/pytest-factoryboy/blob/master/index.rst.
The rtd build job also fails for apparently the same reason.
There appears to be no way to define the scope of the resulting fixtures. Not sure if this is unsupported or undocumented, but it is a needed feature. Creating a new fixture scoped for "module" or "session" is not workable as the scope change results in an exception. Currently, all registered Factories are 'function' scoped.
Hey there,
I'm trying to set up a basic test per this example:
https://pytest-factoryboy.readthedocs.io/en/latest/#integration
When my tests check whether company_factory
is an instance of CompanyFactory
, the test fails.
Why isn't company_factory
being instantiated?
Here's my code:
# tests/test_company.py
import pytest
from .factories import CompanyFactory
from project.apps.company.models import Company
def test_company_factory(company_factory):
assert isinstance(company_factory, CompanyFactory) # passes
def test_company_model(db, company):
assert isinstance(company, Company) # fails
# message: where False = isinstance(<class 'tests.factories.CompanyFactory'>, CompanyFactory)**
# tests/factories.py
class CompanyFactory(factory.django.DjangoModelFactory):
class Meta:
model = 'company.Company'
name = 'company'
# other attributes ...
# tests/conftest.py
import pytest
from pytest_factoryboy import register
from .factories import CompanyFactory
register(CompanyFactory)
Tests failing
============================================================================================================ ERRORS =============================================================================================================
________________________________________________________________________________________ ERROR collecting tests/test_factory_fixtures.py ________________________________________________________________________________________
In function "test_parametrized":
Parameter "edition__year" should be declared explicitly via indirect or in function itself
__________________________________________________________________________________________ ERROR collecting tests/test_lazy_fixture.py __________________________________________________________________________________________
In function "test_lazy_attribute":
Parameter "user__password" should be declared explicitly via indirect or in function itself
______________________________________________________________________________________ ERROR collecting tests/test_postgen_dependencies.py ______________________________________________________________________________________
In function "test_depends_on":
Parameter "foo__expected" should be declared explicitly via indirect or in function itself
There are errors with factory_boy
master:
================================================ ERRORS ================================================
_______________________________ ERROR collecting tests/test_circular.py ________________________________
tests/test_circular.py:50: in <module>
register(AuthorFactory)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:60: in register
deps = get_deps(factory_class, model_name=model_name)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:154: in get_deps
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items()
E AttributeError: 'FactoryOptions' object has no attribute 'postgen_declarations'
___________________________ ERROR collecting tests/test_factory_fixtures.py ____________________________
tests/test_factory_fixtures.py:56: in <module>
class AuthorFactory(factory.Factory):
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:60: in register
deps = get_deps(factory_class, model_name=model_name)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:154: in get_deps
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items()
E AttributeError: 'FactoryOptions' object has no attribute 'postgen_declarations'
_____________________________ ERROR collecting tests/test_lazy_fixture.py ______________________________
tests/test_lazy_fixture.py:29: in <module>
register(UserFactory)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:60: in register
deps = get_deps(factory_class, model_name=model_name)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:154: in get_deps
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items()
E AttributeError: 'FactoryOptions' object has no attribute 'postgen_declarations'
_________________________ ERROR collecting tests/test_postgen_dependencies.py __________________________
tests/test_postgen_dependencies.py:23: in <module>
class FooFactory(factory.Factory):
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:60: in register
deps = get_deps(factory_class, model_name=model_name)
.tox/py36-pytest3/lib/python3.6/site-packages/pytest_factoryboy/fixture.py:154: in get_deps
for attr, value in factory_class.declarations(factory_class._meta.postgen_declarations).items()
E AttributeError: 'FactoryOptions' object has no attribute 'postgen_declarations'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 4 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================= 4 error in 0.30 seconds ========================================
ERROR: InvocationError: '…/Vcs/pytest-factoryboy/.tox/py36-pytest3/bin/py.test --junitxml=…/Vcs/pytest-factoryboy/.tox/py36-pytest3/log/junit-py36-pytest3.xml pytest_factoryboy tests'
_______________________________________________ summary ________________________________________________
ERROR: py36-pytest3: commands failed
Bisecting brings up the following commits (2 are skipped, since they cause a different error):
FactoryBoy/factory_boy@c079d87
FactoryBoy/factory_boy@e447662
FactoryBoy/factory_boy@6f20207
Likely related to the refactoring mentioned in #23 (comment).
Due to unsorted dict that Factory.attributes returns the evaluation of the LazyFixture is not yet done for the LazyAttribute even it is declared above the latter.
When using factory.PostGenerationMethodCall on a factory I get the type error in the title.
The factory I'm working with is a django user model. Simple example:
class UserFactory(factory.django.DjangoModelFactory):
email = factory.Sequence(lambda n: "user-{0}@example.com".format(n))
password = factory.PostGenerationMethodCall("set_password", ["password"])
first_name = fuzzy.FuzzyText(length=20)
last_name = fuzzy.FuzzyText(length=20)
class Meta:
model = "users.User"
django_get_or_create = ("email",)
register(UserFactory)
Attempting to use that factory as a fixture will throw:
env/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:83: in evaluate
self.execute(request, function, deferred)
env/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:65: in execute
self.results[model][attr] = function(request)
env/lib/python3.7/site-packages/pytest_factoryboy/fixture.py:273: in deferred
declaration.call(instance, step, context)
env/lib/python3.7/site-packages/factory/declarations.py:743: in call
return method(*args, **kwargs)
env/lib/python3.7/site-packages/django/contrib/auth/base_user.py:98: in set_password
self.password = make_password(raw_password)
env/lib/python3.7/site-packages/django/contrib/auth/hashers.py:78: in make_password
return hasher.encode(password, salt)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.contrib.auth.hashers.MD5PasswordHasher object at 0x7f1fa3759cd0>, password = <factory.declarations.PostGenerationMethodCall object at 0x7f1fa47ff390>, salt = 'XXXXXXXXX'
def encode(self, password, salt):
assert password is not None
assert salt and '$' not in salt
> hash = hashlib.md5((salt + password).encode()).hexdigest()
E TypeError: can only concatenate str (not "PostGenerationMethodCall") to str
env/lib/python3.7/site-packages/django/contrib/auth/hashers.py:508: TypeError
The error stems from
.Changing that check to something like:
if isinstance(value, factory.declarations.PostGeneration) or isinstance(
value, factory.declarations.PostGenerationMethodCall
):
Seems to fix the issue. I haven't looked at this closely though so not sure if that's the best solution.
possibly relevant versions:
pytest-factoryboy==2.0.3
django==2.2.6
factory-boy==2.12.0
pytest-django==3.6.0
Because pytest-factoryboy
replaces SubFactory
with registered factories, it is possible to inadvertently create circular dependencies, which are not detected by pytest.
In my case, the setup was the following:
User
factoryCompany
factory with a Contact
subfactory.user
fixture overridden in the test file, depending on the company
fixturecontact
fixture overridden in the same file, depending on the company
fixture.Normally it should be fine because user -> company
and contact -> company
- there's no cycle. But, because the plugin creates a dependency company -> contact
, the graph becomes: user -> company -> contact -> company
and there's a cycle. Yet this cycle is a bit magical - I did not ask for company.contact
and contact.company
to be the same... I want a new, unrelated contact to be created for each company.
Would it be possible to add an option to disable this for those who don't need it? Or only some whitelisted subfactories? In my case, I would like the company.contact
factory to be unrelated to the contact
factory.
Here's a reproduction:
import factory
from pytest_factoryboy import register
@register
class OAuthPayloadFactory(factory.DictFactory):
"""Fake factory for OAuth payload response."""
refresh_token = 'some-token'
access_token = 'some-refresh-token'
token_type = 'bearer'
expires_in = 0
When trying to access this fixture I get an error:
@pytest.fixture()
def access_token(o_auth_payload): # failing here: o_auth_payload is not found
"""A demo fixture to illustrate the issue."""
return o_auth_payload['access_token']
I expect that o_auth_payload
would be injected as a fixture.
@pytest.fixture()
def user_email(user, o_auth_payload, user_payload):
E fixture 'o_auth_payload' not found
> available fixtures:
dict
<string>:3: no docstring available
dict__access_token
<string>:3: no docstring available
dict__expires_in
<string>:3: no docstring available
dict__refresh_token
<string>:3: no docstring available
dict__token_type
<string>:3: no docstring available
o_auth_payload_factory
<string>:3: no docstring available
pytest==3.6.1
pytest-factoryboy==2.0.1
factory-boy==2.11.1
I am trying to make some tests and this is my first time using pytest-factoryboy
. I would like to understand why my does my print()
doesn't print the same for both objects. I thought they were from the same class (UserFactory).
from pytest_factoryboy import register
from bin.tests.factories import UserFactory
register(UserFactory)
import factory
from pytest_factoryboy import register
from faker import Factory as FakerFactory
import datetime
import pytest
from bin import models
fake = FakerFactory.create()
@register
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.User
django_get_or_create = ('username',)
username = factory.LazyAttribute(lambda n: fake.user_name())
email = factory.LazyAttribute(lambda n: fake.safe_email())
first_name = factory.LazyAttribute(lambda n: fake.first_name_female())
last_name = factory.LazyAttribute(lambda n: fake.last_name_female())
def __init__(self, *args, **kwargs):
super(UserFactory, self).__init__(*args, **kwargs)
self.set_password('1234')
@classmethod
def _create(cls, model_class, *args, **kwargs):
"""Override the default ``_create`` with our custom call."""
manager = cls._get_manager(model_class)
# The default would use ``manager.create(*args, **kwargs)``
user = manager.create_user(*args, **kwargs)
user.is_active = True
user.save()
return user
import pytest
from django.core.urlresolvers import reverse
from django.conf import settings
class TestUser:
@pytest.mark.integration
def test_user_gets_locked_after_unsuccessful_attempts(self, db, user_factory, client):
client.get(reverse('logout'))
for _ in range(0, 10):
response = client.post(
reverse('login'),
{
'username': user_factory.username,
'password': 'some_wrong_password'
}
)
print(user_factory.username)
another_user = UserFactory()
print(another_user.username)
assert user_factory.profile.pwd_attempts > 9
assert not user_factory.is_active
bin/tests/test_user.py:27: AttributeError
----------------------------- Captured stdout call -----------------------------
<UserFactory for <class 'django.contrib.auth.models.User'>>
tinamendoza
Using the convenience register
method to register fixtures does not import the docstring. Running pytest --fixtures
results in no docstring available for all pytest-factoryboy fixtures.
It would be nice to include a docstring arg to the register
method e.g
register(UserFactory, _name="special_user", _docstring="Useful sentence describing this fixture")
Thanks for the library it is very handy!
I'm using factory_boy with https://github.com/pytest-dev/pytest-django.
python: 3.6.2
django: 1.11.4
pytest-django: 3.1.2
factory-boy: 2.8.1 (downgraded due to #47 (comment))
pytest-factoryboy: 1.3.1
Here's my app1/conftest.py:
# -*- coding: utf-8 -*-
import factory
import pytest
from django.contrib.auth import get_user_model
from django.core.management import call_command
from pytest_factoryboy import register
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = get_user_model()
username = factory.Sequence(lambda n: "user%03d" % n)
password = factory.Sequence(lambda n: "pass%03d" % n)
register(UserFactory)
This makes user
available as a fixture for me. However, it only works in tests in the same application, not project-wide (in different django application test directories).
Am I doing it wrong, then? I'm trying to narrow down if this is a mistake on my end, a bug, a potential feature, or expected behavior.
Given the following factories:
class BookFactory(factory.django.DjangoModelFactory):
title = factory.LazyAttribute(lambda x: faker.sentence(nb_words=4))
pub_date = factory.LazyAttribute(lambda x: faker.date())
class Meta:
model = Book
author = factory.SubFactory(AuthorFactory)
class RedBookFactory(BookFactory):
pass
class NovelFactory(BookFactory):
pass
I was a bit confused at first as to why red_book
and novel
fixtures were not being created, but after looking at the code, it looks like the factory's model drives these instance fixtures.
Any interest in creating these fixtures? If not, what's the reasoning?
If anything, maybe add this example to the documentation, showing that the factory fixtures register (red_book_factory
and novel_factory
) but not the instance fixtures (red_book
and novel
).
I run py.test -n auto and got this:
@pytest.mark.tryfirst
def pytest_runtest_call(item):
"""Before the test item is called."""
try:
request = item._request
except AttributeError:
# pytest-pep8 plugin passes Pep8Item here during tests.
return
factoryboy_request = request.getfuncargvalue("factoryboy_request")
factoryboy_request.evaluate()
factoryboy_request.is_finalized = True
> request.config.hook.pytest_factoryboy_done(request=request)
E AttributeError: _HookRelay instance has no attribute 'pytest_factoryboy_done'
Using a factory with a django.Image field leads to error fixture 'dict' not found
.
Sample:
from factory.django import DjangoModelFactory, ImageField
from pytest_factoryboy import register
from . import models
class AttachmentFactory(DjangoModelFactory):
path = ImageField(width=1024, height=768)
class Meta:
model = models.Attachment
register(AttachmentFactory)
# this test will lead to `fixture 'dict' not found` error
def test_attachment(attachment):
# some tests
This happens with following dependencies:
factory-boy==2.10.0
pytest-factoryboy==2.0.1
This worked without any problems with these dependencies:
factory-boy==2.8.1
pytest-factoryboy==1.3.2
Hi how would an integration with sqlalchemy works here ??, especially with the scoped_session
I currently have this conftest.py
setup on my flask project:
@pytest.fixture(scope='session')
def app(request):
"""Session-wide test `Flask` application."""
app = create_app('testing')
# Establish an application context before running the tests.
ctx = app.app_context()
ctx.push()
def teardown():
ctx.pop()
request.addfinalizer(teardown)
return app
@pytest.fixture(scope='session')
def db(app, request):
"""Session-wide test database."""
def teardown():
_db.drop_all()
_db.app = app
_db.create_all()
request.addfinalizer(teardown)
return _db
@pytest.fixture(scope='function')
def session(db, request):
"""Creates a new database session for a test."""
# connect to the database
connection = db.engine.connect()
# begin a non-ORM transaction
transaction = connection.begin()
# bind an individual session to the connection
options = dict(bind=connection, binds={})
session = db.create_scoped_session(options=options)
# overload the default session with the session above
db.session = session
def teardown():
session.close()
# rollback - everything that happened with the
# session above (including calls to commit())
# is rolled back.
transaction.rollback()
# return connection to the Engine
connection.close()
request.addfinalizer(teardown)
return session
# basically instead of creating and dropping the database for each test
# i just rollback the transaction.
# this setup works perfectly fine without using factory boy
I've been searching around the internet on how to make Factory Boy use the same session fixture that pytest use. And then stumble upon this library, but upon looking into the examples, I cant figure how I or this library would do the same.
when having pytest-factoryboy and flake8-3.0.0 packages installed in the environment, pytest-factoryboy will fail registering as a pytest plugin.
common scenario when using pytest-flake8 for instance.
I'll try to see the reason but maybe it's easy enough for someone with more knowledge in the project
I am using pytest-factoryboy to test some of my django Code.
When using A model 'MainModel' with a ForeignKey to another Model 'OneOnly' I create a Factory for both like the following.
models.py:
from django.db import models
class OnlyOne(models.Model):
name = models.CharField(max_length=16)
class MainModel(models.Model):
name = models.CharField(max_length=16)
one = models.ForeignKey(OnlyOne)
factories.py
import factory
import factory.fuzzy
from bug.models import MainModel
from bug.models import OnlyOne
class OnlyOneFactory(factory.DjangoModelFactory):
class Meta(object):
model = OnlyOne
name = factory.Sequence(lambda n: 'OnlyOne {}'.format(n))
class MainModelFactory(factory.DjangoModelFactory):
class Meta(object):
model = MainModel
name = factory.Sequence(lambda n: 'MainModel {}'.format(n))
one = factory.SubFactory(OnlyOneFactory, name='Initial Name')
So I want the Subfactory to set OnlyOnes' name always to Initial Name. As of the documentation this is how to do it (see example here ):
one = factory.SubFactory(OnlyOneFactory, name='Initial Name')
Now I have written some basic tests to test that the name of OnlyOne is set correctly. And it is if I use the factory build and/or create method, but however not if I use the LazyFixture.
test_factories.py:
"""Test the factories."""
import pytest
@pytest.mark.django_db
def test_main_model_factory__create(main_model_factory):
"""Test if the MainModelFactory.create() works properly."""
main_model = main_model_factory.create()
assert main_model.one.name == 'Initial Name'
@pytest.mark.django_db
def test_main_model_factory__build(main_model_factory):
"""Test if the MainModelFactory.build() works properly."""
main_model = main_model_factory.build()
assert main_model.one.name == 'Initial Name'
@pytest.mark.django_db
def test_main_model_fixture(main_model):
"""Test if the MainModelFactory shortcut works properly."""
assert main_model.one.name == 'Initial Name'
Test output is the following:
pytest
=========================================================== test session starts ============================================================
platform linux2 -- Python 2.7.12+, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
django settings: factoryboy_subfactory_attribute_bug.settings (from ini file)
rootdir: /home/daniel/workspace/private/factoryboy_subfactory_attribute_bug/factoryboy_subfactory_attribute_bug, inifile: pytest.ini
plugins: bdd-2.18.0, factoryboy-1.1.6, django-2.9.1, timeout-1.0.0, blockage-0.2.0, cov-2.4.0
collected 3 items
bug/tests/test_factories.py ..F
================================================================= FAILURES =================================================================
_________________________________________________________ test_main_model_fixture __________________________________________________________
main_model = <MainModel: MainModel object>
@pytest.mark.django_db
def test_main_model_fixture(main_model):
"""Test if the MainModelFactory shortcut works properly."""
> assert main_model.one.name == 'Initial Name'
E assert 'OnlyOne 2' == 'Initial Name'
E - OnlyOne 2
E + Initial Name
bug/tests/test_factories.py:22: AssertionError
==================================================== 1 failed, 2 passed in 0.32 seconds ====================================================
The question now is should it set the name as expected or am I misunderstanding the functionality of the LazyFixture used?
I am attaching a sample.tar.gz with a working django app to simulate this.
sample.tar.gz
Thanks for the help.
Edit: If you need any further information please feel free to ask. Sorry if something is missing I am new to submitting Issues on an open source project.
Hi,
I'd like to parametrize use of a Factoryboy Trait. But i don't see my Traits when i list my fixtures, so i get there is something missing here.
I honestly don't know if that would even be possible, so if it's not, please explain why ;)
Thanks
Using pytest-factoryboy with the newest pytest currently generates a lot of deprecation warnings. This is fixed in #62, but hasn't been released on pypi yet. Could you please create a new release?
Here are my models:
from typing import List
from mypy_extensions import TypedDict
class WakatimeCommit(TypedDict):
"""Class to represent a single Wakatime commit instance from API. """
hash: str
author_email: str
class WakatimeCommitsResponse(TypedDict):
"""Class to represent Wakatime response from commits API."""
commits: List[WakatimeCommit]
And my factories:
import factory
from pytest_factoryboy import register
@register
class WakatimeCommitFactory(factory.BaseDictFactory):
"""
Fake factory for a single Wakatime commit entry.
Note:
This class is marked as protected and is not registered,
since we do not actually need a single commit in tests.
"""
class Meta(object):
model = WakatimeCommit
hash = '123abc'
author_email = '[email protected]'
@register
class WakatimeCommitsResponseFactory(factory.BaseDictFactory):
"""Fake factory for Wakatime `/commits` response."""
class Meta(object):
model = WakatimeCommitsResponse
commits = factory.List([
factory.SubFactory(WakatimeCommitFactory) for _ in range(10)
])
And finally my test:
def test_pipeline_for_opened_valid_mr(
wakatime_commits_response,
):
"""
Tests the whole process of adding spent time to a merge request.
All requests are mocked, everything returns valid responses.
"""
print(wakatime_commits_response)
assert 1 == 2
This tests fails due to unresolved fixtures:
def test_pipeline_for_opened_valid_mr(
file <string>, line 2: source code not available
file <string>, line 2: source code not available
E fixture 'list' not found
> available fixtures:
...
wakatime_commit, wakatime_commit__author_email, wakatime_commit__hash, wakatime_commit__total_seconds, wakatime_commit_factory, wakatime_commits_response, wakatime_commits_response__commits, wakatime_commits_response_factory
...
I guess this happens due to the fact that I am using factory.List
.
class WakatimeCommitsResponseFactory(factory.BaseDictFactory):
...
@factory.post_generation
def commits(self, create, extracted, **kwargs):
if extracted:
self['commits'] = extracted
else:
self['commits'] = []
for _ in range(10):
self['commits'].append(WakatimeCommitFactory.build())
It appears that when processing SubFactory
attributes on the parent factory and generating deps for the SubFactory fixture, the introspected names do not take into account whether a given factory was registered earlier with a different model_name
.
This gist demonstrates a failing test where the generated SubFactory fixture is expecting to find a b_model__name
fixture when the one available is actually named b_model_with_some_other_name__name
.
https://gist.github.com/ryancausey/904ad5b77349769d32c72d413dd79a59
I think the root cause of all the issues I'm experiencing can be boiled down to this. This generally shows up when a second factory class is created from a parent subclass. Using the documentation's AuthorFactory
as an example:
class BobAuthorFactory(AuthorFactory):
name = "Bob"
register(BobAuthorFactory, "author_bob")
If we create a second BookFactory
subclass that uses BobAuthorFactory
as the SubFactory
:
class BobBookFactory(BookFactory):
author = factory.SubFactory(BobAuthorFactory)
register(BobBookFactory, "book_bob")
Then any use of book_bob
will actually end up using the original author
fixture and end up with an author whose name is "Charles Dickens" based on the docs at the time of this writing.
It doesn't appear that there's an easy fix for register
to be able to look up what model_name
a given factory class was registered with so I don't have a good answer on how to fix this right now.
I may be missing something, but I am having trouble registering a "partial specialization" fixture for a factory with a ManyToMany
field.
I tried using [the example in factoryboy docs][1], combined with the example in fixture attributes, but it throws TypeError: int() argument must be a string or a number, not 'LazyFixture'
. Is this something we can even do?
Here's a test case:
class UserFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.User
name = "John Doe"
@factory.post_generation
def groups(self, create, extracted, **kwargs):
if not create:
# Simple build, do nothing.
return
if extracted:
# A list of groups were passed in, use them
for group in extracted:
self.groups.add(group)
register(UserFactory, "special_user", groups=[LazyFixture("group")])
Hi
I try this and 'navigator' parameter is not overrided by the 'yoshi' fixture...
Is this valid code?
@pytest.mark.parametrize('navigator', [LazyFixture("yoshi")])
@given('I am on the Registration Page')
def i_am_on_the_registration_page(navigator):
"""I am on the Registration Page."""
navigator.load_index().login().load_registration()
I have the following fixtures:
@pytest.yield_fixture(scope='session')
def db_url():
with testing.postgresql.Postgresql() as db:
yield db.url()
@pytest.yield_fixture
def db(db_url):
"""Create a database session."""
engine = sqlalchemy.create_engine(db_url)
models.metadata.create_all(engine)
factories.Session.configure(bind=engine)
session = factories.Session() # creates the thread local session used by factories
yield session
session.rollback()
factories.Session.remove() # disables the thread local session
models.metadata.drop_all(engine)
pytest_factoryboy.register(factories.BookFactory)
My problem now is that trying to use the book_factory
fixture on its own doesn't work; I need the db
fixture to open a session the factory can use, first.
I'd like to be able to specify something like
pytest_factoryboy.register(factories.BookFactory, depends_on=['db'])
which would have the same effect as the manual implementation of
def book_factory(db):
# …
would.
It seems only the _create
of the parent class (factory.django.DjangoModelFactory._create
) is called when using a pytest-factoryboy
fixture in a test. Using the Factory() class directly works fine (does indeed call the Factory._create
classmethod).
I'll try to add a test case, but it will require adding a bunch of new requirements if we want to test it for a real Django model factory.
Example:
# models
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=1000)
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE)
text = models.TextField()
# conftest.py
class CommentFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Comment
article = factory.SubFactory("tests.conftest.ArticleFactory")
text = faker.text()
class ArticleFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.Article
title = faker.sentence(nb_words=4)
# This only returns 1 comment if loaded through pytest-factoryboy
comment_set = factory.RelatedFactoryList(CommentFactory, "article", size=5)
@pytest.fixture()
def article1():
yield ArticleFactory()
register(CommentFactory)
register(ArticleFactory)
# Tests
@pytest.mark.django_db
class TestComments:
def test_fails_to_create_5_comments(self, graphql_client, article):
assert article.comment_set.count() == 5 # fails, always returns 1
def test_creates_5_comments(self, graphql_client, article1):
assert article1.comment_set.count() == 5
No parameters are generated for model-only parameters. We often have Django model defaults which we don't override in factories, but do override in tests. For example:
class Book(models.Model):
title = models.CharField(max_length=255, default='My title')
class BookFactory(factory.DjangoModelFactory):
class Meta:
model = Book
register(BookFactory)
@pytest.mark.django_db
@pytest.mark.parametrize('book__title', ['My other title'])
def test_title(book):
assert book.title == 'My other title'
This results in ValueError: <function test_title at 0x7efe970a2488> uses no fixture 'book__title'
If I add the title to the BookFactory it does work.
Result of pip freeze:
Django==1.9.6
factory-boy==2.7.0
fake-factory==0.5.7
inflection==0.3.1
ipaddress==1.0.16
py==1.4.31
pytest==2.9.1
pytest-django==2.9.1
pytest-factoryboy==1.1.6
python-dateutil==2.5.3
six==1.10.0
import factory
from pytest_factoryboy import register
@register
class AuthorFactory(factory.Factory):
class Meta:
model = Author
name = "Charles Dickens"
def test_model_fixture(author):
assert author.name == "Charles Dickens"
Get error '"author" is not found', only works with author_factory
As seen in travis fails here:
https://travis-ci.org/pytest-dev/pytest-factoryboy/jobs/552058354
Support drop of pytest < 3.6 is mentioned in pytest-cov release notes here: https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst#260-2018-09-03
We can either peg pytest-cov in our
to e.gpytest-cov<2.6
; or, we can drop support for pytest < 3.6 as well, in our travis/tox configurations.
Since last release was a while ago, I lean towards the latter, with a 2.1 release noting this breaking change.
What say you @pytest-dev ?
When trying to use pytest-factoryboy
with newest pytest, exception occurs:
____________________________________________________________________ ERROR at setup of test_asdf ____________________________________________________________________
request = <SubRequest 'xyz' for <Function 'test_asdf'>>, factory_name = 'xyz_factory'
def model_fixture(request, factory_name):
"""Model fixture implementation."""
factoryboy_request = request.getfuncargvalue("factoryboy_request")
# Try to evaluate as much post-generation dependencies as possible
factoryboy_request.evaluate(request)
factory_class = request.getfuncargvalue(factory_name)
prefix = "".join((request.fixturename, SEPARATOR))
data = {}
for argname in request._fixturedef.argnames:
if argname.startswith(prefix) and argname[len(prefix):] not in factory_class._meta.postgen_declarations:
data[argname[len(prefix):]] = request.getfuncargvalue(argname)
class Factory(factory_class):
@classmethod
def attributes(cls, create=False, extra=None):
return dict(
(key, evaluate(request, value))
for key, value in super(Factory, cls).attributes(create=create, extra=extra).items()
if key in data
)
Factory._meta.postgen_declarations = {}
Factory._meta.exclude = [value for value in Factory._meta.exclude if value in data]
# Extract post-generation context
post_decls = []
if factory_class._meta.postgen_declarations:
for attr, decl in sorted(factory_class._meta.postgen_declarations.items()):
post_decls.append((attr, decl, decl.extract(attr, data)))
# Create model fixture instance
instance = Factory(**data)
request._fixturedef.cached_result = (instance, None, None)
> request._fixturedefs[request.fixturename] = request._fixturedef
E AttributeError: SubRequest instance has no attribute '_fixturedefs'
<snip>/lib/python2.7/site-packages/pytest_factoryboy/fixture.py:200: AttributeError
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.