"""运行器必须保留失败码,并仅清理本次成功创建的对象。""" import importlib.util from pathlib import Path from types import SimpleNamespace import pytest @pytest.fixture def runner(monkeypatch): path = Path(__file__).resolve().parents[3] / "scripts/run_isolated_tests.py" spec = importlib.util.spec_from_file_location("isolated_runner", path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) calls, commands = [], [] def sql(statement): calls.append(statement) return SimpleNamespace(returncode=0) def run(command, **kwargs): commands.append(command) return SimpleNamespace(returncode=0) monkeypatch.setattr(module, "run_mysql", sql) monkeypatch.setattr(module.subprocess, "run", run) monkeypatch.setattr(module.sys, "argv", ["run_isolated_tests.py"]) return module, calls, commands @pytest.mark.parametrize( "args", [[], ["--keep"], ["--reuse-database", "payroll_test_0123456789ab"]] ) def test_失败码不被清理覆盖(runner, monkeypatch, args): module, calls, _ = runner monkeypatch.setattr(module.sys, "argv", ["runner", *args]) monkeypatch.setattr(module.subprocess, "run", lambda *_, **__: SimpleNamespace(returncode=5)) assert module.main() == 5 drops = [sql for sql in calls if sql.startswith("DROP")] assert bool(drops) == ("--keep" not in args) if "--reuse-database" in args: assert not any(sql.startswith("DROP DATABASE") for sql in drops) def test_只清理成功创建的对象(runner, monkeypatch): module, calls, _ = runner def sql(statement): calls.append(statement) return SimpleNamespace(returncode=int(statement.startswith("CREATE USER"))) monkeypatch.setattr(module, "run_mysql", sql) assert module.main() == 1 assert any(sql.startswith("DROP DATABASE") for sql in calls) assert not any(sql.startswith("DROP USER") for sql in calls) def test_创建重名库失败绝不删除原库(runner, monkeypatch): module, calls, _ = runner def sql(statement): calls.append(statement) return SimpleNamespace(returncode=1) monkeypatch.setattr(module, "run_mysql", sql) assert module.main() == 1 assert not any(sql.startswith("DROP") for sql in calls) def test_参数分隔符不传给pytest(runner, monkeypatch): module, _, commands = runner monkeypatch.setattr(module.sys, "argv", ["runner", "--", "tests/integration/test_auth_flow.py"]) assert module.main() == 0 assert "--" not in commands[-1] assert "tests/integration/test_auth_flow.py" in commands[-1] def test_清理失败不能报成功(runner, monkeypatch): module, calls, _ = runner def sql(statement): calls.append(statement) return SimpleNamespace(returncode=int(statement.startswith("DROP DATABASE"))) monkeypatch.setattr(module, "run_mysql", sql) assert module.main() == 1 assert any(sql.startswith("DROP USER") for sql in calls)