Skip to content

django_db_serialized_rollback does not reset to previous db state #1062

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

Open
Eraldo opened this issue May 8, 2023 · 4 comments
Open

django_db_serialized_rollback does not reset to previous db state #1062

Eraldo opened this issue May 8, 2023 · 4 comments

Comments

@Eraldo
Copy link

Eraldo commented May 8, 2023

Problem description

Ever since I added the live_server to my tests, other tests started to fail, that did previously pass.

Details

The fixture to setup my browser with live_server support:

@pytest.fixture
def live_browser(browser, live_server, django_db_serialized_rollback) -> WebDriver:
    return browser

Example of how I use that fixture:

def test_some_case(live_browser):
    pass

The test that fails when (and after) using the live_server fixture:

def test_user_get_absolute_url(user: User):
    assert user.get_absolute_url() == escape_uri_path(
        f"http://mydomain.com/users/{user.id}"
    )

Context infos:
I am using --reuse-db as part of my pytest.ini file.

Problem Analysis

I understand this happens due to improper reset (flush) of the test database after any test using the live_server fixture.

I did some research and found this issue: #329

This lead me back to the docs of pytest-django where I payed closer attention and found django_db_serialized_rollback: https://pytest-django.readthedocs.io/en/latest/helpers.html#std-fixture-django_db_serialized_rollback
As I understand it, this would in theory restore the content of the test database after a test that uses my fixture.

However this does either not seem to be the case, or not work as expected.

The user.get_absolute_url() uses the django.contrib Site model, for which I have a data migration.
The content seems to get flushed in the tests using live_server and never get restored.
Running only the broken test again after running my full test suit, still fails until I recreate the test database manually.

Solution ideas / requests

Workaround: Removing --reuse-db.
Sadly this is the only reliable way I found so far to get my test to work again.
And even then I need to run pytest twice once excluding the tests using live_server and then running them separately.
Obviously this is considerably slowing down the (TDD) testing process.

At this point I don't really have any proper solution ideas.
I would be happy to clarify any misunderstandings I have,
and maybe even discuss potential solution ideas
(or at least better workarounds). 😊

If I can provide further context to clarify the issue and use case, I'll gladly provide it.
Looking forward to hearing some feedback. 😅

@Eraldo
Copy link
Author

Eraldo commented May 8, 2023

I might have misunderstood the application of the django_db_serialized_rollback fixture.
Am I supposed to do it the other way around?:
Removing django_db_serialized_rollback from the live_browser fixture and adding it to the test_user_get_absolute_url test?

I was hoping I could restore the migration data after running my live_server tests. 🤔
Since these tests are the ones breaking the migration data, it would make more sense to me to fix the db there.

@Tubo
Copy link

Tubo commented Jan 27, 2024

I came across this issue as well, that after adding a live_server test case to my suite, all my other tests started to fail.

My investigation suggest this was not a pytest-django problem, but a django problem. This was first raised in 2015, and here's a summary https://code.djangoproject.com/ticket/25251#comment:38. Essentially LiveServerTestCase is a child of TransactionTestCase, which flushes all data after it finishes, including data migrations.

The same author who summarised the issue in the above link also made a pull request here django/django#14147 but unfortunately it wasn't merged.

If you're using pytest, one solution would be to add --create-db option. Although it defeats the purpose of --reuse-db, at least your tests will now pass consistently.

@mbegoc
Copy link

mbegoc commented Feb 3, 2024

Just running into the same problem and lost 2 days trying to understand what's going on. Didn't know about the serialized_rollback and thought it would solve my problem, but it runs the deserialization before the test run, while I was expecting it to run as a teardown of the test.
So what, we are supposed to emulate the rollback on the next test when it's the one that disable transaction rollback that flush the database in the first place?
Plus, I have no garantee the tests will run in a specific order.
I'm so puzzled.

Anto59290 added a commit to betagouv/seves that referenced this issue Jun 21, 2024
Ce commit s'assure que tous les tests E2E de l'application soient OK
qu'ils soient lancés individuellement ou dans leur ensemble.

- Certains tests sont supprimés car les features n'existent plus
- Correction id en double dans le HTML
- Correcton des coordonnées manquantes dans le formulaire
- Utilisation de `serialized_rollback=True` pour s'assurer que les
  données créés dans les migrations soient toujours présentent pour les
autre tests
- Ajout d'utilitaire pour créer des fiches détections plus facilement

pytest-dev/pytest-django#1062
pytest-dev/pytest-django#970
pytest-dev/pytest-django#329
Anto59290 added a commit to betagouv/seves that referenced this issue Jun 26, 2024
Ce commit s'assure que tous les tests E2E de l'application soient OK
qu'ils soient lancés individuellement ou dans leur ensemble.

- Certains tests sont supprimés car les features n'existent plus
- Correction id en double dans le HTML
- Correcton des coordonnées manquantes dans le formulaire
- Utilisation de `serialized_rollback=True` pour s'assurer que les
  données créés dans les migrations soient toujours présentent pour les
autre tests
- Ajout d'utilitaire pour créer des fiches détections plus facilement

pytest-dev/pytest-django#1062
pytest-dev/pytest-django#970
pytest-dev/pytest-django#329
@mcosti
Copy link

mcosti commented Aug 29, 2024

I am running into the same issue as everyone above

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

4 participants