如何使用@ contextlib.contextmanager为函数实现pytest?

时间:2018-12-31 11:37:49

标签: python python-3.x pytest

如何使用@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)

2 个答案:

答案 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