From b6b2cbe40ddb39d013c04e2c218bd8e636d6e183 Mon Sep 17 00:00:00 2001 From: Elarwei Date: Sun, 5 Jul 2026 21:35:38 +0800 Subject: [PATCH] test(ci): parallelize the test suite with pytest-xdist [WIP] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI runs ~29 min per Python version, dominated by network-bound live tests (test_virus alone is ~64% of the runtime because each filter test downloads a broad NCBI taxon). These tests are I/O-bound, so running them concurrently should cut wall-clock substantially without changing what is tested. - Add pytest-xdist to the test dependency group and run hatch-test with `-n auto`. - Isolate the test_virus output directory per test (tempfile.mkdtemp) instead of a single shared "test_virus_output" dir, which would otherwise race under parallel workers. WIP: opened to measure the real CI speedup before tuning (worker count, optional NCBI API key). All tests remain live — no semantic change. Co-Authored-By: Claude Opus 4.8 (1M context) --- pyproject.toml | 3 ++- tests/test_virus.py | 19 +++---------------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f36091db5..730028605 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ test = [ "parameterized==0.9", "pytest>=7", "pytest-cov>=6.2.1", + "pytest-xdist>=3", "types-beautifulsoup4==4.12.0.20250516", "types-requests==2.33.0.20260518", "types-tqdm==4.68.0.20260608", @@ -85,7 +86,7 @@ envs.hatch-test.overrides.matrix.python.features = [ ] # pyproject.toml is the single source of truth for the environments CI tests: # the workflow reads this matrix via `hatch env show --json`. -envs.hatch-test.default-args = [ "tests" ] +envs.hatch-test.default-args = [ "-n", "auto", "tests" ] envs.hatch-test.dependency-groups = [ "test" ] [tool.ruff] diff --git a/tests/test_virus.py b/tests/test_virus.py index 12798ac11..673e0dbe0 100644 --- a/tests/test_virus.py +++ b/tests/test_virus.py @@ -261,24 +261,11 @@ class TestVirus(unittest.TestCase, metaclass=from_json(virus_dict, virus)): See module docstring for detailed parameter coverage analysis. """ - @classmethod - def setUpClass(cls): - """Set up test fixtures that are shared across all tests.""" - cls.test_output_dir = "test_virus_output" - - @classmethod - def tearDownClass(cls): - """Clean up after all tests have run.""" - # Clean up test output directory if it exists - if os.path.exists(cls.test_output_dir): - shutil.rmtree(cls.test_output_dir) - def setUp(self): """Set up before each test method.""" - # Create a fresh test output directory - if os.path.exists(self.test_output_dir): - shutil.rmtree(self.test_output_dir) - os.makedirs(self.test_output_dir, exist_ok=True) + # Create a unique per-test output directory so tests can run in parallel + # (pytest-xdist) without racing on a shared, fixed directory. + self.test_output_dir = tempfile.mkdtemp(prefix="test_virus_") def tearDown(self): """Clean up after each test method."""