Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest nested parametrization with tree-like data

Tags:

python

pytest

Using pytest, I'm trying to test a tree like hierarchical scenario. Lets use a document structure as an example:

Document --- Chapter --- Paragraph
       1   n        1   n

Where a document contains multiple chapters; a chapter contains multiple paragraphs.

When starting testing a new document, some setup code need to be run; when a new chapter is started, some other setup code need to be run; and the same for paragraph.

Written as pseudo code:

for doc in documents:
    setup_doc(doc)
    for chapter in doc.chapters:
        setup_chapter(chapter)
        for paragraph in chapter.paragraphs:
            setup_paragraph(paragraph)
            test_it(doc, chapter, paragraph)
            teardown_paragraph(paragraph)
        teardown_chapter(chapter)
    teardown_doc(doc)

If we have the following data:

Document Alpha
   chapter A
      Paragraph A1
      Paragraph A2
   chapter B
      Paragraph B1

I would expect the collected test cases to be:

test_it[Alpha, A, A1]
test_it[Alpha, A, A2]
test_it[Alpha, B, B1]

I've tried different combinations of pytest_generate_tests, class scenarios, fixtures and parametrized test functions, but have not been able to achieve this.

Any pointers would be greatly appreciated.

like image 502
Zen Avatar asked Dec 08 '25 14:12

Zen


1 Answers

Pytest fixutes are supposed to be independent. So to solve your task you have to build one fixture with plain list of all features combinations (document - chapter - paragraph).

You can do that with simple fixture that returns one element of such a list or you can generate this list on test generation phase as demonstrated in the code below.

documents = {
        'Alpha': {
            'A': {'A1': {},'A2': {}},
            'B': {'B1': {}}
        }
    }


def pytest_generate_tests(metafunc):
    """Documents tree from documents"""
    if 'document' in metafunc.fixturenames:
        documents_plain = []
        for document in documents.keys():
            for chapter in documents[document].keys():
                for paragraph in documents[document][chapter].keys():
                    documents_plain.append({'document': document, 'chapter': chapter, 'paragraph': paragraph})
        metafunc.parametrize(
            'document',
            documents_plain,
            scope='session')


def test_it(document):
    print('{}, {}, {}'.format(document['document'], document['chapter'], document['paragraph']))


py.test -s

Alpha, B, B1
Alpha, A, A1
Alpha, A, A2
like image 197
Andrey Sorokin Avatar answered Dec 12 '25 20:12

Andrey Sorokin