-
Notifications
You must be signed in to change notification settings - Fork 42
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
Factory.build fixtures #56
Comments
@olegpidsadnyi any thoughts on this? A sensible defacto way of retrieving build/unsaved models would replace a bunch of stuff in the suite I'm currently working on – and I'd rather not write a fixture for each model – is there a way to do this already or would adding a pre/suffixed fixture name be the way to go here? |
A few further thoughts
A suffix or a decorator to adjust how the factory works for the test in question seems like the way to go but I am wondering if we can do better |
@stevelacey it is more like what kind of base factory are you using, right? What kind of ORM is it in your case. I guess there's a difference between build and create, but if you have a non-db model, what kind of difference does it make? Could you please describe your setup? |
I don’t have anything irregular, we’re talking totally normal Django here
I am just trying to write faster tests that don’t touch the database when they don’t need to
In FactoryBot (Ruby) the way you do this is using a `build` or `build_stubbed` call, instead of `create`
Obviously, that call is implicit here via the model fixtures, but FactoryBoy does mirror that `build` and `create` distinction on factories – these tests can be written by injecting factory fixtures instead of model fixtures everywhere, and explicitly calling build – but I am wondering if we can do better
|
This is very good idea. I try another case, byt this is not work. Normally in FactoryBoy we have
|
I did a lot more work on top of pytest-factoryboy since I suggested this -
but I still don’t have an elegant solution to this
I think a great implementation would be an extension of the factory_boy’s
use_strategy as a decorator that would be applied to a test definition and
apply use_factory to the factory fixture as well as the factory instance
used to generate the model fixture before it is passed into the test
If that worked, it would basically mean you can use the regular model
fixtures but they wouldn’t do db in that test only
You’d be able to use the stub strategy this way too, which might be handy
to some
The feasibility of doing that? Very difficult, and maybe infeasible, was
the conclusion I made last time I looked into this
…On Fri, 30 Mar 2018 at 05:29, witold ***@***.***> wrote:
This is very good idea. I try another case, byt this is not work. Normally
in FactoryBoy we have strategy in class Meta. If I set BUILD_STRATEGY and
usage fixture_factory and call to them, this fixture connect with my db.
This is not intuitive..
def test_something(my_model_factory):
my_model_factory() # <- this call db
my_model_factory.build(). # <- this not call db
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#56 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARq-2C5LgUIHwjd4r4gxyNwa5yZU5vkks5tjWBRgaJpZM4Rlenv>
.
|
Wouldn't the following work? Generate these fixtures: @pytest.fixture
def derive_factory_strategy(): # or call it factory_strategy_strategy ;)
def derive(factory_class):
return factory_class._meta.strategy
return derive
@pytest.fixture
def {factory_name}__strategy(derive_factory_strategy):
strategy = derive_factory_strategy(factory_class)
...
@pytest.yield_fixture
def {factory_name}({factory_name}__strategy):
# - Setting TheFactory._meta.strategy is basically all use_strategy does.
# I'm not using it as I have to get the _meta.strategy so that
# I can reset it later and there's no public function for that that I know of.
# - You could also use the pytest builtin monkeypatch.setattr to temporarily
# change the strategy.
# (It's necessary to change it back as the factory is the actual factory
# class, which isn't isolated across tests)
default_strategy = foo_factory._meta.strategy
foo_factory._meta.strategy = {factory_name}__strategy
yield foo_factory
# yield_fixture catches exceptions for us, no need for try: finally:
foo_factory._meta.strategy = default_strategy The user can now globally override the desired strategy, e.g. to derive from presence of a db fixture the user could write: @pytest.fixture
def derive_factory_strategy(request):
def derive(factory_class):
if 'db' in request.fixturenames:
return factory.CREATE_STRATEGY
else:
return factory.BUILD_STRATEGY If a user wants to override a single FooFactory's strategy, they can override the |
Might be worth adding fixtures for creating models with
build
instead ofcreate
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?Automatically registering fixtures like
asset_build
or similar might be a way to go. Thoughts?The text was updated successfully, but these errors were encountered: