如何测试使用相同路径查找和创建文件的函数,以便它在临时目录中创建?
How to test a function that uses the same path for finding and creating files so it'll create in a temporary dir?
我想使用 Pytest 为函数编写测试。该函数获取一个 id,通过它找到视频文件的路径,然后在视频文件夹中创建另一个文件夹(将一些新文件放入其中)。这是函数:
def foo(id):
root_dir = find_local_dir(id) # finds the path to the video file
video_file = root_dir / 'video.mp4'
out_dir = root_dir / 'foo'
out_dir.mkdir(parents=True, exist_ok=True)
我在tests
目录下有一个视频,我想用它来测试,我使用monkeypatch
来防止函数根据id寻找视频。但我不知道如何让它在 tests
中获取视频并在 tmp 中创建新文件夹,不更改 foo
.
我试图将视频从 tests
复制到 tmp_path
,但这不起作用:
def test_foo(tmp_path, monkeypatch):
id = '1234'
mock = MagicMock()
mock.return_value = tmp_path
monkeypatch.setattr(pipeline, 'find_local_dir', mock)
copy2('coffee.mp4', tmp_path / 'video.mp4')
var = pipeline.foo(id)
我的错误是FileNotFoundError: [WinError 2] The system cannot find the file specified
我猜复制没有成功? (我对 Pytest 有点陌生,所以我不知道这是否可行。)
我很乐意用任何其他方法来解决这个问题而不改变 foo
。
谢谢。
编辑:
def find_local_dir(id):
local_dir = Path(f'/tmp/{id}')
local_dir.mkdir(parents=True, exist_ok=True)
return local_dir
I have a video in the tests directory which I would like to use for testing
所以我假设您已经有一个 tests
目录,我们可以将其用作测试的临时目录。现在,我们需要控制的只是 find_local_dir()
的输出指向 tests
目录,因为
- 这是
video.mp4
所在的地方
- 这是创建目录
foo
的地方
文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
└── test_pipeline.py
pipeline.py
from pathlib import Path
def find_local_dir(id):
local_dir = Path(f'/tmp/{id}')
local_dir.mkdir(parents=True, exist_ok=True)
return local_dir
def foo(id):
root_dir = find_local_dir(id) # finds the path to the video file
video_file = root_dir / 'video.mp4'
out_dir = root_dir / 'foo'
out_dir.mkdir(parents=True, exist_ok=True)
# Let's add a print to see the location of the video file
print(f"{video_file=}")
test_pipeline.py
import os
from pathlib import Path
from shutil import copy2, rmtree
import time
from unittest.mock import MagicMock
import pytest
import pipeline
@pytest.fixture
def tmp_path(mocker):
local_dir = Path(f'./tests/tmp')
local_dir.mkdir(parents=True, exist_ok=True)
yield local_dir
# Optionally, delete the temporary directory used for testing
rmtree(local_dir)
def test_foo(tmp_path, monkeypatch):
id = '1234'
mock = MagicMock()
mock.return_value = tmp_path
monkeypatch.setattr(pipeline, 'find_local_dir', mock)
copy2('./tests/coffee.mp4', tmp_path / 'video.mp4')
pipeline.foo(id)
# Remove this line. It is just here so that we can see the files before deletion.
time.sleep(10)
运行 测试
$ pytest -q -rP
================================================================================================= PASSES ==================================================================================================
________________________________________________________________________________________________ test_foo _________________________________________________________________________________________________
------------------------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------------------------
video_file=PosixPath('tests/tmp/video.mp4')
1 passed in 0.05s
测试进行时的文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
├── test_pipeline.py
└── tmp
├── foo
└── video.mp4
测试完成后的文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
└── test_pipeline.py
如您所见,视频文件的位置是正确的 tests/tmp/video.mp4
。新目录也在 tests/tmp/foo
处正确创建。然后在测试结束的时候,临时的tests/tmp/
被删除了
我想使用 Pytest 为函数编写测试。该函数获取一个 id,通过它找到视频文件的路径,然后在视频文件夹中创建另一个文件夹(将一些新文件放入其中)。这是函数:
def foo(id):
root_dir = find_local_dir(id) # finds the path to the video file
video_file = root_dir / 'video.mp4'
out_dir = root_dir / 'foo'
out_dir.mkdir(parents=True, exist_ok=True)
我在tests
目录下有一个视频,我想用它来测试,我使用monkeypatch
来防止函数根据id寻找视频。但我不知道如何让它在 tests
中获取视频并在 tmp 中创建新文件夹,不更改 foo
.
我试图将视频从 tests
复制到 tmp_path
,但这不起作用:
def test_foo(tmp_path, monkeypatch):
id = '1234'
mock = MagicMock()
mock.return_value = tmp_path
monkeypatch.setattr(pipeline, 'find_local_dir', mock)
copy2('coffee.mp4', tmp_path / 'video.mp4')
var = pipeline.foo(id)
我的错误是FileNotFoundError: [WinError 2] The system cannot find the file specified
我猜复制没有成功? (我对 Pytest 有点陌生,所以我不知道这是否可行。)
我很乐意用任何其他方法来解决这个问题而不改变 foo
。
谢谢。
编辑:
def find_local_dir(id):
local_dir = Path(f'/tmp/{id}')
local_dir.mkdir(parents=True, exist_ok=True)
return local_dir
I have a video in the tests directory which I would like to use for testing
所以我假设您已经有一个 tests
目录,我们可以将其用作测试的临时目录。现在,我们需要控制的只是 find_local_dir()
的输出指向 tests
目录,因为
- 这是
video.mp4
所在的地方 - 这是创建目录
foo
的地方
文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
└── test_pipeline.py
pipeline.py
from pathlib import Path
def find_local_dir(id):
local_dir = Path(f'/tmp/{id}')
local_dir.mkdir(parents=True, exist_ok=True)
return local_dir
def foo(id):
root_dir = find_local_dir(id) # finds the path to the video file
video_file = root_dir / 'video.mp4'
out_dir = root_dir / 'foo'
out_dir.mkdir(parents=True, exist_ok=True)
# Let's add a print to see the location of the video file
print(f"{video_file=}")
test_pipeline.py
import os
from pathlib import Path
from shutil import copy2, rmtree
import time
from unittest.mock import MagicMock
import pytest
import pipeline
@pytest.fixture
def tmp_path(mocker):
local_dir = Path(f'./tests/tmp')
local_dir.mkdir(parents=True, exist_ok=True)
yield local_dir
# Optionally, delete the temporary directory used for testing
rmtree(local_dir)
def test_foo(tmp_path, monkeypatch):
id = '1234'
mock = MagicMock()
mock.return_value = tmp_path
monkeypatch.setattr(pipeline, 'find_local_dir', mock)
copy2('./tests/coffee.mp4', tmp_path / 'video.mp4')
pipeline.foo(id)
# Remove this line. It is just here so that we can see the files before deletion.
time.sleep(10)
运行 测试
$ pytest -q -rP
================================================================================================= PASSES ==================================================================================================
________________________________________________________________________________________________ test_foo _________________________________________________________________________________________________
------------------------------------------------------------------------------------------ Captured stdout call -------------------------------------------------------------------------------------------
video_file=PosixPath('tests/tmp/video.mp4')
1 passed in 0.05s
测试进行时的文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
├── test_pipeline.py
└── tmp
├── foo
└── video.mp4
测试完成后的文件树
$ tree
.
├── pipeline.py
└── tests
├── coffee.mp4
└── test_pipeline.py
如您所见,视频文件的位置是正确的 tests/tmp/video.mp4
。新目录也在 tests/tmp/foo
处正确创建。然后在测试结束的时候,临时的tests/tmp/
被删除了