From 0ca9271a749a18cb4ff4c0a255da054b25c14565 Mon Sep 17 00:00:00 2001 From: Heinz-Alexander Fuetterer Date: Wed, 24 Jul 2024 10:46:39 +0200 Subject: [PATCH] test: improve test performance --- conftest.py | 19 +- .../tests/test_viewset_condition.py | 2 +- .../tests/test_viewset_condition_multisite.py | 2 +- rdmo/domain/tests/test_viewset_attribute.py | 2 +- .../tests/test_viewset_attribute_multisite.py | 2 +- .../test_viewset_optionsets_multisite.py | 33 ++-- rdmo/projects/tests/test_view_project.py | 179 +++++++++--------- rdmo/questions/tests/test_viewset_catalog.py | 2 +- .../tests/test_viewset_catalog_multisite.py | 49 +++-- rdmo/questions/tests/test_viewset_page.py | 45 ++--- .../tests/test_viewset_page_multisite.py | 5 +- 11 files changed, 187 insertions(+), 153 deletions(-) diff --git a/conftest.py b/conftest.py index 5dbd3652e6..b1dc53ddfa 100644 --- a/conftest.py +++ b/conftest.py @@ -50,7 +50,24 @@ def files(settings, tmp_path): return settings.MEDIA_ROOT -@pytest.fixture +@pytest.fixture(scope='session') def json_data(): json_file = Path(settings.BASE_DIR) / 'import' / 'catalogs.json' return {'elements': json.loads(json_file.read_text())} + + +@pytest.fixture +def mocked_convert_text(mocker): + """Mock the pypandoc.convert_text function. + + `mocked_convert_text` can be used in tests of the export views. + Use it to assert pypandoc would have been called with: + mocked_convert_text.assert_called(), mocked_convert_text.assert_called_once() or + mocked_convert_text.assert_called_once_with(). + + See: + - + - + """ + from rdmo.core.utils import pypandoc # noqa: F401 + return mocker.patch("pypandoc.convert_text") diff --git a/rdmo/conditions/tests/test_viewset_condition.py b/rdmo/conditions/tests/test_viewset_condition.py index efae4659ca..8ec9626c7c 100644 --- a/rdmo/conditions/tests/test_viewset_condition.py +++ b/rdmo/conditions/tests/test_viewset_condition.py @@ -285,7 +285,7 @@ def test_delete(db, client, username, password): @pytest.mark.parametrize('username,password', users) @pytest.mark.parametrize('export_format', export_formats) -def test_detail_export(db, client, username, password, export_format): +def test_detail_export(db, client, username, password, export_format, mocked_convert_text): client.login(username=username, password=password) instance = Condition.objects.first() diff --git a/rdmo/conditions/tests/test_viewset_condition_multisite.py b/rdmo/conditions/tests/test_viewset_condition_multisite.py index 6d1f0da587..0041b678f9 100644 --- a/rdmo/conditions/tests/test_viewset_condition_multisite.py +++ b/rdmo/conditions/tests/test_viewset_condition_multisite.py @@ -32,7 +32,7 @@ def test_index(db, client, username, password): @pytest.mark.parametrize('username,password', users) @pytest.mark.parametrize('export_format', export_formats) -def test_export(db, client, username, password, export_format): +def test_export(db, client, username, password, export_format, mocked_convert_text): client.login(username=username, password=password) url = reverse(urlnames['export']) + export_format + '/' diff --git a/rdmo/domain/tests/test_viewset_attribute.py b/rdmo/domain/tests/test_viewset_attribute.py index 00c7c71310..69b33b5b33 100644 --- a/rdmo/domain/tests/test_viewset_attribute.py +++ b/rdmo/domain/tests/test_viewset_attribute.py @@ -54,7 +54,7 @@ def test_list(db, client, username, password): @pytest.mark.parametrize('username,password', users) @pytest.mark.parametrize('export_format', export_formats) -def test_export(db, client, username, password, export_format): +def test_export(db, client, username, password, export_format, mocked_convert_text): client.login(username=username, password=password) url = reverse(urlnames['export']) + export_format + '/' diff --git a/rdmo/domain/tests/test_viewset_attribute_multisite.py b/rdmo/domain/tests/test_viewset_attribute_multisite.py index 39bd7a663e..ee27a1c140 100644 --- a/rdmo/domain/tests/test_viewset_attribute_multisite.py +++ b/rdmo/domain/tests/test_viewset_attribute_multisite.py @@ -110,7 +110,7 @@ def test_delete_multisite(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_detail_export(db, client, username, password): +def test_detail_export(db, client, username, password, mocked_convert_text): client.login(username=username, password=password) instances = Attribute.objects.all() diff --git a/rdmo/options/tests/test_viewset_optionsets_multisite.py b/rdmo/options/tests/test_viewset_optionsets_multisite.py index 55bd2a30eb..21e3d3953a 100644 --- a/rdmo/options/tests/test_viewset_optionsets_multisite.py +++ b/rdmo/options/tests/test_viewset_optionsets_multisite.py @@ -11,9 +11,18 @@ from ..models import OptionSet from .test_viewset_optionsets import urlnames +pytestmark = pytest.mark.django_db + + +@pytest.fixture(scope="module") +def instances(django_db_blocker): + """Returns a queryset of all `OptionSet` objects in the test database, queries only once.""" + with django_db_blocker.unblock(): + return OptionSet.objects.all() + @pytest.mark.parametrize('username,password', users) -def test_list(db, client, username, password): +def test_list(client, username, password): client.login(username=username, password=password) url = reverse(urlnames['list']) @@ -22,9 +31,8 @@ def test_list(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_detail(db, client, username, password): +def test_detail(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: url = reverse(urlnames['detail'], args=[instance.pk]) @@ -33,9 +41,8 @@ def test_detail(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_nested(db, client, username, password): +def test_nested(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: url = reverse(urlnames['nested'], args=[instance.pk]) @@ -44,7 +51,7 @@ def test_nested(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_index(db, client, username, password): +def test_index(client, username, password): client.login(username=username, password=password) url = reverse(urlnames['index']) @@ -53,7 +60,7 @@ def test_index(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_export(db, client, username, password): +def test_export(client, username, password): client.login(username=username, password=password) url = reverse(urlnames['export']) @@ -68,9 +75,8 @@ def test_export(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_create(db, client, username, password): +def test_create(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: url = reverse(urlnames['list']) @@ -86,9 +92,8 @@ def test_create(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_update_m2m_multisite(db, client, username, password): +def test_update_m2m_multisite(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: optionset_options = [{ @@ -119,9 +124,8 @@ def test_update_m2m_multisite(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_delete_multisite(db, client, username, password): +def test_delete_multisite(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: url = reverse(urlnames['detail'], args=[instance.pk]) @@ -130,9 +134,8 @@ def test_delete_multisite(db, client, username, password): @pytest.mark.parametrize('username,password', users) -def test_detail_export(db, client, username, password): +def test_detail_export(client, username, password, instances): client.login(username=username, password=password) - instances = OptionSet.objects.all() for instance in instances: url = reverse(urlnames['detail_export'], args=[instance.pk]) diff --git a/rdmo/projects/tests/test_view_project.py b/rdmo/projects/tests/test_view_project.py index b43660cf14..37bd857926 100644 --- a/rdmo/projects/tests/test_view_project.py +++ b/rdmo/projects/tests/test_view_project.py @@ -11,6 +11,8 @@ from ..forms import CatalogChoiceField from ..models import Project +pytestmark = pytest.mark.django_db + users = ( ('owner', 'owner'), ('manager', 'manager'), @@ -25,35 +27,35 @@ ) view_project_permission_map = { - 'owner': [1, 2, 3, 4, 5, 10], - 'manager': [1, 3, 5, 7], - 'author': [1, 3, 5, 8], - 'guest': [1, 3, 5, 9], - 'api': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - 'site': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + 'owner': {1, 2, 3, 4, 5, 10}, + 'manager': {1, 3, 5, 7}, + 'author': {1, 3, 5, 8}, + 'guest': {1, 3, 5, 9}, + 'api': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + 'site': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} } change_project_permission_map = { - 'owner': [1, 2, 3, 4, 5, 10], - 'manager': [1, 3, 5, 7], - 'api': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - 'site': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] + 'owner': {1, 2, 3, 4, 5, 10}, + 'manager': {1, 3, 5, 7}, + 'api': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + 'site': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} } delete_project_permission_map = { - 'owner': [1, 2, 3, 4, 5, 10], - 'api': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - 'site': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + 'owner': {1, 2, 3, 4, 5, 10}, + 'api': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + 'site': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, } export_project_permission_map = { - 'owner': [1, 2, 3, 4, 5, 10], - 'manager': [1, 3, 5, 7], - 'api': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - 'site': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + 'owner': {1, 2, 3, 4, 5, 10}, + 'manager': {1, 3, 5, 7}, + 'api': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + 'site': {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, } -projects = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +projects = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) export_formats = ('rtf', 'odt', 'docx', 'html', 'markdown', 'tex', 'pdf') @@ -63,7 +65,7 @@ @pytest.mark.parametrize('username,password', users) -def test_list(db, client, username, password): +def test_list(client, username, password): client.login(username=username, password=password) url = reverse('projects') @@ -75,7 +77,7 @@ def test_list(db, client, username, password): assert response.status_code == 200 # assertTemplateUsed(response, 'projects/projects.html') - if username in ('site', 'api'): + if username in {'site', 'api'}: assert projects == [] # assert response.context['number_of_projects'] == len([]) # assertContains(response, 'View all projects on') @@ -90,13 +92,13 @@ def test_list(db, client, username, password): @pytest.mark.parametrize('username,password', users) @pytest.mark.parametrize('project_id', projects) -def test_detail(db, client, username, password, project_id): +def test_detail(client, username, password, project_id): client.login(username=username, password=password) url = reverse('project', args=[project_id]) response = client.get(url) - if project_id in view_project_permission_map.get(username, []): + if project_id in view_project_permission_map.get(username, set()): assert response.status_code == 200 else: if password: @@ -106,7 +108,7 @@ def test_detail(db, client, username, password, project_id): @pytest.mark.parametrize('username,password', users) -def test_project_create_get(db, client, username, password): +def test_project_create_get(client, username, password): client.login(username=username, password=password) url = reverse('project_create') @@ -117,12 +119,12 @@ def test_project_create_get(db, client, username, password): # check the parent select dropdown for project_id in re.findall(r'