mirror of https://github.com/langgenius/dify.git
feat: use xdist to make make test faster (#30824)
Signed-off-by: yihong0618 <zouzou0208@gmail.com>
This commit is contained in:
parent
25ac69afc5
commit
8aeef36e2d
|
|
@ -72,6 +72,7 @@ jobs:
|
|||
OPENDAL_FS_ROOT: /tmp/dify-storage
|
||||
run: |
|
||||
uv run --project api pytest \
|
||||
-n auto \
|
||||
--timeout "${PYTEST_TIMEOUT:-180}" \
|
||||
api/tests/integration_tests/workflow \
|
||||
api/tests/integration_tests/tools \
|
||||
|
|
|
|||
2
Makefile
2
Makefile
|
|
@ -80,7 +80,7 @@ test:
|
|||
echo "Target: $(TARGET_TESTS)"; \
|
||||
uv run --project api --dev pytest $(TARGET_TESTS); \
|
||||
else \
|
||||
uv run --project api --dev dev/pytest/pytest_unit_tests.sh; \
|
||||
PYTEST_XDIST_ARGS="-n auto" uv run --project api --dev dev/pytest/pytest_unit_tests.sh; \
|
||||
fi
|
||||
@echo "✅ Tests complete"
|
||||
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ dev = [
|
|||
# "locust>=2.40.4", # Temporarily removed due to compatibility issues. Uncomment when resolved.
|
||||
"sseclient-py>=1.8.0",
|
||||
"pytest-timeout>=2.4.0",
|
||||
"pytest-xdist>=3.8.0",
|
||||
]
|
||||
|
||||
############################################################
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
import pytest
|
||||
from flask import Flask
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
# Getting the absolute path of the current file's directory
|
||||
ABS_PATH = os.path.dirname(os.path.abspath(__file__))
|
||||
|
|
@ -36,6 +37,7 @@ import sys
|
|||
|
||||
sys.path.insert(0, PROJECT_DIR)
|
||||
|
||||
from core.db.session_factory import configure_session_factory, session_factory
|
||||
from extensions import ext_redis
|
||||
|
||||
|
||||
|
|
@ -102,3 +104,18 @@ def reset_secret_key():
|
|||
yield
|
||||
finally:
|
||||
dify_config.SECRET_KEY = original
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def _unit_test_engine():
|
||||
engine = create_engine("sqlite:///:memory:")
|
||||
yield engine
|
||||
engine.dispose()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _configure_session_factory(_unit_test_engine):
|
||||
try:
|
||||
session_factory.get_session_maker()
|
||||
except RuntimeError:
|
||||
configure_session_factory(_unit_test_engine, expire_on_commit=False)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ def _load_app_module():
|
|||
|
||||
def schema_model(self, name, schema):
|
||||
self.models[name] = schema
|
||||
return schema
|
||||
|
||||
def model(self, name, model_dict=None, **kwargs):
|
||||
"""Register a model with the namespace (flask-restx compatibility)."""
|
||||
if model_dict is not None:
|
||||
self.models[name] = model_dict
|
||||
return model_dict
|
||||
|
||||
def _decorator(self, obj):
|
||||
return obj
|
||||
|
|
|
|||
24
api/uv.lock
24
api/uv.lock
|
|
@ -1479,6 +1479,7 @@ dev = [
|
|||
{ name = "pytest-env" },
|
||||
{ name = "pytest-mock" },
|
||||
{ name = "pytest-timeout" },
|
||||
{ name = "pytest-xdist" },
|
||||
{ name = "ruff" },
|
||||
{ name = "scipy-stubs" },
|
||||
{ name = "sseclient-py" },
|
||||
|
|
@ -1678,6 +1679,7 @@ dev = [
|
|||
{ name = "pytest-env", specifier = "~=1.1.3" },
|
||||
{ name = "pytest-mock", specifier = "~=3.14.0" },
|
||||
{ name = "pytest-timeout", specifier = ">=2.4.0" },
|
||||
{ name = "pytest-xdist", specifier = ">=3.8.0" },
|
||||
{ name = "ruff", specifier = "~=0.14.0" },
|
||||
{ name = "scipy-stubs", specifier = ">=1.15.3.0" },
|
||||
{ name = "sseclient-py", specifier = ">=1.8.0" },
|
||||
|
|
@ -1896,6 +1898,15 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/19/d8/2a1c638d9e0aa7e269269a1a1bf423ddd94267f1a01bbe3ad03432b67dd4/eval_type_backport-0.3.0-py3-none-any.whl", hash = "sha256:975a10a0fe333c8b6260d7fdb637698c9a16c3a9e3b6eb943fee6a6f67a37fe8", size = 6061, upload-time = "2025-11-13T20:56:49.499Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "execnet"
|
||||
version = "2.1.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bf/89/780e11f9588d9e7128a3f87788354c7946a9cbb1401ad38a48c4db9a4f07/execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd", size = 166622, upload-time = "2025-11-12T09:56:37.75Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "faker"
|
||||
version = "38.2.0"
|
||||
|
|
@ -5141,6 +5152,19 @@ wheels = [
|
|||
{ url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-xdist"
|
||||
version = "3.8.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "execnet" },
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/78/b4/439b179d1ff526791eb921115fca8e44e596a13efeda518b9d845a619450/pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1", size = 88069, upload-time = "2025-07-01T13:30:59.346Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88", size = 46396, upload-time = "2025-07-01T13:30:56.632Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-calamine"
|
||||
version = "0.5.4"
|
||||
|
|
|
|||
|
|
@ -5,6 +5,12 @@ SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
|||
cd "$SCRIPT_DIR/../.."
|
||||
|
||||
PYTEST_TIMEOUT="${PYTEST_TIMEOUT:-20}"
|
||||
PYTEST_XDIST_ARGS="${PYTEST_XDIST_ARGS:--n auto}"
|
||||
|
||||
# libs
|
||||
pytest --timeout "${PYTEST_TIMEOUT}" api/tests/unit_tests
|
||||
# Run most tests in parallel (excluding controllers which have import conflicts with xdist)
|
||||
# Controller tests have module-level side effects (Flask route registration) that cause
|
||||
# race conditions when imported concurrently by multiple pytest-xdist workers.
|
||||
pytest --timeout "${PYTEST_TIMEOUT}" ${PYTEST_XDIST_ARGS} api/tests/unit_tests --ignore=api/tests/unit_tests/controllers
|
||||
|
||||
# Run controller tests sequentially to avoid import race conditions
|
||||
pytest --timeout "${PYTEST_TIMEOUT}" api/tests/unit_tests/controllers
|
||||
|
|
|
|||
Loading…
Reference in New Issue