pytest嵌套参数化与树状数据

时间:2016-11-26 12:05:21

标签: python pytest

使用pytest,我试图像分层场景一样测试树。 让我们以文档结构为例:

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

文件包含多个章节;一章包含多个段落。

开始测试新文档时,需要运行一些设置代码;当新章节开始时,需要运行一些其他设置代码;和段落相同。

写为伪代码:

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)

如果我们有以下数据:

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

我希望收集的测试用例是:

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

我尝试过pytest_generate_tests,类场景,灯具和参数化测试函数的不同组合,但未能实现这一点。

任何指针都会非常感激。

2 个答案:

答案 0 :(得分:2)

Pytest fixutes应该是独立的。 因此,要解决您的任务,您必须使用所有功能组合的简单列表构建一个夹具(文档 - 章节 - 段落)。

您可以使用返回此类列表的一个元素的简单fixture来执行此操作,或者您可以在测试生成阶段生成此列表,如下面的代码所示。

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

答案 1 :(得分:0)

如果像我一样,你想要一些由document参数化的测试,一些由documentchapter以及其他documentchapter,{ {1}}我的方法(灵感来自Andrey Sorokin)如下。

paragraph

conftest.py

然后在import pytest documents = { 'Alpha': { 'A': {'A1': {},'A2': {}}, 'B': {'B1': {}} } } def pytest_generate_tests(metafunc): if 'document' in metafunc.fixturenames: if 'chapter' in metafunc.fixturenames: if 'paragraph' in metafunc.fixturenames: metafunc.parametrize( ['document', 'chapter', 'paragraph'], [(d, c, p) for d, cs in documents.items() for c, ps in cs.items() for p in ps.keys() ]) else: metafunc.parametrize( ['document', 'chapter'], [(d, c) for d, cs in documents.items() for c in cs.keys() ]) else: metafunc.parametrize( 'document', documents.keys())

test.py

运行

def test_d(document):
    print(document)

def test_dc(document, chapter):
    print(document, chapter)

def test_dcp(document, chapter, paragraph):
    print(document, chapter, paragraph)