Динамическое создание параметров прибора PyTest из другого прибора - PullRequest
3 голосов
/ 20 февраля 2020

У меня есть каталог AWS S3, содержащий несколько файлов JSON, которые используются в качестве входных данных для тестирования.

Я создал модуль PyTest, который загружает все файлы JSON один раз, используя широкий модуль fixture, а затем запускает несколько тестовых функций, каждая из которых параметризована через набор JSON:

import pytest
import os
from tempfile import mkdtemp, TemporaryDirectory
from glob import glob

JSONS_AWS_PATH = 's3://some/path/'

def download_jsons():
    temp_dir = mkdtemp()
    aws_sync_dir(JSONS_AWS_PATH, temp_dir)
    json_filenames = glob(os.path.join(local_path, "*.json"))
    return json_filenames

@pytest.fixture(scope='module', params=download_jsons()) #<-- Invoking download_jsons() directly
def json_file(request):
    return request.param

def test_something(json_file):
   # Open the json file and test something

def test_something_else(json_file):
   # Open the json file and test something else

def test_another_thing(json_file):
   # you got the point...

Этот тестовый модуль сам по себе работает - единственная болевая точка заключается в том, как очистить temp_dir в конец модуля \ сеанса.
Поскольку download_jsons() вызывается напрямую, еще до запуска json_file фикстура - у него нет собственного контекста. Поэтому я не могу сделать его чистым temp_dir после того, как все тесты сделаны.

Я бы хотел сделать download_jsons() модулем \ сессионной областью fixture сам по себе. Что-то вроде:

fixture(scope='module')
def download_jsons():
   temp_dir = mkdtemp()
   # Download and as glob, as above
   yield json_filenames
   shutil.rmtree(temp_dir)

или

fixture(scope='module')
def download_jsons(tmpdir_factory):
    #...

, как предложила @Gabriela Melo.

Вопрос в том, как сделать параметризацию приспособления json_file по списку. вернул download_jsons(), не вызывая его напрямую?

Я пытался реализовать это решение либо с mark.parametrize, setup_module(), либо pytest_generate_tests(metafunc) - но не смог реализовать ту функцию, которую я искал.

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

Если вы хотите использовать ресурс для параметризации, он не может быть возвращен прибором (по крайней мере, в текущей версии pytest). Однако вы можете переместить код настройки / разрыва в ловушки - это также позволит параметризовать через pytest_generate_tests ловушку. Пример: в директории root вашего проекта создайте файл с именем conftest.py со следующим содержимым:

from tempfile import TemporaryDirectory
from pathlib import Path


def pytest_sessionstart(session):
    # this is where we create the temp dir and download the files
    session.config._tempdir = TemporaryDirectory()
    d = session.config._tempdir.name
    aws_sync_dir(JSONS_BLOBBY_PATH, d)
    session.config._json_files = Path(d).glob("*.json")


def pytest_sessionfinish(session):
    # this is where we delete the created temp dir
    session.config._tempdir.cleanup()


def pytest_generate_tests(metafunc):
    if "file" in metafunc.fixturenames:
        # parametrize the file argument with the downloaded files
        files = metafunc.config._json_files
        metafunc.parametrize("file", files)

Теперь вы можете использовать аргумент file в тестах, как обычно, например,

def test_ends_with_json(file):
    assert file.suffix == ".json"
0 голосов
/ 20 февраля 2020

Похоже, это то, что вы ищете: https://docs.pytest.org/en/latest/tmpdir.html#the -tmpdir-factory-fixture

(Использование прибора Pytest * tmpdir_factory и настройка области действия json_file функция session вместо module)

...