Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility issues with pytest-factoryboy #55

Closed
yashtodi94 opened this issue Aug 1, 2019 · 8 comments
Closed

Compatibility issues with pytest-factoryboy #55

yashtodi94 opened this issue Aug 1, 2019 · 8 comments

Comments

@yashtodi94
Copy link

Hello,

Thanks for creating this extremely useful plugin.

I get thrown an error when I try running pytest when 'pytest-cases' and 'pytest-factoryboy' both are installed.

The tests run fine if either 'pytest-cases' or 'pytest-factoryboy' is installed but not both.

What can be the issue?

platform darwin -- Python 3.7.0, pytest-5.0.1, py-1.8.0, pluggy-0.12.0
rootdir: /Users/yash/Sojern/python/campaigner
plugins: factoryboy-2.0.3, cases-1.10.1, cov-2.7.1, mock-1.6.3
collected 0 items / 1 errors                                                                                                                                                                                                                                            

================================================================================================================================ ERRORS =================================================================================================================================
_________________________________________________________________________________________________________ ERROR collecting campaigner/tests/test_parametrize.py _________________________________________________________________________________________________________
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/hooks.py:289: in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/manager.py:87: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/manager.py:81: in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/_pytest/python.py:225: in pytest_pycollect_makeitem
    res = list(collector._genfunctions(name, obj))
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/_pytest/python.py:401: in _genfunctions
    self.ihook.pytest_generate_tests(metafunc=metafunc)
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/hooks.py:289: in __call__
    return self._hookexec(self, self.get_hookimpls(), kwargs)
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/manager.py:87: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pluggy/manager.py:81: in <lambda>
    firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:125: in pytest_generate_tests
    metafunc.fixturenames.extend(related)
E   AttributeError: 'FixtureClosureNode' object has no attribute 'extend'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================================================================================================== 1 error in 0.39 seconds ========================================================================================================================
@smarie
Copy link
Owner

smarie commented Aug 1, 2019

This is unfortunately a limitation of changing the whole fixture system but not merging back this feature into pytest. pytest-cases is used as an experiment to validate the new features of fixture unions and fixture references, but this requires a drastic change of the way fixture closures are computed. Currently I do this without pytest knowing about it, by replacing metafunc.fixturenames, which was a list, with a tree representing alternative branches to run, each with its own fixture closure. Of course here the pytest_factoryboy plugin does not know about it, but it tries to extend the list: that fails.

I can try to provide a fix, but to do this I have to better understand what factoryboy is trying to do here. Can you provide me with an example test where the factoryboy functionality is actually used ?

For the long term, if you actually use the fixture reference and/or fixture unions feature a lot, please ask for it to be considered into pytest in pytest-dev/pytest#349

@yashtodi94
Copy link
Author

The tests don't matter. The mere existence of pytest-factoryboy being installed itself leads to this error irrespective of the test(s) I try to run (even for the tests where I am not using factoryboy at all)

@smarie
Copy link
Owner

smarie commented Aug 1, 2019

I know but... to fix it it matters :)

Indeed the only thing I can do right now is to cancel everything pytest-factoryboy does. This cancellation will be done for all of your pytest sessions, even if you do not use pytest-cases in them!. So you probably do not want that: it would be similar to asking you to uninstall factoryboy, but it would be less obvious.

Since I have no idea of how factoryboy works, could you help me with providing an extremely tiny example of a test using it ? That way, the related list that I will receive in the extend method (the one crashing right now because not implemented by my object) will not be empty:

/Users/yash/.virtualenvs/campaigner/lib/python3.7/site-packages/pytest_factoryboy/plugin.py:125: in pytest_generate_tests
    metafunc.fixturenames.extend(related)

(you can even check that it is not empty before posting, by putting a breakpoint on that line)

Thanks a lot for your help ! Then I'll be able to investigate

@yashtodi94
Copy link
Author

As it turns out, pytest-cases was of more value to me rather than pytest-factoryboy so I did uninstall the latter. :P

But for this issue's sake, you can consider the test from here

import factory
from pytest_factoryboy import register

class AuthorFactory(factory.Factory):

    class Meta:
        model = Author


register(AuthorFactory)


def test_factory_fixture(author_factory):
    author = author_factory(name="Charles Dickens")
    assert author.name == "Charles Dickens"

@smarie
Copy link
Owner

smarie commented Aug 2, 2019

Thanks ! Unfortunately this example does not work (NameError: Author is not defined) and I have no idea from the doc how to make it work. I tried to replace it with a string : model = 'Author' but that does not work either.

If you are familiar with the project, can you please guide me here ?
In the meantime I fixed at least part of the issue: I now tolerate that factoryboy tries to add an empty list of fixtures to the fixture tree.

@smarie smarie closed this as completed in d520f81 Aug 2, 2019
@yashtodi94
Copy link
Author

@smarie

I tested it again with pytest-cases v1.11.1. The problem seems that my fixtures are in conftest.py and tests are in various test files. In all the examples considered, the fixtures and tests existed in the same file which is not the practical case in my project.

@smarie
Copy link
Owner

smarie commented Aug 8, 2019

I do not understand what you mean, sorry :) . Do you mean that the issue is not actually solved by 1.11.1 and should be reopened ? If so please provide a reproducible example.

Otherwise, could you still provide a reproducible example of pytest-factoryboy ? as mentioned above, I did not manage to reproduce your example.

Thanks a lot, I really can't start to work on fixing anything if I have no means to reproduce, and as of now I am quite unable to reproduce any of the scenarios you mention (except the one that I fixed, where factoryboy was not used at all so the fix was trivial).

@smarie
Copy link
Owner

smarie commented Sep 5, 2019

I realized that my fix was never released, I do not know what happened in my mind that day... the version I was mentioning was 1.11.2. Very sorry for that, I'll release it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants