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

The --use-existing-database option does not wrap scenarios in transactions #51

Open
richard-reece opened this issue Dec 29, 2017 · 5 comments

Comments

@richard-reece
Copy link

richard-reece commented Dec 29, 2017

The --use-existing-database option is invaluable for running against an existing database, but it does not roll back changes after each scenario runs. This means scenarios touching the same table may collide.

@bittner
Copy link
Member

bittner commented Dec 29, 2017

Thanks for the feedback, Richard! I agree, rolling back changes would be nice.

I may disclose that this option has not been envisioned for rolling back changes. When I added it to the feature set it was for a trouble-shooting use case against a copy of a production system, with a workflow like this:

  1. Pull static files and database from production system to development environment
  2. Run tests to verify a malicious behavior can be reproduced
  3. Repeat the two steps above with adaptions to tests and application code

When 1. is fully scripted this should be acceptable as a development workflow for trouble-shooting.

If you feel like the problem is worth getting your hands dirty, please place a pull request. Thanks!

@richard-reece
Copy link
Author

Thanks for the response!

Our use case is that we have a legacy database schema that we have to run our tests over (not a complete database, just the schema). The schema is very much owned by other parties in the organisation, and we Django developers are just one of many consumers, but also due to eccentricities in the database we can't get Django models to 100% describe the schema. It's far easier to just set up a self-contained docker image that's updated with the production schema on a nightly basis. That means we need to disable any sort of database creation/migration, but we also need test encapsulation so we need any changes made during a test are rolled back.

I'm trying to figure how to do this nicely, but for now we have a combination of --use-existing-database (so the database is used untouched at startup) and then the following in an after_scenario() function:

call_command('flush', verbosity=0, interactive=False, database='default', inhibit_post_migrate=True)

It's a bit too manual for my tastes (also entirely destructive, which is fine for me but might not work for others 😄 ), and I'd like to hear your opinion about how this might be done better in the behave-django environment. What I'm really after is:

  1. the behaviour of the django test command switch --keepdb which accepts a database is created, but performs transactional rollbacks after each test (scenario), and
  2. the added --nomigrations that pytest-bdd includes which prevents any application of migrations to the existing database (this functionality can be provided by https://github.com/henriquebastos/django-test-without-migrations/ though.)

I'm not asking you to do the work, just thoughts. I am continuing to investigate and am always happy to provide a PR if I'm able.

@mixxorz
Copy link
Collaborator

mixxorz commented Jan 15, 2018

I'm not sure I completely understand the situation, but have you tried using --keepdb and explicitly configuring the test database you want to use?

https://docs.djangoproject.com/en/2.0/topics/testing/overview/#the-test-database

@richard-reece
Copy link
Author

The --keepdb option is only part of the solution (it prevents teardown of the database after the tests) - Django will still attempt to perform migrations before the tets without something like the --nomigrations option that pytest-bdd implements.

@rodrigondec
Copy link

rodrigondec commented Aug 2, 2021

This problem seems too specific for me.

I don't think the lib could solve your pain in a re-utilizable manner without breaking the Django behavior.

What I can say it's that with #122 and #123 you should have more power to customize how your tests should run.

I would recommend using the flag --simple to use the TestCase. Consequently rollback support. You just need to overwrite some other operations from django to disable the migrations.

Dig around on the Django source code may be good.

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

No branches or pull requests

4 participants