为目录中的每个文件运行pytest

2024-06-28 11:27:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试构建一个例程,为当前directoy中的每个PDF文档调用一个Pytest类。。。让我解释一下

假设我有这个测试文件

import pytest

class TestHeader:
    #asserts...

class TestBody:
    #asserts...

此脚本需要测试我的cwd中的每个pdf文档

以下是我最好的尝试:

import glob
import pytest

class TestHeader:
    #asserts...

class TestBody:
    #asserts...

filelist = glob.glob('*.pdf')

for file in filelist:
    #magically call pytest for each file

我将如何处理这个问题

编辑:补充我的问题

我有一个巨大的函数,可以提取每个文档的数据,我们称之为extract_pdf 此函数返回一个元组(头、体)

当前尝试如下所示:

import glob
import pytest

class TestHeader:
    #asserts...

class TestBody:
    #asserts...

filelist = glob.glob('*.pdf')

for file in filelist:
    header, body = extract_pdf(file)
    pytest.main(<pass header and body as args for pytest>)

我需要在测试之前解析每个文档。可以这样做吗


Tags: 函数in文档importforpdfpytestextract
2条回答

这是对@ArunKalirajaBaskaran现有答案的扩展

问题是您有不同的测试类想要使用相同的数据,但是您只想解析数据一次。如果可以一次读取所有数据,则可以将其读入全局变量,并使用这些变量对测试进行参数化:

def extract_data():
    filenames = []
    headers = []
    bodies = []
    for filename in glob.glob('*.pdf'):
        header, body = extract_pdf(filename)
        filenames.append(filename)
        headers.append(header)
        bodies.append(body)
    return filenames, headers, bodies

filenames, headers, bodies = extract_data()


def pytest_generate_tests(metafunc):
    if "header" in metafunc.fixturenames:
        # use the filename as ID for better test names
        metafunc.parametrize("header", headers, ids=filenames)
    elif "body" in metafunc.fixturenames:
        metafunc.parametrize("body", bodies, ids=filenames)

class TestHeader:
    def test_1(header):
        ...

    def test_2(header):
        ...

class TestBody:
    def test_1(body):
        ...

这与使用相同

class TestHeader:
    @pytest.mark.parametrize("header", headers, ids=filenames)
    def test_1(header):
        ...

    @pytest.mark.parametrize("header", headers, ids=filenames)
    def test_2(header):
        ...

pytest_generate_tests只是增加了一点便利性,因此您不必为每个测试重复parametrize装饰程序

当然,这样做的缺点是您将一次读入所有数据,如果有很多文件,这可能会导致内存使用问题。使用pytest.main的方法将不起作用,因为这与使用给定参数在命令行上调用pytest是一样的。参数化可以在夹具级别或测试级别上完成(如此处),但两者都需要在加载时对参数进行评估,因此我不认为可以懒散地进行此操作(除了将其全部放在一个测试中)。也许其他人有更好的主意

实现这一点的最佳方法是动态参数化测试用例

这可以通过使用pytest_generate_tests钩子实现

def pytest_generate_tests(metafunc):
    filelist = glob.glob('*.pdf')
    metafunc.parametrize("fileName", filelist )

注意:fileName应该是测试函数的参数之一

这将导致对目录中的每个文件执行testcase,testcase如下

TestFunc[File1]
TestFunc[File2]
TestFunc[File3]
.
.

等等

相关问题 更多 >