如何将 tmpdir 与我的 pytest.fixture 一起使用?

Jef*_*aum 1 python unit-testing file fixtures pytest

我有一个单元测试类正在测试 txt 文件中的内容。我正在使用 tmpdir 夹具和 pytest。这是我当前的课程:

from objects.TicketCounter import TicketCounter
from objects.ConfigReader import ConfigReader
import os
import pytest
 
class TestTicketCounter():

    # @pytest.fixture(scope="module") #<---Could I use this instead of passing tmpdir each time?
    # def my_filepath(self, tmpdir):
    #     return tmpdir.mkdir("sub").join("testCurrentTicketCount.txt")

    def test_createNewTicketCountFile(self, tmpdir):
        x = tmpdir.mkdir("sub").join("testCurrentTicketCount.txt") #<----Repeated
        ticketCounter = TicketCounter(x)
        assert os.path.getsize(x) > 0

    def test_addOneTicketCounter(self, tmpdir):
        x = tmpdir.mkdir("sub").join("testCurrentTicketCount.txt") #<----Repeated
        ticketCounter = TicketCounter(x)
        beforeCount = int(ticketCounter.readTicketCountFromFile())
        ticketCounter.addOneTicketCounter()
        afterCount = int(ticketCounter.readTicketCountFromFile())
        assert beforeCount + 1 == afterCount

    def test_readTicketCountFromFile(self, tmpdir):
        x = tmpdir.mkdir("sub").join("testCurrentTicketCount.txt") #<----Repeated
        ticketCounter = TicketCounter(x)
        print(ticketCounter.readTicketCountFromFile())
        assert int(ticketCounter.readTicketCountFromFile()) >= 0
Run Code Online (Sandbox Code Playgroud)

我想摆脱重复的代码,并每次使用我注释掉的固定装置my_filepath传递相同的路径。当我尝试使用my_parser pytest 固定装置时,出现错误:

ScopeMismatch: You tried to access the 'function' scoped fixture 'tmpdir' with a 'module' scoped request object, involved factories   
unit_tests\test_TicketCounter.py:12: 
Run Code Online (Sandbox Code Playgroud)

那么您无法将 tmpdir 与 pytest 夹具一起使用吗?是因为 tmpdir 是一个固定装置吗?关于如何删除重复的代码并使用函数或夹具来传递路径有什么想法吗?

MrB*_*men 8

正如错误消息所述,tmpdir是一个基于函数的固定装置,例如,它为每个测试创建一个新的临时目录,并在测试后将其删除。因此,您不能在模块作用域的固定装置中使用它,该固定装置仅在模块加载后实例化一次。如果您可以这样做,您的临时目录将在第一次测试后被删除,并且您将无法在下一次测试中访问它。

在当前代码中,固定tmpdir装置用作函数作用域固定装置,因此为每个测试创建一个新目录 - 通常需要什么。如果删除模块范围,您可以毫无问题地使用您的装置:

@pytest.fixture
def my_filepath(self, tmpdir):
    return tmpdir.mkdir("sub").join("testCurrentTicketCount.txt")
Run Code Online (Sandbox Code Playgroud)

如果出于某种原因您想在每个测试中使用相同的临时目录,则无法使用该tmpdir装置。在这种情况下,您只需创建自己的 tmp 目录,例如:

import os
import tempfile
import shutil

@pytest.fixture(scope="module")
def my_filepath(self):
    tmpdir = tempfile.mkdtemp()
    subdir = os.path.join(tmpdir, "sub")
    os.mkdir(subdir)
    yield os.path.join(subdir, "testCurrentTicketCount.txt")
    shutil.rmtree(tmpdir)
Run Code Online (Sandbox Code Playgroud)