如何使用@contextlib.contextmanager
为函数实现pytest?
为了提高覆盖范围,我也想对此功能进行测试。
@contextlib.contextmanager
def working_directory_relative_to_script_location(path):
"""Changes working directory, and returns to previous on exit. It's needed for PRAW for example,
because it looks for praw.ini in Path.cwd(), but I have that file in the settings directory.
"""
prev_cwd = Path.cwd()
script_dir = Path(os.path.realpath(__file__)).parent
os.chdir(script_dir / path)
try:
yield
finally:
os.chdir(prev_cwd)
答案 0 :(得分:1)
也许不是最好的解决方案,因为它实际上在驱动器上创建目录:
import contextlib
import os
from pathlib import Path
@contextlib.contextmanager
def working_directory_relative_to_script_location(path):
"""Changes working directory, and returns to previous on exit.
It's needed for PRAW for example,
because it looks for praw.ini in Path.cwd(),
but I have that file in the settings directory."""
prev_cwd = Path.cwd()
script_dir = Path(os.path.realpath(__file__)).parent
os.chdir(script_dir / path)
try:
yield
finally:
os.chdir(prev_cwd)
def test_decorator():
tmp = 'tmp_dir'
initial_path = Path.cwd()
os.mkdir(tmp)
tmp_path = os.path.join(initial_path, tmp)
@working_directory_relative_to_script_location(tmp_path)
def with_decorator():
return Path.cwd()
try:
assert with_decorator() == tmp_path
assert Path.cwd() == initial_path
except AssertionError as e:
raise e
finally:
os.rmdir(tmp)
test_decorator()
在这里,我创建了一个返回当前工作目录的函数,并使用上下文管理器对其进行了修饰。您的上下文管理器会期望它在函数调用期间将目录更改为tmp
(这由第一条assert
语句进行测试),然后将其更改回初始目录(第二条assert
语句对此进行了测试)。
答案 1 :(得分:0)
最短的版本:
def test_working_directory_relative_to_script_location(tmpdir):
initial_path = Path.cwd()
@working_directory_relative_to_script_location(tmpdir)
def with_decorator():
return Path.cwd()
try:
assert with_decorator() == tmpdir