[英]Run pytest for each file in directory
I'm trying to build a routine that calls a Pytest class for each PDF document in current directoy... Let me explain我正在尝试为当前目录中的每个 PDF 文档构建一个调用 Pytest class 文档的例程......让我解释一下
Lets say i have this test file假设我有这个测试文件
import pytest
class TestHeader:
#asserts...
class TestBody:
#asserts...
This script needs to test each pdf document in my cwd此脚本需要测试我的 cwd 中的每个 pdf 文档
Here is my best attempt:这是我最好的尝试:
import glob
import pytest
class TestHeader:
#asserts...
class TestBody:
#asserts...
filelist = glob.glob('*.pdf')
for file in filelist:
#magically call pytest for each file
How would i approach this?我将如何处理这个问题?
EDIT: Complementing my question.编辑:补充我的问题。
I have a huge function that extracts each document's data, lets call it extract_pdf
this function returns a tuple (header, body).我有一个巨大的 function 提取每个文档的数据,我们称之为extract_pdf
这个 function 返回一个元组(标题,正文)。
Current attempt looks like this:当前尝试如下所示:
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>)
I need to parse each document prior to testing.我需要在测试之前解析每个文档。 Can it be done this way?可以这样做吗?
The best way to do this through parameterization of the testcases dynamically..通过动态参数化测试用例来做到这一点的最佳方法..
This can be achieved using the pytest_generate_tests
hook..这可以使用pytest_generate_tests
钩子来实现。
def pytest_generate_tests(metafunc):
filelist = glob.glob('*.pdf')
metafunc.parametrize("fileName", filelist )
NOTE: fileName
should be one of the argument to your test function.注意: fileName
应该是您的测试 function 的参数之一。
This will result in executing the testcase for each of the file in the directory and the testcase will be like这将导致为目录中的每个文件执行测试用例,测试用例就像
TestFunc[File1]
TestFunc[File2]
TestFunc[File3]
.
.
and so on..等等..
This is expanding on the existing answer by @ArunKalirajaBaskaran.这是对@ArunKalirajaBaskaran 现有答案的扩展。
The problem is that you have different test classes that want to use the same data, but you want to parse the data only once.问题是您有不同的测试类想要使用相同的数据,但您只想解析数据一次。 If it is ok for you to read all data at once, you could read them into global variables and use these for parametrizing your tests:如果您可以一次读取所有数据,您可以将它们读入全局变量并使用它们来参数化您的测试:
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):
...
This is the same as using这与使用相同
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
just adds a bit of convenience so you don't have to repeat the parametrize
decorator for each test. pytest_generate_tests
只是增加了一点便利,因此您不必为每个测试重复parametrize
装饰器。
The downside of this is of course that you will read in all of the data at once, which may cause a problem with memory usage if there is a lot of files.这样做的缺点当然是您将一次读取所有数据,如果有很多文件,这可能会导致 memory 使用出现问题。 Your approach with pytest.main
will not work, because that is the same as calling pytest
on the command line with the given parameters.您使用pytest.main
的方法将不起作用,因为这与使用给定参数在命令行上调用pytest
相同。 Parametrization can be done at the fixture level or on the test level (like here), but both need the parameters alreay evaluated at load time, so I don't see a possibility to do this lazily (apart from putting it all into one test).参数化可以在夹具级别或测试级别完成(如这里),但两者都需要在加载时已经评估的参数,所以我看不出有可能懒惰地这样做(除了把它全部放在一个测试中)。 Maybe someone else has a better idea...也许别人有更好的主意...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.