Skip to content

Commit

Permalink
⚡️ improve test performance with pytest-xdist
Browse files Browse the repository at this point in the history
  • Loading branch information
krmax44 committed Nov 18, 2024
1 parent 484ca10 commit 7a1b9aa
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:
run: pnpm run build
- name: Run tests
run: |
coverage run --branch -m pytest froide/
make test
coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
env:
DATABASE_URL: postgis://postgres:postgres@localhost/froide
Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ export DJANGO_SETTINGS_MODULE=froide.settings
export DJANGO_CONFIGURATION=Test
export PYTHONWARNINGS=default

lint:
pre-commit run --all

test:
ruff check
coverage run --branch -m pytest froide/
coverage report
pytest --cov froide -n auto -m "not elasticsearch"
pytest --cov froide --cov-append -m "elasticsearch"

testui:
coverage run --branch -m pytest --browser chromium froide/tests/live/
Expand Down
1 change: 1 addition & 0 deletions froide/foirequest/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def test_search(self):
response = self.client.get("/api/v1/request/search/?q=Number")
self.assertEqual(response.status_code, 200)

@pytest.mark.elasticsearch
def test_search_similar(self):
factories.delete_index()
search_url = "/api/v1/request/search/"
Expand Down
8 changes: 8 additions & 0 deletions froide/foirequest/tests/test_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ def test_request_prefilled_redirect(world, client):


@pytest.mark.django_db
@pytest.mark.elasticsearch
def test_list_requests(world, client):
factories.rebuild_index()
response = client.get(reverse("foirequest-list"))
Expand All @@ -117,6 +118,7 @@ def test_list_requests(world, client):
assert response.status_code == 404


@pytest.mark.elasticsearch
@pytest.mark.django_db
def test_list_jurisdiction_requests(world, client):
factories.rebuild_index()
Expand Down Expand Up @@ -151,6 +153,7 @@ def test_list_jurisdiction_requests(world, client):


@pytest.mark.django_db
@pytest.mark.elasticsearch
def test_tagged_requests(world, client):
tag_slug = "awesome"
req = FoiRequest.published.all()[0]
Expand All @@ -170,6 +173,7 @@ def test_tagged_requests(world, client):


@pytest.mark.django_db
@pytest.mark.elasticsearch
def test_publicbody_requests(world, client):
factories.rebuild_index()
req = FoiRequest.published.all()[0]
Expand All @@ -188,6 +192,7 @@ def test_publicbody_requests(world, client):


@pytest.mark.django_db(transaction=True)
@pytest.mark.elasticsearch
def test_list_no_identical(world, client):
factories.FoiRequestFactory.create(site=world)
factories.rebuild_index()
Expand Down Expand Up @@ -277,6 +282,7 @@ def test_auth_links(world, client):


@pytest.mark.django_db
@pytest.mark.elasticsearch
def test_feed(world, client):
factories.rebuild_index()

Expand Down Expand Up @@ -673,6 +679,7 @@ def jurisdiction_with_many_requests_slug(request: pytest.FixtureRequest):


@pytest.mark.django_db
@pytest.mark.elasticsearch
@pytest.mark.parametrize(
"filter_field,filter_value,filter_value_function",
[["jurisdiction", None, jurisdiction_with_many_requests_slug], ["q", "*", None]],
Expand Down Expand Up @@ -726,6 +733,7 @@ def dict_combinations_all_r(sequence):
yield dict(parts)


@pytest.mark.elasticsearch
@pytest.mark.django_db
def test_request_list_path_filter(
client: Client,
Expand Down
4 changes: 4 additions & 0 deletions froide/publicbody/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from django.test import TestCase
from django.urls import reverse

import pytest

from froide.foirequest.tests.factories import make_world, rebuild_index
from froide.georegion.models import GeoRegion
from froide.helper.csv_utils import export_csv_bytes
Expand All @@ -25,6 +27,7 @@ class PublicBodyTest(TestCase):
def setUp(self):
self.site = make_world()

@pytest.mark.elasticsearch
def test_web_page(self):
pb = PublicBody.objects.all()[0]
category = CategoryFactory.create(is_topic=True)
Expand Down Expand Up @@ -250,6 +253,7 @@ def test_search(self):
response = self.client.get("/api/v1/publicbody/search/?format=json&q=Body")
self.assertEqual(response.status_code, 200)

@pytest.mark.elasticsearch
def test_autocomplete(self):
pb = PublicBody.objects.all()[0]
rebuild_index()
Expand Down
3 changes: 3 additions & 0 deletions froide/tests/live/test_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def do_login(page, live_server, navigate=True):
expect(page.locator("#navbaraccount-link")).to_have_count(1)


@pytest.mark.elasticsearch
@pytest.mark.django_db
def test_make_not_logged_in_request(page, live_server, public_body_with_index):
pb = PublicBody.objects.all().first()
Expand Down Expand Up @@ -120,6 +121,7 @@ def test_make_not_logged_in_request_to_public_body(page, live_server, world):
assert req.status == FoiRequest.STATUS.AWAITING_USER_CONFIRMATION


@pytest.mark.elasticsearch
@pytest.mark.django_db
def test_make_logged_in_request(page, live_server, public_body_with_index, dummy_user):
do_login(page, live_server)
Expand Down Expand Up @@ -227,6 +229,7 @@ def test_collapsed_menu(page, live_server):


@pytest.mark.django_db
@pytest.mark.elasticsearch
@pytest.mark.parametrize(
"from_resolution, to_resolution",
[("", "successful"), ("successful", "refused")],
Expand Down
9 changes: 7 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,11 @@ test = [
"pre-commit",
"pycodestyle",
"pyflakes",
"pytest-cov",
"pytest-django",
"pytest-factoryboy",
"pytest-playwright",
"pytest-xdist",
"tblib",
"text-unidecode",
"time-machine",
Expand Down Expand Up @@ -137,15 +139,18 @@ branch = true

[tool.coverage.report]
show_missing = true
skip_covered = true
skip_covered = false
exclude_lines = ["pragma: no cover"]

[toolcoverage.files]
source = ["froide"]

[tool.pytest.ini_options]
DJANGO_CONFIGURATION = "Test"
DJANGO_SETTINGS_MODULE = "froide.settings"
python_files = ["tests.py", "test_*.py", "*_tests.py"]
addopts = ["--reuse-db"]
markers = ["no_delivery_mock"]
markers = ["no_delivery_mock", "elasticsearch"]

[tool.mypy]
plugins = ["mypy_django_plugin.main"]
Expand Down
27 changes: 12 additions & 15 deletions requirements-test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ asgiref==3.8.1
# channels
# django
# django-stubs
async-timeout==4.0.3
# via aiohttp
attrs==24.2.0
# via
# aiohttp
Expand Down Expand Up @@ -70,6 +68,7 @@ coverage==7.6.1
# via
# froide (pyproject.toml)
# django-coverage-plugin
# pytest-cov
cron-descriptor==1.4.5
# via django-celery-beat
cryptography==43.0.1
Expand Down Expand Up @@ -127,7 +126,7 @@ django-crossdomainmedia==0.0.4
# via froide (pyproject.toml)
django-elasticsearch-dsl==8.0
# via froide (pyproject.toml)
django-filingcabinet @ git+https://github.com/okfde/django-filingcabinet.git@69cde01cf767ebf6447d057b1400b87c32d03803
django-filingcabinet @ git+https://github.com/okfde/django-filingcabinet.git@3e7a8cc61b04cb77f7010d4c878112fc93af4337
# via froide (pyproject.toml)
django-filter==24.3
# via
Expand Down Expand Up @@ -191,8 +190,8 @@ elasticsearch-dsl==8.15.2
# via
# froide (pyproject.toml)
# django-elasticsearch-dsl
exceptiongroup==1.2.2
# via pytest
execnet==2.1.1
# via pytest-xdist
factory-boy==3.3.1
# via
# froide (pyproject.toml)
Expand Down Expand Up @@ -312,7 +311,7 @@ prompt-toolkit==3.0.47
# via click-repl
psycopg==3.2.3
# via froide (pyproject.toml)
psycopg-binary==3.2.1
psycopg-binary==3.2.3
# via psycopg
pycodestyle==2.12.1
# via froide (pyproject.toml)
Expand Down Expand Up @@ -341,17 +340,23 @@ pyphen==0.16.0
pytest==8.3.3
# via
# pytest-base-url
# pytest-cov
# pytest-django
# pytest-factoryboy
# pytest-playwright
# pytest-xdist
pytest-base-url==2.1.0
# via pytest-playwright
pytest-cov==6.0.0
# via froide (pyproject.toml)
pytest-django==4.9.0
# via froide (pyproject.toml)
pytest-factoryboy==2.7.0
# via froide (pyproject.toml)
pytest-playwright==0.5.2
# via froide (pyproject.toml)
pytest-xdist==3.6.1
# via froide (pyproject.toml)
python-crontab==3.2.0
# via django-celery-beat
python-dateutil==2.9.0.post0
Expand Down Expand Up @@ -427,12 +432,6 @@ tinycss2==1.3.0
# via
# cssselect2
# weasyprint
tomli==2.0.1
# via
# coverage
# django-stubs
# mypy
# pytest
types-markdown==3.7.0.20240822
# via froide (pyproject.toml)
types-python-dateutil==2.9.0.20240906
Expand All @@ -443,22 +442,20 @@ types-requests==2.32.0.20240907
# via froide (pyproject.toml)
typing-extensions==4.12.2
# via
# asgiref
# dj-database-url
# django-stubs
# django-stubs-ext
# elasticsearch-dsl
# jwcrypto
# multidict
# mypy
# psycopg
# pyee
# pypdf
# pytest-factoryboy
tzdata==2024.1
# via
# celery
# django-celery-beat
# kombu
uritemplate==4.1.1
# via
# coreapi
Expand Down
10 changes: 3 additions & 7 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ asgiref==3.8.1
# via
# channels
# django
async-timeout==4.0.3
# via aiohttp
attrs==24.2.0
# via
# aiohttp
Expand Down Expand Up @@ -112,7 +110,7 @@ django-crossdomainmedia==0.0.4
# via froide (pyproject.toml)
django-elasticsearch-dsl==8.0
# via froide (pyproject.toml)
django-filingcabinet @ git+https://github.com/okfde/django-filingcabinet.git@69cde01cf767ebf6447d057b1400b87c32d03803
django-filingcabinet @ git+https://github.com/okfde/django-filingcabinet.git@3e7a8cc61b04cb77f7010d4c878112fc93af4337
# via froide (pyproject.toml)
django-filter==24.3
# via
Expand Down Expand Up @@ -248,7 +246,7 @@ prompt-toolkit==3.0.47
# via click-repl
psycopg==3.2.3
# via froide (pyproject.toml)
psycopg-binary==3.2.1
psycopg-binary==3.2.3
# via psycopg
pycparser==2.22
# via cffi
Expand Down Expand Up @@ -329,17 +327,15 @@ tinycss2==1.3.0
# weasyprint
typing-extensions==4.12.2
# via
# asgiref
# dj-database-url
# elasticsearch-dsl
# jwcrypto
# multidict
# psycopg
# pypdf
tzdata==2024.1
# via
# celery
# django-celery-beat
# kombu
uritemplate==4.1.1
# via
# coreapi
Expand Down

0 comments on commit 7a1b9aa

Please sign in to comment.