Python 使用tmp_路径夹具创建路径后,路径不存在

Python 使用tmp_路径夹具创建路径后,路径不存在,python,pytest,fixtures,pytest-bdd,Python,Pytest,Fixtures,Pytest Bdd,编辑:这里有一个git回购协议,便于测试: 我想将一些重复的代码从step_def文件重构为conftest.py文件。以下是步骤的内容: @scenario('../features/CLI.feature', 'store file in object database') def test_file_stored_by_content_address(): pass @given("a file exists at some full path

编辑:这里有一个git回购协议,便于测试:

我想将一些重复的代码从step_def文件重构为
conftest.py
文件。以下是步骤的内容:

@scenario('../features/CLI.feature',
          'store file in object database')

def test_file_stored_by_content_address():
    pass

@given("a file exists at some full path within a ugit dir", target_fixture="file_exists_at_path")
def file_exists_at_path(file_within_ugit_dir):
    return file_within_ugit_dir

@when("I enter ugit hash-object followed by that path")
def file_gets_hashed(file_exists_at_path):
    dir_name = os.path.dirname(file_exists_at_path)
    base_name = os.path.basename(file_exists_at_path)
    os.chdir(dir_name)
    os.system(f'ugit hash-object {base_name}')

@then("this object is stored in a content-addressed location in the subdirectory .ugit/objects")
def object_saved_in_db(file_within_ugit_dir, file_hashed):
    with open(file_hashed, "rb") as f:
        contents = f.read()
        with open(file_path, "rb") as hf:
            assert hf.read() == f.read()
下面是
conftest.py

import os
import subprocess
import hashlib
import pytest
from pytest_bdd import scenario, given, when, then, parsers

WISE_WORDS = "Don\\'t be a fool!  I\\'ll call you later."

@pytest.fixture(scope="session")
def is_ugit_dir(tmp_path_factory):
    path = tmp_path_factory.mktemp('data')
    os.chdir(path)
    subprocess.run(['ugit', 'init'])
    return path

@pytest.fixture
def file_within_ugit_dir(is_ugit_dir):
    path = is_ugit_dir
    full_path = f'{path}/wise_words.txt'
    os.system(f'echo {WISE_WORDS} > wise_words.txt')
    return full_path


   
 @pytest.fixture
def file_hashed(is_ugit_dir, file_within_ugit_dir):
    """
    Returns the full path to a hash-object within the objects database
    """
    subprocess.run(['ugit', 'hash-object', file_within_ugit_dir])
    # there should now be a file with a sha1 content-address in the following directory
    objects_dir = os.path.dirname(is_ugit_dir)+'/.ugit/objects/'
    with open(file_within_ugit_dir, "rb") as f:
        # first calculate the hash
        sha_hash = hashlib.sha1 (f.read()).hexdigest ()
        return objects_dir+sha_hash
运行测试时,在以下步骤之间,临时目录似乎没有保持打开状态:

t-74/.ugit/objects/7b5ee3d8d42c66048125a3937a0170ffdaf7b272'

    @then("this object is stored in a content-addressed location in the subdirectory .ugit/objects")
    def object_saved_in_db(file_hashed):
>       with open(file_hashed, "rb") as f:
E       FileNotFoundError: [Errno 2] No such file or directory: '/private/var/folders/m2/99x5jvw95ll6sbtgvj5md9700000gp/T/pytest-of-davidjoseph/pytest-74/.ugit/objects/7b5ee3d8d42c66048125a3937a0170ffdaf7b272'

/Users/davidjoseph/projects/ugit-bdd/tests/step_defs/test_cli.py:43: FileNotFoundError
-------------------------------------- Captured stdout call ---------------------------------------
Initialized empty ugit repository in /private/var/folders/m2/99x5jvw95ll6sbtgvj5md9700000gp/T/pytest-of-davidjoseph/pytest-74/data1/.ugit
7b5ee3d8d42c66048125a3937a0170ffdaf7b272

有没有办法使这个临时目录保持打开状态,以便在
conftest.py
文件中的装置之间重用,并最终在step_def文件中重用?

我认为代码中存在逻辑问题。 根据测试场景,散列的fixture文件必须返回包含散列的现有文件的路径。你可以在这里看到:

@then("this object is stored in a content-addressed location in the subdirectory .ugit/objects")
def object_saved_in_db(file_within_ugit_dir, file_hashed):
    with open(file_hashed, "rb") as f:
        contents = f.read()
        with open(file_path, "rb") as hf:
            assert hf.read() == f.read()
conftest.py中,您没有创建包含哈希的文件。您正在创建一个虚拟链接,由于该链接上没有任何内容,因此会得到FileNotFoundError。此处有错误(您的代码未创建哈希文件):


is_ugit_dir
夹具的范围更改为
注释中建议的“会话”
,就足够了;其余的都是您自己代码中的错误:

  • 您将当前工作目录更改为
    /tmp/pytest smth/data
    ,并在其中调用
    ugit init
    ——我假设工具在
    /tmp/pytest smth/data/.ugit
    处创建存储库元数据。以后,你用

    要创建objects dir-这将使您获得
    /tmp/pytest smth/.ugit/objects
    。难怪这个目录不存在。将其更改为例如
    objects\u dir=is\u ugit\u dir/'.ugit'/'objects'
    修复了第一个错误。作为后续操作,必须将散列的
    文件
    fixture的返回更改为
    对象_dir/sha_hash
    ,以使用
    路径库
    路径

  • 除了没有定义
    file\u路径
    (我想这应该是
    file\u在\u ugit\u目录中
    ),您正在将文件读入
    内容
    ,然后再次读取。为什么?再次调用
    f.read()
    之前,通过
    f.seek(0)
    倒带文件,或者使用
    内容进行比较

  • 以下是完整的工作代码,只需进行最少的必要更改:

    conftest.py
    step_def.py

    Make
    是通过将deco更改为
    @pytest.fixture(scope='session')
    @hoefling来确定会话范围的。当
    是会话作用域时,它仍然在同一行中断。唯一的区别是
    is_ugit_dir
    似乎不是为散列的
    文件创建新的tmp_dir
    。但显然,它仍然不能跨文件使用。很好的捕获-这绝对不是有意的。虽然我已经解决了,但我还是会遇到同样的问题。更新了我的代码,以便您可以查看当前状态。还添加了git回购协议,以使测试更容易。
    @pytest.fixture
    def file_hashed(is_ugit_dir, file_within_ugit_dir):
        objects_dir = os.path.dirname(is_ugit_dir)+'/.ugit/objects/'
        with open(file_within_ugit_dir, "rb") as f:
            # first calculate the hash
            sha_hash = hashlib.sha1 (f.read()).hexdigest ()
            return objects_dir+sha_hash
    
    path = tmp_path_factory.mktemp('data')
    os.chdir(path)
    subprocess.run(['ugit', 'init'])
    
    objects_dir = os.path.dirname(is_ugit_dir)+'/.ugit/objects/'
    
    contents = f.read()
    with open(file_path, "rb") as hf:
        assert hf.read() == f.read()
    
    import os
    import subprocess
    import hashlib
    import pytest
    from pytest_bdd import scenario, given, when, then, parsers
    
    WISE_WORDS = "Don\\'t be a fool!  I\\'ll call you later."
    
    
    @pytest.fixture(scope="session")
    def is_ugit_dir(tmp_path_factory):
        path = tmp_path_factory.mktemp('data')
        os.chdir(path)
        subprocess.run(['ugit', 'init'])
        return path
    
    
    @pytest.fixture
    def file_within_ugit_dir(is_ugit_dir):
        path = is_ugit_dir
        full_path = path / 'wise_words.txt'
        os.system(f'echo {WISE_WORDS} > wise_words.txt')
        return full_path
    
    
    @pytest.fixture
    def file_hashed(is_ugit_dir, file_within_ugit_dir):
        """
        Returns the full path to a hash-object within the objects database
        """
        subprocess.run(['ugit', 'hash-object', file_within_ugit_dir])
        # there should now be a file with a sha1 content-address in the following directory
        objects_dir = is_ugit_dir / '.ugit' / 'objects'
        with open(file_within_ugit_dir, "rb") as f:
            # first calculate the hash
            data = b'blob\x00' + f.read()  # prepend the object type
            sha_hash = hashlib.sha1(data).hexdigest()
            return objects_dir / sha_hash
    
    import os
    from pytest_bdd import scenario, given, when, then, parsers
    
    
    @scenario('features/CLI.feature', 'store file in object database')
    def test_file_stored_by_content_address():
        pass
    
    
    @given("a file exists at some full path within a ugit dir", target_fixture="file_exists_at_path")
    def file_exists_at_path(file_within_ugit_dir):
        return file_within_ugit_dir
    
    
    @when("I enter ugit hash-object followed by that path")
    def file_gets_hashed(file_exists_at_path):
        dir_name = os.path.dirname(file_exists_at_path)
        base_name = os.path.basename(file_exists_at_path)
        os.chdir(dir_name)
        os.system(f'ugit hash-object {base_name}')
    
    @then("this object is stored in a content-addressed location in the subdirectory .ugit/objects")
    def object_saved_in_db(file_within_ugit_dir, file_hashed):
        with open(file_hashed, "rb") as f:
            contents = f.read().strip(b"blob\x00")
            with open(file_within_ugit_dir, "rb") as hf:
                assert hf.read() == contents