Closed urlsangel closed 12 months ago
Hey @urlsangel,
To be honest, I do not know š as I do not use pytest. Will try to have a read in the coming days.
Thanks @zerolab! š
Hi @zerolab - just getting back onto this now, did you get a chance to have a look at this issue?
Heh, did not get any breathing time to look into pytest. But I do have some dedicated Wagtail time this Friday and I aim to play with it
Awesome, Thanks @zerolab! š š
@urlsangel well.. Friday was more meetings-heavy than anticipated so did not get to this. Do you have a minimal test case that would help speed things up on this side?
Hi @zerolab
No problem - here's one of the tests that was failing, it's because of the MigrationRecorder
being called via TranslationSource
by the looks (see previous comment here: https://github.com/wagtail/wagtail-localize/issues/706#issue-1822513281):
import pytest
from wagtail_localize.models import (
Translation,
TranslationSource,
)
from ..service import _languages
from helpers.util import dummy_request
@pytest.mark.trans
def test_translate_pt_to_es(benchmark, client, tagged_article_pt):
og = tagged_article_pt
og.body = og.footer = og.excerpt = ''
new_lang = _languages.first(language_code='es')
source, created = TranslationSource.get_or_create_from_instance(og)
translation = Translation.objects.create(
source=source,
target_locale=new_lang,
)
translation.save_target()
np = og.get_translation(new_lang)
np.title = "Spanish translation of Portuguese page"
np.save_revision().publish()
res = benchmark(client.get, np.url)
assert res.status_code == 200
assert res is not None
assert "Spanish translation of Portuguese page" in res.rendered_content
The quick fix would be to wrap https://github.com/wagtail/wagtail-localize/blob/v1.4/wagtail_localize/models.py#L139 in a try/except.
But I most certainly want to understand a bit more as to how pytest does things and how it gets away with not running Django migrations
--nomigrations
is a feature of pytest-django, not pytest
https://pytest-django.readthedocs.io/en/latest/database.html#no-migrations-disable-django-migrations
Basically it just ignores all your migrations and generates the DB based on the current state of the DB model classes. I guess the theory is you don't need to re-play the entire migration history (including hand-written data backfills, etc) to just build an empty DB.
Thanks for the clarification @chris48s, I should have been clearer!
@zerolab - I don't think we can run our tests with migrations, so not sure if we can test code that uses TranslationSource
from wagtail-localize
with the current codebase?
Also, TIL this is something django can do out of the box, independent of pytest using the settings['TEST']['MIGRATE']
setting: https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-TEST_MIGRATE
Given that, it doesn't seem ridiculous to handle this.
For anyone finding this through search, pytest lets you monkeypatch stuff inside packages, and reading through the code that's accessing the table here it looks like in places it's happy to handle an empty string, so we're working around it for now by monkeypatching the get_schema_version
function in the tests that it breaks...
def _no_migrations_access(*args, **kwargs):
return ""
def test_article_share_header(benchmark, article_page, languages, monkeypatch):
# Monkey patch because wagtail_localize.models.get_schema_version tries to access
# the django migrations table which isn't guaranteed to exist
import wagtail_localize
monkeypatch.setattr(wagtail_localize.models, "get_schema_version", _no_migrations_access)
[...]
https://docs.pytest.org/en/7.1.x/how-to/monkeypatch.html#monkeypatching-functions
edit to add: A longer term, fairly simple fix, as @zerolab mentioned, would be to just pop a try / except inside that function, returning an empty string if table access fails.
def get_schema_version(app_label):
"""
Returns the name of the last applied migration for the given app label.
"""
try:
migration = (
MigrationRecorder.Migration.objects.filter(app=app_label)
.order_by("applied")
.last()
)
if migration:
return migration.name
except OperationalError:
return ""
return ""
however, I only use pytest, so I'm not sure if this fix would break something in UnitTest.
Amazing, thanks @zerolab
wagtail = "4.2" wagtail-localize = "^1.4"
We are running tests using
pytest
with the--nomigrations
flag and SQLite as the db backend.When running tests involving
TranslationSource.get_or_create_from_instance
, the tests fail with the following error:This looks like it's because
MigrationRecorder
is being used here:https://github.com/wagtail/wagtail-localize/blob/v1.4/wagtail_localize/models.py#L139
Is there a way around this for testing
TranslationSource
usingpytest
andSQLite
?