zoukankan      html  css  js  c++  java
  • 6、pytest -- 临时目录和文件

    1. 相关的fixture

    1.1. tmp_path

    tmp_path是一个用例级别的fixture,其作用是返回一个唯一的临时目录对象(pathlib.Path);

    我们看下面的例子:

    # src/chapter-6/test_tmp_path.py
    
    CONTENT = "content"
    
    
    def test_create_file(tmp_path):
        d = tmp_path / "sub"  
        d.mkdir()  # 创建一个子目录
        p = d / "hello.txt"
        p.write_text(CONTENT)
        assert p.read_text() == CONTENT
        assert len(list(tmp_path.iterdir())) == 1  # iterdir() 迭代目录,返回迭代器
        assert 0  # 为了展示,强制置为失败
    

    执行:

    λ pipenv run pytest -q -s src/chapter-6/test_tmp_path.py
    F
    ==================================== FAILURES =====================================
    ________________________________ test_create_file _________________________________
    
    tmp_path = WindowsPath('C:/Users/luyao/AppData/Local/Temp/pytest-of-luyao/pytest-4/test_create_file0')
    
        def test_create_file(tmp_path):
            d = tmp_path / "sub"
            d.mkdir()  # 创建一个子目录
            p = d / "hello.txt"
            p.write_text(CONTENT)
            assert p.read_text() == CONTENT
            assert len(list(tmp_path.iterdir())) == 1  # iterdir() 迭代目录,返回迭代器
    >       assert 0  # 为了展示,强制置为失败
    E       assert 0
    
    srcchapter-6	est_tmp_path.py:32: AssertionError
    1 failed in 0.06s
    

    可以看出:

    • tmp_path在不同的操作系统中,返回的是不同类型的pathlib.Path对象,这里Windows系统下返回的是WindowsPath对象,它是Path的子类对象;
    • Path对象可以使用/操作符代替常用的os.path.join()的方法;更多关于pathlib的使用方法可以查看:https://docs.python.org/3.7/library/pathlib.html

    1.2. tmp_path_factory

    tmp_path_factory是一个会话级别的fixture,其作用是在其它fixture或者用例中创建任意的临时目录;

    查看上一章tmp_path fixture的源码,我们能够看到tmp_path就是使用tmp_path_factory的一个例子:

    # _pytest.tmpdir
    
    @pytest.fixture
    def tmp_path(request, tmp_path_factory):
        """Return a temporary directory path object
        which is unique to each test function invocation,
        created as a sub directory of the base temporary
        directory.  The returned object is a :class:`pathlib.Path`
        object.
    
        .. note::
    
            in python < 3.6 this is a pathlib2.Path
        """
    
        return _mk_tmp(request, tmp_path_factory)
    
    @pytest.fixture(scope="session")
    def tmp_path_factory(request):
        """Return a :class:`_pytest.tmpdir.TempPathFactory` instance for the test session.
        """
        return request.config._tmp_path_factory
    

    可以看出:

    • tmp_path调用了tmp_path_factory

    • tmp_path_factory返回一个_pytest.tmpdir.TempPathFactory对象;

    • 进一步查看_mk_tmp的源码:

      def _mk_tmp(request, factory):
        name = request.node.name
        name = re.sub(r"[W]", "_", name)
        MAXVAL = 30
        name = name[:MAXVAL]
        return factory.mktemp(name, numbered=True)
      

      可以看出,tmp_path最终调用了TempPathFactory.mktemp()方法,它返回的是一个pathlib.Path对象;

    1.3. tmpdir

    tmp_path是一个用例级别的fixture,其作用是返回一个唯一的临时目录对象(py.path.local),它提供os.path的方法;

    上面的例子也可以修改成如下这样:

    # src/chapter-6/test_tmpdir.py
    
    CONTENT = "content"
    
    
    def test_create_file(tmpdir):
        p = tmpdir.mkdir("sub").join("hello.txt")  # 创建子文件夹,并新建文件
        p.write(CONTENT)
        assert p.read() == CONTENT
        assert len(tmpdir.listdir()) == 1  # iterdir() 迭代目录,返回列表
        assert 0  # 为了展示,强制置为失败
    

    执行:

    λ pipenv run pytest -q -s src/chapter-6/test_tmpdir.py
    F
    ==================================== FAILURES =====================================
    ________________________________ test_create_file _________________________________
    tmpdir = local('C:\Users\luyao\AppData\Local\Temp\pytest-of-luyao\pytest-6\test_create_file0')
    
        def test_create_file(tmpdir):
            p = tmpdir.mkdir("sub").join("hello.txt")  # 创建子文件夹,并新建文件
            p.write(CONTENT)
            assert p.read() == CONTENT
            assert len(tmpdir.listdir()) == 1  # iterdir() 迭代目录,返回列表
    >       assert 0  # 为了展示,强制置为失败
    E       assert 0
    
    srcchapter-6	est_tmpdir.py:30: AssertionError
    1 failed in 0.06s
    

    其实,tmpdir也调用了tmp_path,只是对返回值做了一次py.path.local()封装:

    # _pytest.tmpdir
    
    @pytest.fixture
    def tmpdir(tmp_path):
        """Return a temporary directory path object
        which is unique to each test function invocation,
        created as a sub directory of the base temporary
        directory.  The returned object is a `py.path.local`_
        path object.
    
        .. _`py.path.local`: https://py.readthedocs.io/en/latest/path.html
        """
        return py.path.local(tmp_path)
    

    1.4. tmpdir_factory

    tmpdir_factory是一个会话级别的fixture,其作用是在其它fixture或者用例中创建任意的临时目录;

    假设,一个测试会话需要使用到一个很大的由程序生成的图像文件,相比于每个测试用例生成一次文件,更好的做法是每个会话只生成一次:

    import pytest
    
    
    @pytest.fixture(scope="session")
    def image_file(tmpdir_factory):
        img = compute_expensive_image()
        fn = tmpdir_factory.mktemp("data").join("img.png")
        img.save(str(fn))
        return fn
    
    
    def test_histogram(image_file):
        img = load_image(image_file)
        # compute and test histogram
    

    1.5. 区别

    fixture 作用域 返回值类型
    tmp_path 用例级别(function) pathlib.Path
    tmp_path_factory 会话级别(session) TempPathFactory
    tmpdir 用例级别(function) py.local.path
    tmpdir_factory 会话级别(session) TempDirFactory

    2. 默认的基本临时目录

    上述fixture在创建临时目录时,都是创建在系统默认的临时目录(例如:Windows系统的%temp%目录)下;你可以通过指定--basetemp=mydir选项自定义默认的基本临时目录;

    λ pipenv run pytest -q -s --basetemp="/d/temp" src/chapter-6/test_tmpdir.py
    F
    ==================================== FAILURES =====================================
    ________________________________ test_create_file _________________________________
    tmpdir = local('D:\temp\test_create_file0')
    
        def test_create_file(tmpdir):
            p = tmpdir.mkdir("sub").join("hello.txt")  # 创建子文件夹,并新建文件
            p.write(CONTENT)
            assert p.read() == CONTENT
            assert len(tmpdir.listdir()) == 1  # iterdir() 迭代目录,返回列表
    >       assert 0  # 为了展示,强制置为失败
    E       assert 0
    
    srcchapter-6	est_tmpdir.py:30: AssertionError
    1 failed in 0.04s
    

    GitHub仓库地址:https://github.com/luizyao/pytest-chinese-doc

  • 相关阅读:
    在批处理中调用JS操作MongoDB
    如何利用jQuery post传递含特殊字符的数据
    利用Spring.NET实现WCF的AOP编程
    C#操作MongoDB帮助类
    C#操作MongoDB数据库方法
    利用CORS配置实现jQuery对WebApi及MVC的跨域访问
    利用System.Drawing.Image类进行图片相关操作
    图片预览示例
    文件上传控件(input type='file')对文件类型的过滤
    sysstat工具包之mpstat
  • 原文地址:https://www.cnblogs.com/luizyao/p/11732764.html
Copyright © 2011-2022 走看看