Запустите pytest для каждого файла в каталоге - PullRequest
1 голос
/ 02 августа 2020

Я пытаюсь создать процедуру, которая вызывает класс Pytest для каждого PDF-документа в текущем каталоге ... Позвольте мне объяснить

Допустим, у меня есть этот тестовый файл

import pytest

class TestHeader:
    #asserts...

class TestBody:
    #asserts...

Этот сценарий должен проверить каждый PDF-документ в моем cwd

Вот моя лучшая попытка:

import glob
import pytest

class TestHeader:
    #asserts...

class TestBody:
    #asserts...

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

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

Как мне подойти к этому?

EDIT: Дополнение моего вопроса .

У меня есть огромная функция, которая извлекает данные каждого документа, позволяет вызвать ее 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>)

Мне нужно разобрать каждый документ перед тестированием. Можно ли так?

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Это расширяет существующий ответ @ 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 в командной строке с заданными параметрами. Параметризация может быть выполнена на уровне приспособлений или на уровне тестирования (как здесь), но оба требуют, чтобы параметры уже оценивались во время загрузки, поэтому я не вижу возможности сделать это лениво (кроме помещения всего в один тест. ). Может у кого-то есть идея получше ...

1 голос
/ 02 августа 2020

Лучший способ сделать это путем динамической параметризации тестовых наборов.

Это может быть достигнуто с помощью pytest_generate_tests хука .. быть одним из аргументов вашей тестовой функции.

Это приведет к выполнению тестового набора для каждого файла в каталоге, и тестовый набор будет похож на

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

и так далее. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...