Implementing a fixture with a single setup but a dedicated instance per test #9312
-
I have a scenario in which a fixture setup task consumes 30-45 seconds to populate a working directory. I then have about a dozen tests that use the working directory created by this fixture. Each test needs to have its own dedicated instance of the working directory, but given how time-intensive the setup is the fixture should only be run once. Is this possible with To ground this scenario in a concrete example, I've included a mock test script below. The The script below satisfies my requirements, but it feels like I'm abusing pytest's features rather than using them as intended. Is there any cleaner, more idiomatic way to accomplish this? Something that doesn't require me running from pathlib import Path
import pytest
from shutil import copytree
from tempfile import TemporaryDirectory
from time import sleep
def long_setup_task(tmp):
sleep(30)
with open(tmp / "data.tsv", "w") as fh:
print("A", "1", sep="\t", file=fh)
print("B", "2", sep="\t", file=fh)
print("C", "3", sep="\t", file=fh)
with open(tmp / "log.txt", "w") as fh:
print("do_long_task complete", file=fh)
def one(wd):
with open(wd / "data.tsv", "a") as fh:
print("D", "4", sep="\t", file=fh)
with open(wd / "log.txt", "a") as fh:
print("one complete", file=fh)
def two(wd):
with open(wd / "data.tsv", "a") as fh:
print("G", "7", sep="\t", file=fh)
with open(wd / "log.txt", "a") as fh:
print("two complete", file=fh)
def three(wd):
with open(wd / "data.tsv", "a") as fh:
print("†", "0", sep="\t", file=fh)
with open(wd / "log.txt", "a") as fh:
print("three complete", file=fh)
@pytest.fixture(scope="session")
def workdir():
with TemporaryDirectory() as tmp:
tmp = Path(tmp)
long_setup_task(tmp)
yield tmp
def test_one(workdir, tmp_path):
copytree(workdir, tmp_path, dirs_exist_ok=True)
one(tmp_path)
with open(tmp_path / "data.tsv", "r") as fh:
observed = fh.read()
expected = "A\t1\nB\t2\nC\t3\nD\t4\n"
assert observed == expected
def test_two(workdir, tmp_path):
copytree(workdir, tmp_path, dirs_exist_ok=True)
two(tmp_path)
with open(tmp_path / "data.tsv", "r") as fh:
observed = fh.read()
expected = "A\t1\nB\t2\nC\t3\nG\t7\n"
assert observed == expected
def test_three(workdir, tmp_path):
copytree(workdir, tmp_path, dirs_exist_ok=True)
three(tmp_path)
with open(tmp_path / "data.tsv", "r") as fh:
observed = fh.read()
expected = "A\t1\nB\t2\nC\t3\n†\t0\n"
assert observed == expected |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
your question indicates that the "costly setup" cannot be separated form a "instance" |
Beta Was this translation helpful? Give feedback.
your question indicates that the "costly setup" cannot be separated form a "instance"
so unless you find a less expensive way to replicate a setup, there is simply not technical way to create it to begin with